百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

捉虫笔记(二)之 杀软请你自重点 捉虫记200字

itomcoil 2024-12-23 11:07 16 浏览

捉虫笔记(二)之 杀软请你自重点

前一篇文章介绍了如何配置符号,这一篇文章我们来个实战。

1 现象

在我们的程序中利用robocopy进行文件的复制。但是QA反馈,只要进行了备份操作,整个进程就会卡住。但是奇怪的是只有他的机器能发现。刚开始的时候我没有太重视这个问题。随着内部反馈的人多了,我开始对这个现象感兴趣了。

2 分析过程

2.1 初步猜测

首先我们是利用的python的脚本启动robocopy,下面是伪代码:

proc = subprocess.Popen("robocopy %s %s /E /MT:32 /XD .* /XF *.gmp *.zip" % (src, dst), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
_, _ = proc.communicate()

robocopy是windows自带的一个复制程序,我觉得可靠性应该是很高的。所以一开始我觉得出问题的肯定 是在我们的内部程序,我仔细检查了每个参数一无所获。

目标只能转移到robocopy本身,刚开始觉得卡住可能是因为需要复制的文件过多,导致线程卡住,但是执行了10分钟还是纹丝不动。我就意识到估计死锁或者等待某个事件。

但是需要证据,此时我让QA的同事立马生成robocopy的dump文件。

2.2 线程堆栈分析

拿到dump之后,立马使用WinDbg打开。

首先就执行了!runaway看看哪个线程跑的最欢。

现0s和5s排在前面。0号线程其实是UI线程(windows中0号线程默认是UI线程),用时最长可以理解。但是仔细分析就发现5号线程其实还没有开始执行就已经卡住了。看来我们刚开始的猜测是有出入的。robocopy刚启动就被按住不动了。

即使卡住了,看看是不是有上锁了,执行!cs -l,查看发现就没有任何的锁。

再执行.exr -1看看是不是出现了什么异常。发现最近的异常还是断点异常。说明也没有异常。

思考片刻,决定还是看看每个线程的 堆栈情况如何。执行~*k,查看所有线程的堆栈,还好线程不多。

因为涉及到一些敏感信息,我把关键点使用softwareXXX来代替。

 # Child-SP          RetAddr               Call Site
00 00000092`21d3f088 00007ffb`ddfc1c4e     ntdll!NtWaitForSingleObject+0x14
01 00000092`21d3f090 00007ff7`4c9009fa     KERNELBASE!WaitForSingleObjectEx+0x8e
02 00000092`21d3f130 00007ff7`4c90296d     Robocopy!WaitMultiThreaded+0x50e
03 00000092`21d3f1b0 00007ff7`4c90f3ad     Robocopy!wmain+0x681
04 00000092`21d3f970 00007ffb`dec37344     Robocopy!__wmainCRTStartup+0x14d
05 00000092`21d3f9b0 00007ffb`e051cc91     kernel32!BaseThreadInitThunk+0x14
06 00000092`21d3f9e0 00000000`00000000     ntdll!RtlUserThreadStart+0x21
0:000> ~*k;.  0  Id: 5bf8.4ee4 Suspend: 0 Teb: 00000092`21f62000 Unfrozen
 # Child-SP          RetAddr               Call Site
00 00000092`21d3f088 00007ffb`ddfc1c4e     ntdll!NtWaitForSingleObject+0x14
01 00000092`21d3f090 00007ff7`4c9009fa     KERNELBASE!WaitForSingleObjectEx+0x8e
02 00000092`21d3f130 00007ff7`4c90296d     Robocopy!WaitMultiThreaded+0x50e
03 00000092`21d3f1b0 00007ff7`4c90f3ad     Robocopy!wmain+0x681
04 00000092`21d3f970 00007ffb`dec37344     Robocopy!__wmainCRTStartup+0x14d
05 00000092`21d3f9b0 00007ffb`e051cc91     kernel32!BaseThreadInitThunk+0x14
06 00000092`21d3f9e0 00000000`00000000     ntdll!RtlUserThreadStart+0x21   1  Id: 5bf8.4c68 Suspend: 0 Teb: 00000092`21f6a000 Unfrozen
 # Child-SP          RetAddr               Call Site
00 00000092`2217fca8 00007ffb`ddfc1c4e     ntdll!NtWaitForSingleObject+0x14
01 00000092`2217fcb0 00007ffb`d9776e2b     KERNELBASE!WaitForSingleObjectEx+0x8e
02 00000092`2217fd50 00007ffb`dec37344     softwareXXX+0x76e2b
03 00000092`2217fd80 00007ffb`e051cc91     kernel32!BaseThreadInitThunk+0x14
04 00000092`2217fdb0 00000000`00000000     ntdll!RtlUserThreadStart+0x21   2  Id: 5bf8.5930 Suspend: 0 Teb: 00000092`21f6c000 Unfrozen
 # Child-SP          RetAddr               Call Site
00 00000092`221ff478 00007ffb`ddffbea0     ntdll!NtWaitForMultipleObjects+0x14
01 00000092`221ff480 00007ffb`ddffbd9e     KERNELBASE!WaitForMultipleObjectsEx+0xf0
02 00000092`221ff770 00007ffb`d977a9c0     KERNELBASE!WaitForMultipleObjects+0xe
03 00000092`221ff7b0 00007ffb`dec37344     softwareXXX+0x7a9c0
04 00000092`221ff810 00007ffb`e051cc91     kernel32!BaseThreadInitThunk+0x14
05 00000092`221ff840 00000000`00000000     ntdll!RtlUserThreadStart+0x21   3  Id: 5bf8.5dbc Suspend: 0 Teb: 00000092`21f6e000 Unfrozen
 # Child-SP          RetAddr               Call Site
00 00000092`2227f648 00007ffb`e051d407     ntdll!NtWaitForWorkViaWorkerFactory+0x14
01 00000092`2227f650 00007ffb`dec37344     ntdll!TppWorkerThread+0x2f7
02 00000092`2227f950 00007ffb`e051cc91     kernel32!BaseThreadInitThunk+0x14
03 00000092`2227f980 00000000`00000000     ntdll!RtlUserThreadStart+0x21   4  Id: 5bf8.7f4 Suspend: 0 Teb: 00000092`21f70000 Unfrozen
 # Child-SP          RetAddr               Call Site
00 00000092`222ff7d8 00007ffb`e051d407     ntdll!NtWaitForWorkViaWorkerFactory+0x14
01 00000092`222ff7e0 00007ffb`dec37344     ntdll!TppWorkerThread+0x2f7
02 00000092`222ffae0 00007ffb`e051cc91     kernel32!BaseThreadInitThunk+0x14
03 00000092`222ffb10 00000000`00000000     ntdll!RtlUserThreadStart+0x21   5  Id: 5bf8.3694 Suspend: 0 Teb: 00000092`21f7a000 Unfrozen
 # Child-SP          RetAddr               Call Site
00 00000092`224fd878 00007ffb`ddfc1c4e     ntdll!NtWaitForSingleObject+0x14
01 00000092`224fd880 00007ffb`d978abed     KERNELBASE!WaitForSingleObjectEx+0x8e
02 00000092`224fd920 00007ff7`4c90c25f     softwareXXX+0x8abed
03 00000092`224fe2a0 00007ff7`4c8ff78f     Robocopy!CZEnt::CopyData+0x467
04 00000092`224ff390 00007ff7`4c90014e     Robocopy!RoboCopy+0x18b
05 00000092`224ff400 00007ffb`e0533730     Robocopy!RoboCopyWorker+0x6e
06 00000092`224ff430 00007ffb`e051d79a     ntdll!TppWorkpExecuteCallback+0x130
07 00000092`224ff480 00007ffb`dec37344     ntdll!TppWorkerThread+0x68a
08 00000092`224ff780 00007ffb`e051cc91     kernel32!BaseThreadInitThunk+0x14
09 00000092`224ff7b0 00000000`00000000     ntdll!RtlUserThreadStart+0x21

接下来就是仔细分析每个线程的堆栈情况了。可以看到0,1,2,以及5号线程都在等待某个内核对象。

3,4号线程就是windows内部的线程池,这里我们暂且不关注。

先分析0号线程,我们查了函数原型NtWaitForSingleObject,第一个参数就是需要等待的内核对象,第二个参数是否可中断,第三个参数超时时间。根据x64调用协议,前四个非浮点数且小于64位参数都是寄存器rcx,rdx,r8,r9中。

NTSTATUS NtWaitForSingleObject(
  [in] HANDLE         Handle,
  [in] BOOLEAN        Alertable,
  [in] PLARGE_INTEGER Timeout
);

我们试着找出这个参数,在WinDbg命令中执行r rcx,就是打印出rcx寄存器中的值。

找到这个值之后,我们需要验证这个值是不是内核对象。再执行!handle xxx f,此时就会打印出关于此内核对象的具体信息。

如法炮制,分析切换到1,2,5号线程。比如我们切换到1号线程:

这里需要说下2号线程调用的函数NtWaitForMultipleObjects,这个函数在微软的文档并未公布函数原型。但是我们可以到此线程的第二帧调用的函数KERNELBASE!WaitForMultipleObjectsEx,而这个函数原型是有的。

从名字可以大致猜出此函数应该是等待多个内核对象。第一个参数就是等待的个数,第二个就是类似数组里面保存了句柄,第三个和第四含义和之前是一样的。

DWORD WaitForMultipleObjects(
  [in] DWORD        nCount,
  [in] const HANDLE *lpHandles,
  [in] BOOL         bWaitAll,
  [in] DWORD        dwMilliseconds
);

我们利用WinDbg来找下句柄值。

一共等待两个句柄值0x128, 0x130。我们在验证下找得对不对。看如下的截图发现我们找得没有错。

这里我把句柄做成表格进行对比。

线程

句柄

信息

0

0x194

1

0x128

2

0x128, 0x130

5

0x738

从表格中我们大致可以看到等待的句柄是Event类型,以及权限,当前Event的状态信息。

2.3 陷入僵局

从上面的表格分析,此时线程中并没有出现明显的相互等待的现象。此时有点穷途末路的感觉。

我在想是不是还有蛛丝马迹被我忽略了。

对,还有3,4号线程我并没有分析。我立马着手在msdn搜索函数原型,可惜这两个函数在msdn未公布任何信息。但是我还不死心继续Google上搜索关于这个函数的信息,从网络搜索的信息也是相当的少,都是一笔带过简单的连参数信息都没有提及。

我开始深入思考,到底还有什么信息被我遗漏了 。

坐着已经让我无法思考了,需要走两步清空下大脑。

转了一圈回来之后,发现还是需要从基础的堆栈分析,一个帧一个帧过滤下。从上面的堆栈中可以看到5号线程堆栈是最长的。我们再看下5号线程的堆栈信息。

0:000> ~5k;
 # Child-SP          RetAddr               Call Site
00 00000092`224fd878 00007ffb`ddfc1c4e     ntdll!NtWaitForSingleObject+0x14
01 00000092`224fd880 00007ffb`d978abed     KERNELBASE!WaitForSingleObjectEx+0x8e
02 00000092`224fd920 00007ff7`4c90c25f     softwareXXX+0x8abed
03 00000092`224fe2a0 00007ff7`4c8ff78f     Robocopy!CZEnt::CopyData+0x467
04 00000092`224ff390 00007ff7`4c90014e     Robocopy!RoboCopy+0x18b
05 00000092`224ff400 00007ffb`e0533730     Robocopy!RoboCopyWorker+0x6e
06 00000092`224ff430 00007ffb`e051d79a     ntdll!TppWorkpExecuteCallback+0x130
07 00000092`224ff480 00007ffb`dec37344     ntdll!TppWorkerThread+0x68a
08 00000092`224ff780 00007ffb`e051cc91     kernel32!BaseThreadInitThunk+0x14
09 00000092`224ff7b0 00000000`00000000     ntdll!RtlUserThreadStart+0x21

5号线程刚开始Robocopy!CZEnt::CopyData就被按住了。我们反汇编看下Robocopy!CZEnt::CopyData代码。

反汇编的函数大概有1m A4纸那么长,该怎么看呢。

我们可以直接从02帧那里看到返回值地址00007ff74c90c25f,这个返回值就是softwareXXX+0x8abed执行完后返回到Robocopy!CZEnt::CopyData

再从Robocopy!CZEnt::CopyData反汇编的函数搜索此地址。

搜索的结果如下:

结果发现了点异常,上面帧好像不大对劲。这里的函数是Robocopy!_imp_CopyFile2,而这里显示的却另外一个模块的代码。

再看softwareXXX这个模块加上了一个相当大的偏移0x8abed,这是不同寻常的,很有可能找的符号不对。

而这个模块的代码在Robocopy中根本就没有。这是从哪里来的?相当的奇怪,突然感觉有点意思。

看下这个模块的信息,在命令中执行lmvm softwareXXX,发现了端倪,原来是个杀软,把这个dll注入了robocopy中,很有可能对函数进行了拦截,导致了这个函数一直无法返回。

0:000> lmvm softwareXXX
Browse full module list
start             end                 module name
00007ffb`d9700000 00007ffb`d9a93000   softwareXXX   (no symbols)           
    Loaded symbol image file: softwareXXX.dll
    Image path: C:\Program Files\softwareXXX\softwareXXX.dll
    Image name: softwareXXX.dll
    Browse all global symbols  functions  data
    Timestamp:        Tue Mar 26 22:56:55 2024 (6602E237)
    CheckSum:         0038B6E1
    ImageSize:        00393000
    File version:     1.0.1.622
    Product version:  1.0.1.622
    File flags:       0 (Mask 3F)
    File OS:          40004 NT Win32
    File type:        2.0 Dll
    File date:        00000000.00000000
    Translations:     0804.04b0
    Information from resource tables:
        CompanyName:      https://www.softwareXXX.cn/
        ProductName:      XDR
        InternalName:     softwareXXX.dll
        OriginalFilename: softwareXXX.dll
        ProductVersion:   1.0.1.622
        FileVersion:      1.0.1.622
        FileDescription:  softwareXXX 应用程序监控模块
        LegalCopyright:   Copyright (C) 2021

再回过头看上面的堆栈信息,此dll对系统的其他的关键函数也进行了拦截处理。

2.4 验证问题

接下来就是找IT部门,让他们把robocopy加入白名单,再进行测试。经过协商之后,我们在进行测试问题就解决了。

相关推荐

PS小技巧 调整命令,让人物肤色变得更加白皙 #后期修图

我们来看一下如何去将人物的皮肤变得更加的白皙。·首先选中图层,Ctrl键加J键复制一层。·打开这里的属性面板,选择快速操作删除背景,这样就会将人物进行单独的抠取。·接下来在上方去添加一个黑白调整图层,...

把人物肤色提亮的方法和技巧

PS后期调白肤色提亮照片的方法。一白遮百丑,所以对于Photoshop后期来说把人物肤色调白是一项非常重要的任务。就拿这张素材图片来说,这张素材图片人脸的肤色主要偏红、偏黄,也不够白皙,该怎样对它进行...

《Photoshop教程》把美女图片调成清爽色彩及润肤技巧

关注PS精品教程,每天不断更新~~室内人物图片一般会偏暗,人物脸部、肤色及背景会出现一些杂点。处理之前需要认真的给人物磨皮及美白,然后再整体润色。最终效果原图一、用修补工具及图章工具简单去除大一点的黑...

PS后期对皮肤进行美白的技巧

PS后期进行皮肤美白的技巧。PS后期对皮肤进行美白的技巧:·打开素材图片之后直接复制原图。·接下来直接点击上方的图像,选择应用图像命令。·在通道这里直接选择红通道,混合这里直接选择柔光,然后点击确定。...

493 [PS调色]调模特通透肤色

效果对比:效果图吧:1、光位图:2、拍摄参数:·快门:160;光圈:8;ISO:1003、步骤分解图:用曲线调整图层调出基本色调。用可选颜色调整图层调整红色、黄色、白色和灰色4种颜色的混合比例。用色彩...

先选肤色再涂面部,卡戴珊的摄影师透露:为明星拍完照后怎么修图

据英国媒体12月17日报道,真人秀明星金·卡戴珊终于承认,她把女儿小北P进了家族的圣诞贺卡,怪不得粉丝们都表示这张贺卡照得非常失败。上周,这位39岁的女星遭到了一些粉丝针对这张照片的批评,她于当地时间...

如何在PS中运用曲线复制另一张照片的色调

怎样把另一张作品的外观感觉,套用到自己的照片上?单靠肉眼来猜,可能很不容易,而来自BenSecret的教学,关键是在PS使用了两个工具,让你可以准确比较两张照片的曝光、色调与饱和度,方便你调整及复制...

PS在LAB模式下调出水嫩肤色的美女

本PS教程主要使用Photoshop使用LAB模式调出水嫩肤色的美女,教程调色比较独特。作者比较注重图片高光部分的颜色,增加质感及肤色调红润等都是在高光区域完成。尤其在Lab模式下,用高光选区调色后图...

在Photoshop图像后期处理中如何将人物皮肤处理得白皙通透

我们在人像后期处理中,需要将人物皮肤处理的白皙通透,处理方法很多,大多数都喜欢使用曲线、磨皮等进行调整,可以达到亮但是不透,最终效果往往不是很好,今天就教大家一种如何将任务皮肤处理得白皙通透,希望能帮...

PS调色自学教程:宝宝照片快速调通透,简单实用!

PS调色自学教程:宝宝照片快速调通透。·首先复制图层,然后选择进入ACR滤镜,选择曲线锁定照片的亮部,也就高光位置,其他部位补亮一点,尤其是阴影的部位补亮多一些,让画面的层次均匀一点。·然后回到基本项...

【干货】如何利用PS进行人物美化

人物图像美化在Photoshop中非常常用,Photoshop作为一款功能强大的图像处理软件,不仅可以对人像进行基本的调色、美化和修复等处理,还可以改变人物的线条和幅度,如调整脸部器官和脸型的大小、调...

教大家一种可以快速把肤色处理均匀的方法@抖音短视频

快速把肤色处理均匀的方法。今天教大家一种可以快速把肤色处理均匀的方法。像这张照片整体肤色走紫红色,但是局部偏黄缘处理起来非常的麻烦。其实我们只需要新建空白图层,图层混合模式更改为颜色,再选择画笔工具把...

PS调色教程 利用RAW调出干净通透的肤色

要么不发,要么干货。后期教程来噜~用RAW调出干净通透的肤色。这次终于不会原片比PS后好看了吧。如果你依然这么觉得,请不要残忍的告诉我这个事实,泪谢TAT)附送拍摄花絮,感谢各位的支持更多风格请关注m...

photoshop后期皮肤变白的技巧

PS后期皮肤变白的技巧。1.PS后期让皮肤变白的方法有很多种,接下来教你一种非常简单容易上手的方法。2.打开素材图片之后,直接在小太极下拉框的位置添加一个纯色调整图层,颜色设置一个纯白色,点击...

Photoshop调出人物的淡雅粉嫩肤色教程

本教程主要使用Photoshop调出人物的淡雅粉嫩肤色教程,最终的效果非常的通透迷人,下面让我们一起来学习.出自:86ps效果图:原图:1、打开原图复制一层。2、用Topaz滤镜磨皮(点此下载)。3、...