////////////////////////////////////////////////////////////////////////////////////////////
文件名称:手脱bambam V0.01壳(讲解手脱未知壳的经验)
目标程序:病毒样本“Trojan/PSW.QQPass.snk”木马程序
操作环境:Windows XP-SP2
使用工具:Ollydbg 1.10版
编写作者:Coderui
编写时间:2007年12月25日
联系方式:coderui@163.com
作者博客:
c48K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8X3S2A6i4K6u0W2j5X3q4A6k6s2g2Q4x3X3g2U0L8$3#2Q4x3V1k6U0L8$3c8W2M7Y4g2A6
---------------------------------------------------------------------------------------------
介绍:
今天在分析“Trojan/PSW.QQPass.snk”木马程序时,遇到了一个以前没有见过的壳。使用PEID查壳,显示名称为“bambam V0.01 -> bedrock *”。开始还以为这个壳是加密壳或花指令壳呢,脱掉壳后对比文件大小后才发现原来是压缩壳,呵呵。貌似这个壳不太常用,因为我一直没听过,也没见过。很欣慰的想写个脱文和大家分享,结果百度了下,却发现关于这个壳的资料还真不少…………,呵呵。但我还是决定把这个简单的壳搬出来,因为每个人的脱壳思想都不同。开始拿到样本后我是把它当作未知壳直接去脱的,没有去找资料,所以大家可以体会到遇见未知壳后该去怎么手脱。其实,当大家对壳的理解到了一定的程度以后,脱壳是完全不需要找什么资料的,至于为什么还要去拿PEID查壳,原因只有一个:“看看这个壳是否是自己熟悉的。如果是熟悉的,则构思怎么去快速的脱。如果是不熟悉的,则在跟踪调试时需要多注意壳的特征,单步小心的去分析。”。
我在第一次脱这个壳的时候,我把程序本身的所有的CALL都跟进去看了下,呵呵。如果对领空掌握不好的人估计得口吐鲜血,因为这个壳中有一段是“大小循环式跳转中带有很多的CALL和RETN,而且CALL中还有CALL……,呵呵”。第二次再脱时仔细的看了下程序中CALL的地址,原来是大部分都可以F7步过的,这样脱下来,就显得这个壳很容易脱了。
说了一大堆废话,不过有价值的东西还是很多的,如果您真正理解了下边标为“重点”的经验,相信所有的压缩壳和未知压缩壳到了您手里都可以很快的拿下。再需要提升的就是脱花指令壳和加密壳了。(^_^)
---------------------------------------------------------------------------------------------
重点:
我自己总结的脱未知壳的部分经验:在脱不熟悉的壳时,一般大部分时间都是用来分析CALL和跳转指令等。遇到小跳当然是很好分析的,用眼睛看下就可以判断出怎么去走捷径路线了。遇到大小循环式跳转放在一块时,一般都是在解压或解密,对付它也不需要实际跟,只要去计算出所有跳转的范围,把最后跳出的那个跳转下断点后运行就行了,非常节省时间。遇到CALL时,如果调用的是前边的地址,一般可以步过;如果调用的是后边比较远的地址,一般也可以步过;但如果调用的是离自己很近的地址,如果您不想跑飞的话,那么就请跟进去吧(因为CALL可以当JMP用)。遇到循环式跳转中带有RETN的,要把可疑的都设置上断点,然后在跟踪调试时把不重要的逐个取消断点。遇到大小循环式跳转中带有CALL和RETN时,要把可疑的CALL和RETN都设置上断点,然后在跟踪调试时跟进所有的CALL,最后把不重要的逐个取消断点。进行上边这些步骤,可能会花费很长很多的时间,当然也有快速的方法,那么就是对关键的API下断。不过我喜欢单步跟踪调试的乐趣,这样也可以提高自己的分析能力,不知道大家喜欢什么~~~!
---------------------------------------------------------------------------------------------
OD设置:(OD设置为不忽略任何异常。[F2]:下软断点、[F4]:执行到当前代码处、[F7]:单步步入、[F8]单步步过、[F9]运行。)
00419280 > 6A 14 PUSH 14 ;程序载入后停在这里。向下[F8]单步步过。
00419282 E8 9A050000 CALL 9607f414.00419821 ;[F8]单步步过。
00419287 8BD8 MOV EBX,EAX
00419289 53 PUSH EBX
0041928A 68 FB984100 PUSH 9607f414.004198FB
0041928F E8 6CFDFFFF CALL 9607f414.00419000 ;[F8]单步步过。
00419294 B9 05000000 MOV ECX,5
00419299 89DE MOV ESI,EBX
0041929B BF FB984100 MOV EDI,9607f414.004198FB
004192A0 53 PUSH EBX
004192A1 F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS>
004192A3 E8 8D050000 CALL 9607f414.00419835 ;[F8]单步步过。
004192A8 8B3D 03994100 MOV EDI,DWORD PTR DS:[419903]
004192AE A1 2B994100 MOV EAX,DWORD PTR DS:[41992B]
004192B3 66:8B15 2F99410>MOV DX,WORD PTR DS:[41992F]
004192BA B9 80924100 MOV ECX,OFFSET 9607f414.<模块入口点>
004192BF 2BCF SUB ECX,EDI
004192C1 8945 E8 MOV DWORD PTR SS:[EBP-18],EAX
004192C4 890D 6B994100 MOV DWORD PTR DS:[41996B],ECX
004192CA 66:8955 EC MOV WORD PTR SS:[EBP-14],DX
004192CE 8B41 3C MOV EAX,DWORD PTR DS:[ECX+3C]
004192D1 2BD2 SUB EDX,EDX
004192D3 03C1 ADD EAX,ECX
004192D5 83EC F0 SUB ESP,-10
004192D8 66:8B48 06 MOV CX,WORD PTR DS:[EAX+6]
004192DC 66:8B50 14 MOV DX,WORD PTR DS:[EAX+14]
004192E0 81E1 FFFF0000 AND ECX,0FFFF
004192E6 8D5C02 18 LEA EBX,DWORD PTR DS:[EDX+EAX+18]
004192EA 8D41 FF LEA EAX,DWORD PTR DS:[ECX-1]
004192ED 09C0 OR EAX,EAX
004192EF /0F8E 39010000 JLE 9607f414.0041942E
004192F5 |8945 F0 MOV DWORD PTR SS:[EBP-10],EAX
004192F8 |C645 FF 00 MOV BYTE PTR SS:[EBP-1],0
004192FC |8D7D E8 LEA EDI,DWORD PTR SS:[EBP-18]
004192FF |53 PUSH EBX
00419300 |5E POP ESI
00419301 |8A0E MOV CL,BYTE PTR DS:[ESI]
00419303 |8A17 MOV DL,BYTE PTR DS:[EDI]
00419305 |8AC1 MOV AL,CL
00419307 |3ACA CMP CL,DL
00419309 |75 1E JNZ SHORT 9607f414.00419329 ;[F8]下跳
0041930B |84C0 TEST AL,AL
0041930D |74 16 JE SHORT 9607f414.00419325
.
.
.
00419329 1BC0 SBB EAX,EAX ;跳到这里,[F8]单步步过。
0041932B 83D8 FF SBB EAX,-1
0041932E 09C0 OR EAX,EAX
00419330 75 04 JNZ SHORT 9607f414.00419336 ;[F8]下跳
00419332 C645 FF 01 MOV BYTE PTR SS:[EBP-1],1
00419336 8B43 10 MOV EAX,DWORD PTR DS:[EBX+10] ;跳到这里,[F8]单步步过。
00419339 09C0 OR EAX,EAX
0041933B 0F84 DD000000 JE 9607f414.0041941E
00419341 8B43 08 MOV EAX,DWORD PTR DS:[EBX+8]
00419344 50 PUSH EAX
00419345 E8 D7040000 CALL 9607f414.00419821
0041934A 8A4D FF MOV CL,BYTE PTR SS:[EBP-1]
0041934D 83C4 04 ADD ESP,4
00419350 08C9 OR CL,CL
00419352 8B4B 08 MOV ECX,DWORD PTR DS:[EBX+8]
00419355 8945 F8 MOV DWORD PTR SS:[EBP-8],EAX
00419358 C745 F4 0000000>MOV DWORD PTR SS:[EBP-C],0
0041935F 74 61 JE SHORT 9607f414.004193C2 ;[F8]下跳
00419361 8B15 07994100 MOV EDX,DWORD PTR DS:[419907]
.
.
.
004193C2 8B35 6B994100 MOV ESI,DWORD PTR DS:[41996B] ;跳到这里,[F8]单步步过。
004193C8 8B7B 0C MOV EDI,DWORD PTR DS:[EBX+C]
004193CB 51 PUSH ECX
004193CC 5A POP EDX
004193CD 03F7 ADD ESI,EDI
004193CF 8BF8 MOV EDI,EAX
004193D1 C1E9 02 SHR ECX,2
004193D4 F3:A5 REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS>
004193D6 52 PUSH EDX
004193D7 59 POP ECX
004193D8 83E1 03 AND ECX,3
004193DB F3:A4 REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[>
004193DD 8B35 6B994100 MOV ESI,DWORD PTR DS:[41996B] ; 9607f414.00400000
004193E3 8B7B 0C MOV EDI,DWORD PTR DS:[EBX+C]
004193E6 03F7 ADD ESI,EDI
004193E8 56 PUSH ESI
004193E9 50 PUSH EAX
004193EA E8 11FCFFFF CALL 9607f414.00419000 ;[F8]单步步过。
004193EF 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8]
004193F2 50 PUSH EAX
004193F3 E8 3D040000 CALL 9607f414.00419835 ;[F8]单步步过。
004193F8 8A45 FF MOV AL,BYTE PTR SS:[EBP-1]
004193FB 83C4 0C ADD ESP,0C
004193FE 84C0 TEST AL,AL
00419400 74 1C JE SHORT 9607f414.0041941E ;[F8]下跳
.
.
.
0041941E 8B45 F0 MOV EAX,DWORD PTR SS:[EBP-10] ;跳到这里,[F8]单步步过。
00419421 83C3 28 ADD EBX,28
00419424 48 DEC EAX
00419425 8945 F0 MOV DWORD PTR SS:[EBP-10],EAX
00419428 ^ 0F85 CAFEFFFF JNZ 9607f414.004192F8 ;这里是个回跳,不要跳。经过分析回跳所在段内的全部CALL和跳转都是小范围的,没有飞出去的可能。所以我们可以走捷径去快速执行完这段。
0041942E E8 BD000000 CALL 9607f414.004194F0 ;我们可以直接[F4]:执行到当前代码处。这个CALL是用来解数据用的(因为进去分析过了),我们这里可以直接[F8]单步步过。这里会执行一会才停下来,因为解数据需要一段时间。
00419433 A1 6B994100 MOV EAX,DWORD PTR DS:[41996B] ;继续向下[F8]单步步过。
.
.
.
004194AC 08C0 OR AL,AL
004194AE 74 36 JE SHORT 9607f414.004194E6 ;这里会有一个向下的跳,[F8]跳。
004194B0 8B35 1B994100 MOV ESI,DWORD PTR DS:[41991B] ; 9607f414.00409010
004194B6 A1 77994100 MOV EAX,DWORD PTR DS:[419977]
004194BB 8B3D 7F994100 MOV EDI,DWORD PTR DS:[41997F]
004194C1 8B1D 7B994100 MOV EBX,DWORD PTR DS:[41997B]
.
.
.
004194DC 8B46 04 MOV EAX,DWORD PTR DS:[ESI+4]
004194DF 83C6 04 ADD ESI,4
004194E2 09C0 OR EAX,EAX
004194E4 ^ 75 EE JNZ SHORT 9607f414.004194D4
004194E6 E8 15030000 CALL 9607f414.00419800 ;跳到这里,我们不要动,然后看上下文代码,是不是感觉不对劲?所以这里我们要使用F8步过,F7进去看下吧!
004194EB 90 NOP
004194EC 90 NOP
004194ED 90 NOP
004194EE 90 NOP
004194EF 90 NOP
004194F0 51 PUSH ECX
.
.
.
00419800 55 PUSH EBP ;F7后来到这里。我们F8单步向下走。
00419801 8BEC MOV EBP,ESP
00419803 53 PUSH EBX
00419804 56 PUSH ESI
00419805 57 PUSH EDI
00419806 A1 FB984100 MOV EAX,DWORD PTR DS:[4198FB]
0041980B 0305 6B994100 ADD EAX,DWORD PTR DS:[41996B] ; 9607f414.00400000
00419811 A3 FB984100 MOV DWORD PTR DS:[4198FB],EAX
00419816 - FF25 FB984100 JMP DWORD PTR DS:[4198FB] ;这里是个远跳(也叫跨段大跳),[F8]跳。
0041981C 5F POP EDI
0041981D 5E POP ESI
0041981E 5B POP EBX
0041981F 5D POP EBP
.
.
.
00404830 55 PUSH EBP ;经过跨段大跳后,来到这里。我们看看这里是不是很熟悉的啊。没错,这里就是程序的真正入口点了。我们在上边的CALL没使用[F8]步过就对了,不然就跑飞了。其实,那个CALL就是个变种后的JMP跳转,是无返回的。如果跑起来计算机系统就要中“Trojan/PSW.QQPass.snk”毒了,呵呵。安全很重要啊!!!!
00404831 8BEC MOV EBP,ESP
00404833 83C4 E4 ADD ESP,-1C
00404836 53 PUSH EBX
00404837 56 PUSH ESI
00404838 57 PUSH EDI
00404839 33C0 XOR EAX,EAX
0040483B 8945 E4 MOV DWORD PTR SS:[EBP-1C],EAX
0040483E 8945 EC MOV DWORD PTR SS:[EBP-14],EAX
00404841 8945 E8 MOV DWORD PTR SS:[EBP-18],EAX
00404844 B8 C8474000 MOV EAX,9607f414.004047C8
00404849 E8 1AF0FFFF CALL 9607f414.00403868
0040484E 33C0 XOR EAX,EAX
00404850 55 PUSH EBP
00404851 68 514A4000 PUSH 9607f414.00404A51
00404856 64:FF30 PUSH DWORD PTR FS:[EAX]
00404859 64:8920 MOV DWORD PTR FS:[EAX],ESP
0040485C E8 17FFFFFF CALL 9607f414.00404778
00404861 84C0 TEST AL,AL
00404863 E8 FCFDFFFF CALL 9607f414.00404664
00404868 E8 B3FDFFFF CALL 9607f414.00404620
0040486D 84C0 TEST AL,AL
0040486F 74 27 JE SHORT 9607f414.00404898
00404871 68 B0664000 PUSH 9607f414.004066B0
00404876 E8 09F1FFFF CALL 9607f414.00403984 ; JMP 到 kernel32.GetSystemTime
0040487B 66:C705 B066400>MOV WORD PTR DS:[4066B0],7AE
00404884 68 B0664000 PUSH 9607f414.004066B0
00404889 E8 3EF1FFFF CALL 9607f414.004039CC ; JMP 到 kernel32.SetSystemTime
0040488E 68 204E0000 PUSH 4E20
00404893 E8 44F1FFFF CALL 9607f414.004039DC ; JMP 到 kernel32.Sleep
---------------------------------------------------------------------------------------------
总结:
上边已经找到了病毒程序真正的入口点了,我们剩下的就是DUMP、修复和优化了。DUMP后使用PEID查壳显示为“Borland Delphi 6.0 - 7.0”,脱壳前文件大小为:39424字节,脱壳后文件大小为:108544字节。只是奇怪的是,为什么这个壳很少见呢?反正我是第一次见过这个奇怪名字的壳“bambam V0.01”。
---------------------------------------------------------------------------------------------
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课