查看: 2138|回复: 3
收起左侧

[其他相关] 病毒“wuauclt.exe”所加未知壳的手脱方法

[复制链接]
coderui
发表于 2008-10-13 18:17:21 | 显示全部楼层 |阅读模式
///////////////////////////////////////////////////////////////////////////////////////////////
文件名称:病毒“wuauclt.exe”所加未知壳的手脱方法
目标程序:病毒样本
操作环境:Windows XP-SP2
使用工具:Ollydbg 1.10版
编写作者:Coderui
编写时间:2008年10月14日(更新)
联系方式:coderui@163.com
作者博客:http://hi.baidu.com/coderui
///////////////////////////////////////////////////////////////////////////////////////////////
---------------------------------------------------------------------------------------------
前言:
    本想努力工作来着,好把日程进度再往前赶赶。但很不幸,一不小心发现了个比较诱人的壳,看来今天又要把大部分时间压在它的身上了。
    其实这个病毒的其它变种样本我在很早以前就见过多次,也分析过多次了。只是它所加的壳实在是变态得很,以至于我一直都没能把它完全征服,所以在每次分析它的时候都只能是取其运行后的内存映像来进行研究。
    使用PEID对样本进行扫描,显示出的壳名为“PEtite 2.1 -> Ian Luck”。我脱完壳后在网上搜索了一下,发现有好多该壳的脱文,并且内容都是寥寥几句,一个ESP定律就把壳给搞定了。仔细看了一下,怎么感觉完全不是同一个壳呢?也不知道问题出在哪里了。“PEtite 2.1 -> Ian Luck”这个壳以前我没接触过,具体什么样子我也不知道,这里就把它当未知壳来讲吧。
    该壳应该是一个加密壳,里边有3处异常(通向光明的关键,其中的后2处异常加了暗桩手段)、输入表加密、代码动态解密执行,有N多迷惑性的花指令代码、压缩算法、反动态跟踪调试等技术。如果想脱掉这个壳的话,别说刚入门的新手了,就算是有经验的人都未必能很快的搞定。
    今天仔细分析了下,用了2个小时左右,终于把这个壳的框架思路分析清楚了。下面准备分两部分来讲述:第一部分-手脱方法、第二部分-难点分析。
