病毒木马查杀实战第005篇:熊猫烧香之逆向分析(上)

前言

        对病毒进行逆向分析。能够彻底弄清楚病毒的行为,从而採取更有效的针对手段。为了节省篇幅,在这里我不打算将“熊猫烧香”进行彻底的分析,仅仅会解说一些比較重要的部分。大家仅仅要掌握了这些思想,那么就能够处理非常多的恶意程序了。一般来说,对病毒的静态分析,我们採用的工具是IDA Pro,动态分析则採用OllyDbg。

因为后者会使病毒实际运行起来,所以为了安全起见。最好在虚拟机中操作。另外,在实际分析过程中,我们可能还须要一些辅助工具。比方侦壳或脱壳程序等。

为了简单起见,这次研究的“熊猫烧香”程序并没有加壳。可是以后我们会讨论怎样应对加壳或採用了其他保护手段的病毒。

 

查壳操作

        逆向分析的第一步就是用查壳工具对目标程序进行查壳操作。这里我使用PEiD v0.95,检測结果例如以下:


图1 对“熊猫烧香”进行查壳操作

        可见,本程序并没有加壳。那么就不涉及脱壳操作,而且是由Borland Delphi 6.0-7.0编写的。由Delphi所编写的代码与VC++所编写的代码有所不同,最明显的两点差别例如以下:

        1、函数调用时參数的传递不全然用栈,而是主要用寄存器,即Delphi编译器默认以register方式传递函数參数。这一点与VC编译的程序全然不同。Delphi一般将第一个參数放入eax寄存器,第二个參数放入edx,第三个參数放入ecx寄存器,其余參数依照与VC程序相似的方式压栈。

        2、栈上给局部变量分配空间的时候。栈是向下增长的。而栈上的数组、字符串、结构体等却是向上增长的。理解这一点能够帮助识别栈上的变量。

        对病毒样本进行了简单的侦測之后,就确定了分析的方向,那么接下来就须要使用反汇编工具进行分析了。

“熊猫烧香”的初步分析

        这里我使用IDA Pro加载病毒样本。首先能够看到例如以下代码:


图2 “熊猫烧香”的入口代码

        上图所看到的的病毒程序起始处的反汇编代码是Delphi自行生成的,并非我们所关心的病毒程序的功能代码。所以这里不正确其进行解说。

接下来的代码例如以下:


图3 “熊猫烧香”入口代码第二部分

        在这里最開始的两个CALL调用的都是名为sub_403C98的函数,IDA Pro已经将当中第二个CALL上方的字符分析出来了。是一段作者感言信息。

所以有理由相信,第一个CALL上方应该也是一段字符串。这里能够结合OD来查看一下:


图4 查看字符串

        可见,第一个CALL上方的字符串就是“***武*汉*男*生*感*染*下*载*者***”,能够理解为是病毒作者信息,那么接下来就有必要分析一下病毒程序利用这两段字符串到底做了什么。

也就是进入CALL的内部,即sub_403C98去研究一下:

CODE:00403C98 sub_403C98      proc near                   ; CODE XREF: sub_403ED4+8j
CODE:00403C98                                             ; sub_403F18+6j ...
CODE:00403C98                 test    edx, edx
    ; 对edx 进行验证,这里的test相当于and。不同的是test仅仅进行比較,而不会将结果保存
    ; 在edx中。

因为edx保存的是病毒作者所编写的一段字符串。因此这里的结果一定是非0的。

CODE:00403C9A jz short loc_403CC0 ; 因为上一条语句的结果是非0的,因此这条跳转语句并不会被运行到。 CODE:00403C9C mov ecx, [edx-8] ; 利用OD进行动态分析可知,[edx-8]是将edx-8这个地址中的值取出来。赋给ecx。那么赋值 ; 完以后。ecx的值为0x0FFFFFFFF。

CODE:00403C9F inc ecx ; ecx自增1,那么ecx的值就变为了0x0。注意这个自增的运算会使得ZF的值变为1。 CODE:00403CA0 jg short loc_403CBC ; 这里的jg表明不大于则跳转。或者更准确地说,其跳转条件是SF=OF且ZF=0。因为经过上一步 ; 的运算,ZF=1,因此本跳转不成立。 CODE:00403CA2 push eax CODE:00403CA3 push edx CODE:00403CA4 mov eax, [edx-4] ; 经过赋值后,eax中保存的值为0x20。 CODE:00403CA7 call sub_403D08 ; 结合OD在虚拟机中进行动态分析,进入一层又一层的调用能够得知,这个CALL主要是调用了 ; LocalAlloc函数,它从堆中分配大小为0xFF8的空间。函数參数uFlags=0,即 ; LMEM_FIXED,意思是分配固定内存,返回值是指向一个内存对象的指针。

LocalAlloc函数 ; 假设运行成功则返回一个指向新分配的内存对象的句柄。 CODE:00403CAC mov edx, eax CODE:00403CAE pop eax CODE:00403CAF push edx CODE:00403CB0 mov ecx, [eax-4] CODE:00403CB3 call sub_402650 ; 结合OD在虚拟机中进行动态分析。这个CALL的主要功能是将之前保存在edx中的字符串(病 ; 毒信息与作者感言)复制到上面所分分配的堆空间中。如图5所看到的。

