病毒木马查杀第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

很明显,这是一段解密代码,利用关键字“xboy”将乱码进行还原,通过OD观察,可以得到还原后的字符串为“***武*汉*男*生*感*染*下*载*者***”。那么就可以将函数sub_405360重命名为:DecodeString。继续分析:

图9 分析sub_404018函数

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

图10 分析loc_40CBBC处的代码

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

图11 loc_40CBE6处的代码

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

四、小结

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

时间: 2024-08-14 21:43:57

病毒木马查杀第005篇:熊猫烧香之逆向分析(上)的相关文章

病毒木马查杀第008篇:熊猫烧香之病毒查杀总结

一.前言 之前用了六篇文章的篇幅,分别从手动查杀.行为分析.专杀工具的编写以及逆向分析等方面,对"熊猫烧香"病毒的查杀方式做了讨论.相信大家已经从中获取了自己想要的知识,希望大家在阅读完这几篇文章后,能够有一种"病毒也不过如此"的感觉,更希望这些文章能够为有志于在未来参与到反病毒工作的朋友,打下坚实的理论基础.以下就是我在这几篇文章的分析中所总结出来的一些知识点,分为静态分析与动态分析两个方面进行讨论,并加入了一些延伸知识,为大家查漏补缺. 二.病毒的静态分析 静态

病毒木马查杀第011篇:QQ盗号木马之专杀工具的编写

一.前言 由于我已经在<病毒木马查杀第004篇:熊猫烧香之专杀工具的编写>中编写了一个比较通用的专杀工具的框架,而这个框架对于本病毒来说,经过简单修改也是基本适用的,所以本文就不讨论那些重叠的知识,只针对这个病毒特有的方面来讨论专杀工具的编写,然后将其进行组合,就是完整的针对于本病毒的专杀工具了. 二.原理讨论 对于本病毒而言,其最大的特色就在于使用了进程守护技术.病毒运行后,同时有三个病毒进程存在,关闭其中的任何一个,由于还有两个病毒进程的存在,那么被关闭的又会被重新开启.要解决这个问题,不

病毒木马查杀第009篇:QQ盗号木马之手动查杀

一.前言 之前在<病毒木马查杀第002篇:熊猫烧香之手动查杀>中,我在不借助任何工具的情况下,基本实现了对于"熊猫烧香"病毒的查杀.但是毕竟"熊猫烧香"是一款比较简单的病毒,它并没有采取一些特别强的自我保护技术,所以我们完全可以"徒手"解决.但是这次研究的恶意程序就没那么简单,它采取了进程保护的技术,使得我们不能够使用常规手法对其实现查杀.所以这次我引入了两个工具--icesword与autoruns,以达到查杀的目的. 二.病毒的基

病毒木马查杀第002篇:熊猫烧香之手动查杀

一.前言 作为本系列研究的开始,我选择"熊猫烧香"这个病毒为研究对象.之所以选择这一款病毒,主要是因为它具有一定的代表性.一方面它当时造成了极大的影响,使得无论是不是计算机从业人员,都对其有所耳闻:另一方面是因为这款病毒并没有多高深的技术,即便是在当时来讲,其所采用的技术手段也是很一般的,利用我们目前掌握的知识,足够将其剖析.因此,我相信从这个病毒入手,会让从前没有接触过病毒研究的读者打消对病毒的恐惧心理,在整个学习的过程中开个好头. 本篇文章先研究如何对"熊猫烧香"

病毒木马查杀第013篇:一个基于.NET的“敲竹杠”病毒研究

一.前言 恶意程序发展至今,其功能已经从最初的单纯破坏,不断发展为隐私的窥探,信息的盗取,乃至如今非常流行的"敲竹杠"病毒,用于勒索.可见随着时代的发展,病毒的作者们往往也是想利用自己的技术来获取不义之财,变得越来越功利化了.而本系列文章也顺应了这个发展,从病毒讨论到木马,进而来到了"敲竹杠"病毒的讨论上来. 二.什么是"敲竹杠"病毒 其实"敲竹杠"病毒的行为很简单,它就是篡改我们的计算机的开机密码,然后病毒作者留下个人的联系

病毒木马查杀第004篇:熊猫烧香之专杀工具的编写

一.前言 如果是非感染型的病毒,完成行为分析之后,就可以开始编写专杀工具了.当然对于我们这次研究的对象--"熊猫烧香"来说,其实通过之前的行为分析,我们并没有得出它的所有恶意行为,毕竟还没有对其进行逆向分析.所以这里仅针对我们上一篇文章所得出的结果,来进行专杀工具的编写.一般来说,专杀工具既可以用批处理实现,又可以用编程语言编写,但是现实中更多的还是用后者进行制作的,因为其更加严谨.灵活.因此我这里会使用C++来写一个简单的"熊猫烧香"专杀程序. 二.病毒行为回顾与

病毒木马查杀第006篇:熊猫烧香之逆向分析(中)

一.前言 上一篇文章讲解了"熊猫烧香"病毒样本的反汇编代码入口处的分析,虽然尚未研究到病毒的核心部分,但其实我们后续的分析与之前的思想是一致的.而越到核心部分,可能会遇到越来越多的API函数,结合所调用函数的参数进行分析,反而有助于我们更容易地理解病毒的行为.应当将分析出的每一个CALL函数,改为我们能够理解的名字,这往往也有助于对后续程序的理解. 二.病毒功能分析 上一篇文章的最后,我留下了三个CALL没有分析,现在进入第一个CALL,即sub_408024的内部查看一下: 图1 s

病毒木马查杀第007篇:熊猫烧香之逆向分析(下)

一.前言 这次我们会接着上一篇的内容继续对病毒进行分析.分析中会遇到一些不一样的情况,毕竟之前的代码我们只要按照流程顺序一步一步往下走,就能够弄清楚病毒的行为,但是在接下来的代码中,如果依旧如此,在某些分支中的重要代码就执行不到了,所以我们需要采取一些策略,走完每个分支,彻底分析出病毒的行为. 二.病毒分析 现在程序执行到了loc_408171位置处: 图1 loc_408171起始处的代码 程序首先进行比较操作,由于二者都为0,所以在比较过后ZF=1,那么接下来的跳转并不执行.之后的CALL获

病毒木马查杀第012篇:QQ盗号木马之逆向分析

一.前言 在本系列的文章中,对每一个病毒分析的最后一个部分,若无特殊情况,我都会采用逆向分析的手段来为读者彻底剖析目标病毒.但是之前的"熊猫烧香"病毒,我用了三篇文章的篇幅(每篇2500字左右)也仅仅分析了病毒的三分之一,而且还没分析到病毒的核心部分.主要也是因为那是我这个系列为大家分析的第一个病毒,为了将一些原理性的东西说清楚,所以文章略显冗长,也主要是照顾一下初学的朋友,摒弃那些高大上的东西,将我的实际分析过程完整地呈现出来.相信大家在认真阅读完那三篇文章后,都能够掌握基本的分析方