---------------------------------------------------------------------------------------------
第一部分:手脱方法:
说明:([F2]:下软断点、[F4]:执行到当前代码处、[F7]:单步步入、[F8]:单步步过、[F9]:运行。)
(01):使用“Ollydbg”打开病毒主程序,设置“Ollydbg”为“不忽略任何异常”,然后[F9]运行。
(02):“Ollydbg”提示“访问违规”,然后停在代码“MOV BYTE PTR DS:[EDI],AL”处(代码如下)。
13149217    8807            MOV BYTE PTR DS:[EDI],AL                 ; 访问违规
13149219    81EC D8BA0000   SUB ESP,0BAD8
1314921F    8D8D 887FFFFF   LEA ECX,DWORD PTR SS:[EBP+FFFF7F88]
13149225    834D EC FF      OR DWORD PTR SS:[EBP-14],FFFFFFFF
13149229    894D 90         MOV DWORD PTR SS:[EBP-70],ECX
1314922C    8D8D 887FFFFF   LEA ECX,DWORD PTR SS:[EBP+FFFF7F88]
13149232    894D 8C         MOV DWORD PTR SS:[EBP-74],ECX
13149235    8B4D 08         MOV ECX,DWORD PTR SS:[EBP+8]
13149238    8D45 88         LEA EAX,DWORD PTR SS:[EBP-78]
1314923B    53              PUSH EBX
(03):使用[Shift + F9]来忽略异常,“Ollydbg”停在下一个异常代码“POP EDX”处,并提示“单步异常”(代码如下)。
131438F1    5A              POP EDX                                  ; 单步异常
131438F2    64:8F05 0000000>POP DWORD PTR FS:[0]
131438F9    58              POP EAX
131438FA    6A 00           PUSH 0
131438FC    53              PUSH EBX
131438FD    33DB            XOR EBX,EBX
131438FF    68 4C030000     PUSH 34C
13143904    8B0C24          MOV ECX,DWORD PTR SS:[ESP]
13143907    0FBAE3 00       BT EBX,0
1314390B    72 16           JB SHORT virus.13143923
(04):在代码“POP DWORD PTR FS:[0]”处下软断点(如地址“131438F2”)。使用[Shift + F9]来忽略异常,停在代码“POP DWORD PTR FS:[0]”处(代码如下)。
131438F1    5A              POP EDX                                  ; 断点
131438F2    64:8F05 0000000>POP DWORD PTR FS:[0]
131438F9    58              POP EAX
131438FA    6A 00           PUSH 0
131438FC    53              PUSH EBX
131438FD    33DB            XOR EBX,EBX
131438FF    68 4C030000     PUSH 34C
13143904    8B0C24          MOV ECX,DWORD PTR SS:[ESP]
13143907    0FBAE3 00       BT EBX,0
1314390B    72 16           JB SHORT virus.13143923
(05):向下翻阅代码,你会找到具有明显特征的如下代码,然后在代码“CALL 74DBD43D”处下断点(如地址“13143BB2”),[F9]运行(代码如下)。
13143BA8    59              POP ECX
13143BA9    5E              POP ESI
13143BAA    FD              STD
13143BAB    33C0            XOR EAX,EAX
13143BAD    B9 65030000     MOV ECX,365
13143BB2    E8 8698C761     CALL 74DBD43D                            ; 下断点
13143BB7    0000            ADD BYTE PTR DS:[EAX],AL
13143BB9    0000            ADD BYTE PTR DS:[EAX],AL
13143BBB    0000            ADD BYTE PTR DS:[EAX],AL
13143BBD    0000            ADD BYTE PTR DS:[EAX],AL
13143BBF    0000            ADD BYTE PTR DS:[EAX],AL
13143BC1    0000            ADD BYTE PTR DS:[EAX],AL
.
.
13143FF5    0000            ADD BYTE PTR DS:[EAX],AL
13143FF7    0000            ADD BYTE PTR DS:[EAX],AL
13143FF9    0000            ADD BYTE PTR DS:[EAX],AL
13143FFB    0000            ADD BYTE PTR DS:[EAX],AL
13143FFD    0000            ADD BYTE PTR DS:[EAX],AL
(06):停在代码“CALL 74DBD43D”处后,使用[F7]跟进去。进去后来到这里。然后一直[F8]单步向下走,在代码“JMP”处跳(如地址“1314910B”)(代码如下)。
13149102    5F              POP EDI
13149103    F3:AA           REP STOS BYTE PTR ES:[EDI]
13149105    61              POPAD
13149106    66:9D           POPFW
13149108    83C4 0C         ADD ESP,0C
1314910B >- E9 F2EEFFFF     JMP virus.13148002                       ; 跳转(这里是分界线。听一位网友说前面属于PEtite壳的部分,那么后面的代码可能就属于另一个壳,或是该壳以被改为变形壳了。)
13149110  - E9 1A6B6C69     JMP kernel32.GlobalFree
13149115  - E9 5D796C69     JMP kernel32.GetFileSize
1314911A  - E9 44826D69     JMP kernel32.GetWindowsDirectoryA
1314911F  - E9 540C7169     JMP kernel32.OutputDebugStringA
13149124  - E9 E6906B69     JMP kernel32.WriteProcessMemory
13149129  - E9 F7846B69     JMP kernel32.DeviceIoControl
1314912E  - E9 A73C6D69     JMP kernel32.ExitProcess
13149133  - E9 69256C69     JMP kernel32.GetModuleHandleA
13149138  - E9 631C6C69     JMP kernel32.GetProcAddress
1314913D  - E9 16AE7169     JMP kernel32.Process32Next
13149142  - E9 E48FBE64     JMP USER32.GetWindowTextA
13149147  - E9 ECA0C764     JMP ADVAPI32.StartServiceA
1314914C  - E9 02E6C564     JMP ADVAPI32.OpenProcessToken
13149151  - E9 DE33C864     JMP ADVAPI32.AdjustTokenPrivileges
13149156  - E9 857D4C6A     JMP SHELL32.ShellExecuteA
1314915B  - E9 98BCAB64     JMP msvcrt._onexit
13149160  - E9 CC67AC64     JMP msvcrt.sprintf
(07):跳到这里后,一直[F8]单步向下走,走到代码“INT 2D”处时停下,看堆栈,在堆栈中找到所要执行的异常处理代码位置(代码如下)。
13148002    3BC0            CMP EAX,EAX                              ; 跳到这里
13148004    9B              WAIT
13148005    43              INC EBX
13148006    4B              DEC EBX
13148007    87E6            XCHG ESI,ESP
13148009    87E6            XCHG ESI,ESP
1314800B    60              PUSHAD
1314800C    8B7424 20       MOV ESI,DWORD PTR SS:[ESP+20]
13148010    BF 5F801413     MOV EDI,virus.1314805F
13148015    A4              MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]
13148016    4F              DEC EDI
13148017    87FA            XCHG EDX,EDI
13148019    87FA            XCHG EDX,EDI
1314801B    8037 6E         XOR BYTE PTR DS:[EDI],6E
1314801E    68 42801413     PUSH virus.13148042
13148023    64:FF35 0000000>PUSH DWORD PTR FS:[0]
1314802A    64:8925 0000000>MOV DWORD PTR FS:[0],ESP
13148031    CD 2D           INT 2D                                   ; 停在这里看堆栈,寻找异常处理代码,该处的异常“Ollydbg”不能自动处理。
13148033    C3              RETN
(08):例如找到的异常处理代码所在的位置是“13148042”,那么我们就需要手动把当前调试的EIP值重新设置为“13148042”(需要手动设置的原因是OD没有识别这个异常,我们只能自己去定向这个跳转)。EIP设置完毕后,一直[F8]单步向下走,在代码“RETN”处返回(代码如下)。
13148042    3BFF            CMP EDI,EDI
13148044    9B              WAIT
13148045    90              NOP
13148046    3BFF            CMP EDI,EDI
13148048    3BFF            CMP EDI,EDI
1314804A    8BC0            MOV EAX,EAX
1314804C    B8 65801413     MOV EAX,virus.13148065
13148051    50              PUSH EAX
13148052    C2 0000         RETN 0
(09):返回后来到这里,然后一直[F8]单步向下走,在代码“RETN”处返回(代码如下)。
13148065    B9 00101413     MOV ECX,virus.13141000
1314806A    BB 00200000     MOV EBX,2000
1314806F    68 7C801413     PUSH virus.1314807C
13148074    68 59801413     PUSH virus.13148059
13148079    C2 0000         RETN 0
(10):返回后来到这里,向下翻阅代码,找到无效指定代码“ADD BYTE PTR DS:[EAX],AL”前的最后一个返回跳转代码“RETN”,这个返回跳转就是壳的结尾处了(代码如下)。
13148059    85DB            TEST EBX,EBX
1314805B    74 07           JE SHORT virus.13148064
1314805D    8031 3E         XOR BYTE PTR DS:[ECX],3E
13148060    4B              DEC EBX
13148061    41              INC ECX
13148062  ^ EB F5           JMP SHORT virus.13148059
13148064    C3              RETN
13148065    B9 00101413     MOV ECX,virus.13141000
1314806A    BB 00200000     MOV EBX,2000
1314806F    68 7C801413     PUSH virus.1314807C
13148074    68 59801413     PUSH virus.13148059
13148079    C2 0000         RETN 0
1314807C    42              INC EDX
1314807D    4A              DEC EDX
1314807E    B9 00401413     MOV ECX,virus.13144000
13148083    BB 00200000     MOV EBX,2000
13148088    68 95801413     PUSH virus.13148095
1314808D    68 59801413     PUSH virus.13148059
13148092    C2 0000         RETN 0
13148095    83EB 01         SUB EBX,1
13148098    43              INC EBX
13148099    9B              WAIT
1314809A    60              PUSHAD
1314809B    61              POPAD
1314809C    9B              WAIT
1314809D    B9 00601413     MOV ECX,virus.13146000
131480A2    BB 00100000     MOV EBX,1000
131480A7    68 B4801413     PUSH virus.131480B4                      ; ASCII "ah"
131480AC    68 59801413     PUSH virus.13148059
131480B1    C2 0000         RETN 0
131480B4    61              POPAD
131480B5    68 00221413     PUSH virus.13142200
131480BA    47              INC EDI
131480BB    4F              DEC EDI
131480BC    C3              RETN
131480BD    0000            ADD BYTE PTR DS:[EAX],AL
131480BF    0000            ADD BYTE PTR DS:[EAX],AL
131480C1    0000            ADD BYTE PTR DS:[EAX],AL
131480C3    0000            ADD BYTE PTR DS:[EAX],AL
131480C5    0000            ADD BYTE PTR DS:[EAX],AL
131480C7    0000            ADD BYTE PTR DS:[EAX],AL
131480C9    0000            ADD BYTE PTR DS:[EAX],AL
.
.
13148FF8    0000            ADD BYTE PTR DS:[EAX],AL
13148FFA    0000            ADD BYTE PTR DS:[EAX],AL
13148FFC    0000            ADD BYTE PTR DS:[EAX],AL
13148FFE    0000            ADD BYTE PTR DS:[EAX],AL
(11):返回后来到这里,这个就是病毒样本的真正OEP入口了,看入口代码的结构像汇编写的。使用OD插件DUMP出来就可以了,输入表在DUMP过程中被脱壳插件自动修复了,脱壳后的样本可以正常运行(代码如下)。
13142200    55              PUSH EBP                                 ; ntdll.7C930738
13142201    8BEC            MOV EBP,ESP
13142203    81EC 0C050000   SUB ESP,50C
13142209    57              PUSH EDI
1314220A    6A 00           PUSH 0
1314220C    68 68531413     PUSH virus.13145368                      ; ASCII "YINWSAFDWPEIRPWIEIHENANRENQUANSHILAJIHAOGUOAZHINALDAOJFAGZHIXIANLFALFJAAUFOPWLAJLFJALJFA"
13142211    68 34531413     PUSH virus.13145334                      ; ASCII "TIANYAWEISHENMEHENANLAOCHUPIANZIPEPWUAPREPAJIERPW"
13142216    6A FF           PUSH -1
13142218    FF15 28311413   CALL DWORD PTR DS:[13143128]             ; USER32.MessageBoxA
1314221E    E8 4DFFFFFF     CALL virus.13142170
13142223    85C0            TEST EAX,EAX
13142225    74 13           JE SHORT virus.1314223A
13142227    68 00531413     PUSH virus.13145300                      ; ASCII "FINDINFILESFINDINFILESFNAJIUGANDIAOTAMENBAHEHEHE"
1314222C    FF15 84301413   CALL DWORD PTR DS:[13143084]             ; virus.1314911F
13142232    6A 00           PUSH 0
13142234    FF15 BC301413   CALL DWORD PTR DS:[131430BC]             ; virus.1314912E
---------------------------------------------------------------------------------------------
第二部分:难点分析
    其实这个壳只要了解了其原理,脱起来就简单多了。关键点就是要找出它内部出现的三处异常处理代码的位置,这是脱整个壳的关键。
    大概说下“PEtite”壳的原理:
       (1):壳在一开始运行时先是在内存中解密要执行的代码,解密完毕后使用“内存访问异常”(第一处异常)来离开解密循环,然后在异常处理代码中执行后面的所有操作。
       (2):接着壳大概设置了一部分堆栈和寄存器环境变量,然后创建了一个“单步异常”(第二处异常)。这个异常的异常处理代码中有另一部分对堆栈和寄存器环境变量的设置,而“单步异常”可以使用[F8]单步直接执行过去,并且不会执行内部的异常处理代码,所以这样就做到反动态单步跟踪了。如果这样执行过去的话,由于一部分堆栈和寄存器环境变量没有得到有效的设置,所以就无法对程序去进行正确的动态跟踪了。
       (3):在内存中动态解密并修复输入表。
       (4):创建一个“INT 2D异常”(第三处异常),这个异常不会被“Ollydbg”自动识别并执行。也就是说不管你怎么做,“Ollydbg”都不会去自动寻找并执行“INT 2D异常”所产生的异常处理代码。这里就需要我们自己去看堆栈并寻找异常处理代码位置,自己去设置代码当前的EIP地址,然后从“INT 2D异常”的异常处理代码入口处开始执行剩下的操作,这样这个壳就脱完了(好象只有1到3点属于“PEtite”壳,这个第4点是被后加进来的)。
    原理看似简单,但如果自己去跟的话,如果不细心或经验不足,很多细节都会被忽略掉的。其中,“单步异常”的异常处理代码我是用内存断点定位出来的,不知道堆栈中为什么就看不到对它设置的地址呢?可能同样是在某处被秘密的隐藏起来了。就像第一处异常的异常处理代码就是在壳入口的附近创建的,看样子作者在设计这个壳时可是花去了不少的心思啊,呵呵!