CODE:00403CB8 pop edx CODE:00403CB9 pop eax CODE:00403CBA jmp short loc_403CC0


图5 复制字符串到新申请的空间中
        至此,sub_403C98分析完毕。

这个函数有两个參数,因为採用的是Delphi编译器。因此在反汇编中,第一个參数保存在eax中,第二个參数保存在edx中。这个函数首先完毕堆空间的申请,然后将edx中保存的字符串复制到新申请的空间中。这个函数在最初赋值的时候。eax的值均为0,而在运行后。eax中保存的就是新申请的堆空间中。所复制的字符串的首地址。

为了易于观察,我把IDA Pro中的sub_403C98重命名为AllocStackAndCopyString。例如以下图所看到的:


图6 函数重命名

        接下来有:


图7 分析sub_405360函数

        这里又是两个字符串。当中第一个是“xboy”。而第二个借助于OD能够知道是一堆乱码:


图8 乱码字符串

        之后能够借助于OD进入sub_405360内部进行动态查看。只是这里我们无需关注全部的细节。仅仅有一处循环须要注意:

CODE:004053D1 loc_4053D1:                             ; CODE XREF: sub_405360+B5 j
CODE:004053D1                 mov     eax, [ebp+var_14]
CODE:004053D4                 call    sub_403ECC
CODE:004053D9                 push    eax
CODE:004053DA                 mov     eax, ebx
CODE:004053DC                 pop     edx
CODE:004053DD                 mov     ecx, edx
CODE:004053DF                 cdq
CODE:004053E0                 idiv    ecx
CODE:004053E2                 mov     edi, edx
CODE:004053E4                 inc     edi
CODE:004053E5                 mov     eax, [ebp+var_14]
CODE:004053E8                 movzx   eax, byte ptr [eax+edi-1]
    ; 每次循环逐字节取出“xboy”中的字符进行运算,注意这里首先取出的是“b”。
CODE:004053ED                 mov     ecx, 0Ah
    ; 将ecx赋值为0x0A,作为接下来除法运算的除数。

CODE:004053F2 xor edx, edx ; 清空edx。 CODE:004053F4 div ecx ; 做除法运算,商保存在eax中,余数保存在edx中。 CODE:004053F6 mov eax, [ebp+var_4] ; 这里因为给eax又一次赋值。说明程序实际想使用的是edx中的余数。 CODE:004053F9 movzx eax, byte ptr [eax+ebx-1] ; 每次循环逐字节取出乱码中的字符,赋值给eax进行接下来的运算。

CODE:004053FE xor edx, eax ; 异或运算,结果保存在edx中。也就是通过运算终于得出的字符。

CODE:00405400 lea eax, [ebp+var_18] CODE:00405403 call sub_403E2C CODE:00405408 mov edx, [ebp+var_18] CODE:0040540B lea eax, [ebp+var_10] CODE:0040540E call sub_403ED4 CODE:00405413 inc ebx CODE:00405414 dec esi CODE:00405415 jnz short loc_4053D1

        非常明显,这是一段解密代码,利用keyword“xboy”将乱码进行还原,通过OD观察,能够得到还原后的字符串为“***武*汉*男*生*感*染*下*载*者***”。

那么就能够将函数sub_405360重命名为:DecodeString。继续分析:


图9 分析sub_404018函数

        这里第一句反汇编代码中的[ebp-14h]所保存的就是上面经过解密后的字符串的地址。而ds:dword_40E7D4保存的是之前所分配的堆空间中所保存的字符串地址。通过OD的动态分析,我们非常easy就能够确定sub_404018函数的用途是对字符串进行比較,那么能够将其重命名为:StringCmp。正常来说经过比对之后。二者是一致的,所以以下“相等则跳转”就会运行,跳到loc_40CBBC处运行:


图10 分析loc_40CBBC处的代码

        因为之前已经进行了对应的分析。并进行了重命名的工作,所以这里的代码功能就一目了然了。首先进行解密,然后是字符串的比对。那么接下来的条件跳转也会成立。直接来到loc_40CBE6:


图11 loc_40CBE6处的代码

        这里连续使用了3个CALL,限于篇幅。我会在接下来的文章中再做分析。

小结

        本文对“熊猫烧香”病毒样本的反汇编程序的起始部分做了初步的分析。因为反汇编代码总会出现各种调用与跳转,所以分析时会显得非常是凌乱,可能会打消大家的积极性。可见逆向分析工作须要各位读者的耐心与仔细。耐心。须要大家沉得住气,不断跟踪每个可疑的CALL;仔细。须要大家时刻留意寄存器中的内容,才干够找到我们须要的信息。当然经验也是非常重要的。成功分析出病毒功能的喜悦是不言而喻的。它也吸引着病毒分析人员不断探索,一口气完毕工作。

也希望各位读者能够以此作为起点,体验到当中的乐趣。

原文地址:https://www.cnblogs.com/brucemengbm/p/6823904.html