1. 深入病毒腹地IDA与OD协同作战的实战心法上一篇文章我们像拆解一个精密钟表一样一步步分析了熊猫烧香病毒的初始启动流程。说实话光是看那些汇编指令和函数调用很多朋友可能已经有点头晕了。别急这才是逆向分析的“开胃菜”。真正的核心感染逻辑就像病毒藏在最深处的“发动机”我们今天就要用IDA和OD这两把“神兵利器”把它给彻底揪出来。我刚开始学逆向的时候总想着单靠一个工具就能搞定一切结果要么在IDA的静态代码海洋里迷路要么在OD的动态指令流里跟丢。后来踩过几次坑才明白静态分析是地图动态调试是导航两者缺一不可。IDA Pro能让你看清程序的整个“骨架”和“城市布局”知道有哪些函数、逻辑分支而OllyDbgOD则是带你在这个城市里“实时步行”让你亲眼看到数据怎么流动、条件如何跳转。今天要分析的sub_408024这个核心函数就是病毒开始“作恶”的指挥部我们得把地图和导航都用上才能摸清它的门道。在开始之前我强烈建议你准备好虚拟机环境。我习惯用VMware搭一个干净的Windows XP或Windows 7把样本文件比如setup.exe放进去。分析时记得把虚拟机的网络适配器改成“仅主机模式”或者直接断开虚拟网络这是基本的安全操作。工具方面除了IDA和OD可能还会用到Process MonitorProcmon来监控文件、注册表行为用PEiD或Exeinfo PE再确认一下样本有没有加壳。准备工作做足了动起手来才心里不慌。2. 庖丁解牛逐层剖析sub_408024核心感染模块2.1 定位与概览找到病毒的“决策中心”打开IDA Pro载入我们的熊猫烧香样本。还记得上篇我们分析到的位置吗在loc_40CBE6附近有三个非常关键的call指令它们就像是病毒主逻辑的“三驾马车”call sub_408024 call sub_40CA5C call sub_40C97C我们今天的主角就是第一个call sub_408024。在IDA的图形视图按下空格键切换里你能看到这个函数块相当庞大里面又调用了密密麻麻的子函数。先别被吓到逆向分析讲究的是“分而治之”。我的习惯是先用IDA快速浏览一遍这个函数的整体结构看看它大概调用了哪些关键的API比如文件操作、注册表操作、进程创建等在心里画个草图。然后打开OD附加到病毒进程或者直接加载病毒exe。在OD的CPU窗口按CtrlG输入地址0040804D这就是调用sub_408024的地方。按F2下个断点再按F9运行程序让它停在这个门口。这样一来我们就站在了病毒核心模块的入口接下来每一步都可以慢慢观察。2.2 第一把钥匙获取自身路径与剥离文件名病毒要感染其他文件首先得知道“自己在哪里”。所以进入sub_408024后第一个重要的子函数调用就是0x0040804D call sub_40277C在IDA里双击跟进去一眼就能看到它调用了GetModuleFileNameA这个API。这个API的作用是获取当前进程也就是病毒本身可执行文件的完整路径。在OD里我们按F7单步步入这个call然后按F8一步步执行。执行到call GetModuleFileNameA时注意观察栈和寄存器。通常这个API的第一个参数hModule是NULL表示获取当前模块第二个参数lpFilename是一个缓冲区地址第三个参数nSize是缓冲区大小。执行完后你可以在OD的数据窗口AltD跟随那个缓冲区地址就能看到病毒把自己在磁盘上的完整路径读出来了比如C:\Users\Test\Desktop\setup.exe。这个操作很基础但它是后续所有文件操作的基础。我习惯在IDA里立刻把这个函数重命名为GetSelfFullPath这样代码的可读性就大大提高了。紧接着病毒并不需要这个带文件名的完整路径它更需要知道自己在哪个目录下。所以下一个call0x0040805E call sub_405684这个函数的功能就很有意思了。我们动态跟进去看它会从刚才获取的完整路径字符串的末尾开始向前逐个字符扫描寻找反斜杠\、斜杠/或者冒号:。这实际上是在定位最后一个路径分隔符的位置。找到之后它会把分隔符之前的部分也就是目录路径拷贝出来。比如从C:\Users\Test\Desktop\setup.exe得到C:\Users\Test\Desktop\。这个函数可以重命名为ExtractFileDirectory。这里有个小技巧病毒是用Delphi写的而Delphi的字符串在内存中字符串指针的前4个字节即地址减4的位置存放的是字符串的长度。在OD里跟踪时你可能会看到类似mov eax, dword ptr ds:[eax-0x4]的指令这通常就是在取字符串长度。理解这个约定对分析Delphi程序非常有帮助。2.3 构建攻击路径拼接目标文件与内存信息写入知道了自己的目录后病毒要开始“干活”了。它做的第一件事是在当前目录下构造一个特殊的文件名0x0040806E call sub_403ED4这个函数接收两个参数一个是刚才提取的目录路径另一个是字符串Desktop_.ini的地址。它的作用就是简单的字符串拼接生成一个类似C:\Users\Test\Desktop\Desktop_.ini的完整路径。我们在OD里步过这个函数后跟随目标缓冲区就能看到拼接结果。这个函数可以命名为StringConcatenate。然后病毒会检查这个Desktop_.ini文件是否存在0x00408079 call sub_4057A4跟进这个函数你会发现它内部调用了FindFirstFileA。如果文件存在FindFirstFileA会返回一个有效的句柄并且eax寄存器通常不会是INVALID_HANDLE_VALUE-1。病毒通过test al, al之类的指令来判断结果。如果文件存在可能是之前感染留下的也可能是系统正常的文件病毒会有一系列后续操作先调用SetFileAttributesA将文件属性设置为NORMAL参数0x80然后Sleep(1)稍微延迟可能是为了绕过一些简单的监控最后调用DeleteFileA将其删除。这个函数可以重命名为CheckAndDeleteDesktopIni。这个行为表明病毒试图清理或覆盖可能妨碍它操作的特定文件。接下来是一个比较“重”的函数0x00408126 call sub_4078E0这个函数体量很大调用了很多子过程。静态看有点晕但动态跟踪它的“副作用”非常清晰。我们在OD里在这个call之后下断点然后步过它重点观察它写入的内存区域通常通过[ebp - xxx]这样的局部变量来定位。用数据窗口跟随那个地址你会看到一大片数据被写了进去里面可能包含一些可读的字符串片段比如看起来像字典的单词、可能的命令片段、甚至是加密的配置数据。我当初分析到这里时发现它写入的是一大段用于暴力破解或尝试访问共享资源的凭据和字典列表。这其实是熊猫烧香病毒的一个传播手段它试图利用弱口令字典来攻击局域网内其他机器的共享资源。我们可以把这个函数重命名为WriteBruteForceDataToMemory它揭示了病毒除了文件感染还有网络传播的野心。2.4 资源准备与长度校验为释放病毒体铺路在进行了内存数据准备后病毒开始处理它自身携带的“资源”——也就是那个要释放出去感染别人的PE文件病毒体。首先是一个看似简单的操作0x0040812E call sub_403C44这个函数很短主要就是test edx, edx然后根据结果设置标志位Zero Flag。它的作用更像是一个状态检查或初始化标志位的操作。如果某个指针为空比如[ebp-8]里是0它就会设置ZF1。这个函数可以命名为CheckOrSetZeroFlag它的存在往往是为了控制后续流程的跳转。紧接着是关键一步获取病毒体资源的长度0x00408136 call sub_403ECC这个函数接收一个指针参数eax这个指针指向病毒体资源在内存中的起始位置。还记得Delphi字符串的长度存放在指针前4字节的约定吗这个函数内部很可能就是执行了mov eax, dword ptr ds:[eax-0x4]将资源长度字节数取出来放到eax寄存器中返回。我们在OD里跟进执行完这个call后查看eax寄存器的值通常会看到一个像0xEC00这样的十六进制数这就是病毒体的大小。这个函数重命名为GetEmbeddedPELength非常合适。获取长度后病毒会进行一个校验cmp byte ptr [eaxebx-0x1], 0x0这里eax是资源起始指针ebx是刚获取的长度。[eaxebx-0x1]就是资源数据的最后一个字节。病毒检查这个字节是否为0。这可能是对资源数据完整性的一种简单校验或者是一种特定的格式要求。在OD里跟踪你会发现如果最后一个字节非零程序可能会走向错误处理分支而我们分析的这个样本通常这里是0所以程序继续向下执行。这个校验点是病毒确保要释放的数据是“完好”的一个小关卡。3. 双剑合璧实战技巧让静态代码“活”起来分析了这么多函数调用你可能觉得流程有点碎。这正是需要我们把IDA的静态视图和OD的动态流结合起来看的时候。我分享一下我常用的“协同工作流”实测下来效率很高。第一步IDA先行绘制地图。在IDA里面对像sub_408024这样的大函数先按F5生成伪代码如果IDA能正确识别的话。虽然伪代码可能不完全准确但它能给你一个清晰的C语言式的逻辑概览。你会看到if-else判断、while循环、函数调用顺序。同时用IDA的“重命名”功能快捷键N和“添加注释”功能快捷键:把每一个分析出来的子函数的功能标注清楚。比如把sub_405684改成ExtractFileDirectory在旁边注释“从完整路径中提取目录逆向查找\或/”。这样整个函数的“故事线”就慢慢清晰了。第二步OD验证动态跟踪。拿着IDA分析出的“地图”到OD里去“实地探险”。在关键的函数调用处比如每个call指令下断点。不仅仅是入口在函数内部的关键判断点比如jz,jnz跳转也可以下断。然后运行程序观察函数调用前后栈和寄存器的变化。特别是eax返回值、ecx/edx常用来传参以及[ebp-xxx]这样的局部变量。数据窗口的实时变化。这是最直观的。右键点击寄存器或栈地址选择“数据窗口中跟随”你能看到字符串从无到有、数据被写入、内存被修改的全过程。API调用的参数和返回值。OD通常能解析标准API留意调用时栈顶的参数和返回后eax的值。第三步循环反馈修正地图。在OD里发现和IDA静态分析不一致或理解不了的地方马上记下来。回到IDA查看对应地址的汇编代码可能IDA的某些交叉引用没分析对或者程序有花指令、混淆。手动修正IDA的分析比如按C键将数据转换为代码按P键定义函数让静态视图更准确。同时把OD里观察到的具体值比如某个字符串的内容、某个循环的次数作为注释补充到IDA中。举个例子在分析sub_4078E0我们重命名为WriteBruteForceDataToMemory时IDA的伪代码可能只是一大堆内存拷贝操作看起来很混乱。但在OD里你步过这个函数后直接去数据窗口看它写入的内存区域发现里面是admin、password、123456之类的字符串你立刻就明白了它的意图。这时回到IDA在那个函数开头注释“写入弱口令字典到内存用于网络共享爆破”整个函数的意义就跃然纸上了。4. 从分析到防御理解感染链与防护思路通过这一番细致的逆向我们把熊猫烧香病毒核心模块sub_408024的前半部分感染准备流程摸清楚了。它像是一个有条不紊的入侵者自我定位获取自己的完整路径和所在目录。环境清理检查并删除可能冲突的Desktop_.ini文件。武器准备在内存中构建攻击用的字典数据为网络传播做准备。弹药检查找到自身携带的病毒体资源并检查其完整性和长度。这还没有真正开始感染文件但已经做好了全部铺垫。理解了这个流程我们能从中提炼出哪些防御思路呢首先对于终端防护软件EDR或安全研究人员来说监控关键API的调用序列是非常有效的检测手段。一个正常程序短时间内连续调用GetModuleFileNameA、FindFirstFileA针对Desktop_.ini、SetFileAttributesA、DeleteFileA然后又在内存中进行大规模数据填充这个行为序列就非常可疑。我们可以构建这样的行为特征库。其次对Desktop_.ini文件的异常操作是一个很具体的指标。虽然Desktop_.ini是系统文件但正常程序很少会去主动删除它尤其是在非系统目录下。安全软件可以加强对特定敏感文件不仅仅是Desktop_.ini还包括autorun.inf等的删除、修改行为的监控和告警。再者对于内存中突然出现的大规模字典类字符串现代的内存扫描技术是可以有所作为的。虽然恶意代码会加密但在使用前必然要解密到内存中。监测进程内存空间中是否存在大量的常见弱口令、网络共享命令字符串可以作为启发式检测的一个维度。最后想说的是逆向分析熊猫烧香这样的“古董”病毒绝不仅仅是怀旧。它的许多技术思想如自定位、资源释放、多态感染在今天的高级恶意软件中依然以更复杂的形式存在。通过这种“庖丁解牛”式的实战我们练就的不仅是使用IDA和OD的技巧更是一种系统化的恶意代码分析思维如何从海量的汇编指令中抓住关键行为如何将静态的逻辑图与动态的数据流对应起来如何从攻击者的角度理解其意图再转变成防御者的检测规则。这套方法论才是应对未来层出不穷的安全威胁时我们手中最宝贵的武器。