---------------------------------------------------------------------------------------------
///////////////////////////////////////////////////////////////////////////////////////////////

[ 本帖最后由 coderui 于 2008-10-14 08:57 编辑 ]

评分

参与人数 1经验 +20 魅力 +1 收起 理由
qianwenxiang + 20 + 1 版区有你更精彩: )

查看全部评分

qianwenxiang
发表于 2008-10-13 19:42:10 | 显示全部楼层
占着沙发慢慢看
mox
发表于 2008-10-13 20:03:19 | 显示全部楼层
手脱怕怕    一不少心跑飞就没救了(尤其是的感染型的)
coderui
 楼主| 发表于 2008-10-13 20:19:33 | 显示全部楼层
谢谢加分,谢谢支持!
您需要登录后才可以回帖 登录 | 快速注册

本版积分规则

手机版|杀毒软件|软件论坛| 卡饭论坛

Copyright © KaFan  KaFan.cn All Rights Reserved.

Powered by Discuz! X3.4( 沪ICP备2020031077号-2 ) GMT+8, 2024-5-4 02:15 , Processed in 0.120351 second(s), 17 queries .

卡饭网所发布的一切软件、样本、工具、文章等仅限用于学习和研究,不得将上述内容用于商业或者其他非法用途,否则产生的一切后果自负,本站信息来自网络,版权争议问题与本站无关,您必须在下载后的24小时之内从您的电脑中彻底删除上述信息,如有问题请通过邮件与我们联系。

快速回复 客服 返回顶部 返回列表