这两天闲着没事看了一下脱壳教程http://bbs.pediy.com/showthread.php?t=20366,以前没脱过壳,一直就得加壳挺没意思的。这个教程中第一个例子比较容易,可是第二个例子的输入表不能用ImportRec修复。第二个例子加的壳是PE-Armor V0.49,这到底是个什么壳我也不知道。(第二个例子虽然加的是PE-Armor V0.49,但是本文分析的文件不是这个教程中的,末尾有附件)
按照教程可得到入口的汇编代码如下:
004010CC FFD7 CALL EDI
004010CE 58 POP EAX
004010CF 83EC 44 SUB ESP,44
004010D2 56 PUSH ESI
004010D3 90 NOP
004010D4 E8 B518F8FF CALL 0038298E
一看这入口就有点奇怪,ImportRec修复一下输入表,入口改成push ebp和mov ebp,esp,运行一下弹出错误的对话框。这时候拿加壳前的程序比较一下,发现有些函数调用改成了如下形式:
004010D3 90 NOP
004010D4 E8 B518F8FF CALL 0038298E
004010D9 8BF0 MOV ESI,EAX
根据对照上面调用的是GetCommandLineA。
进去0038298E:
0038298E 50 PUSH EAX
0038298F 60 PUSHAD
00382990 E8 06000000 CALL 0038299B
00382995 8B6424 08 MOV ESP,DWORD PTR SS:[ESP+8]
00382999 EB 20 JMP SHORT 003829BB
0038299B 64:FF35 0000000>PUSH DWORD PTR FS:[0]
003829A2 64:8925 0000000>MOV DWORD PTR FS:[0],ESP
003829A9 9C PUSHFD
003829AA 810C24 00010000 OR DWORD PTR SS:[ESP],100
003829B1 9D POPFD
003829B2 90 NOP
003829B3 64:8F05 0000000>POP DWORD PTR FS:[0]
CALL 0038299B这个调用是个关键,我开始以为这个调用没什么用,经过多少次F8(不知道按了多少次CTRL+F2),终于知道这个地方只能F7。这个调用用于安装SEH,然后触发单步异常。执行这个NOP指令后,就会触发异常。当然这个地方也让我CTRL+F2了N回,一直想NOP怎么会触发异常,最后没办法打开调试选项一个个试。触发异常后会进入00382995。最后F7到003829CC:
003829CC 5D POP EBP
003829CD 8B6D 00 MOV EBP,DWORD PTR SS:[EBP]
003829D0 8B7C24 24 MOV EDI,DWORD PTR SS:[ESP+24] ; unpackme.004010D9
003829D4 8BB5 AF060000 MOV ESI,DWORD PTR SS:[EBP+6AF]
003829DA 03F5 ADD ESI,EBP
003829DC 8B06 MOV EAX,DWORD PTR DS:[ESI]
003829DE 33D2 XOR EDX,EDX
003829F5 3BF8 CMP EDI,EAX
003829F7 75 0A JNZ SHORT 00382A03
003829F9 0AD2 OR DL,DL
003829FB 75 04 JNZ SHORT 00382A01
003829FD EB 09 JMP SHORT 00382A08
003829FF EB 02 JMP SHORT 00382A03
00382A01 EB 2F JMP SHORT 00382A32
00382A03 83C6 08 ADD ESI,8
00382A06 ^ EB D4 JMP SHORT 003829DC
00382A08 8B46 04 MOV EAX,DWORD PTR DS:[ESI+4]
00382A17 2BC7 SUB EAX,EDI
00382A19 F7D0 NOT EAX
00382A1B C1C0 10 ROL EAX,10
00382A2A 8B00 MOV EAX,DWORD PTR DS:[EAX]
00382A2C 894424 20 MOV DWORD PTR SS:[ESP+20],EAX
00382A30 61 POPAD
00382A31 C3 RETN
这段汇编代码中有不少垃圾指令,这个我没有列出来。粗略看这段代码,它应该试在搜索什么东西。观察EDI值为004010D9,难道就为了搜索这个值?如下数据是ESI所指向的地址。
00383474 00401A5C unpackme.00401A5C
00383478 9C481A1B
0038347C 00401523 unpackme.00401523
00383480 9C4414E2
00383484 0040346F unpackme.0040346F
00383488 9C40342E
。。。。。。
003835B4 004010D9 unpackme.004010D9
003835B8 9C5C1098
搜索之后是一段计算过程,计算过程如下:
EDI = 004010D9 EAX = 9C5C1098
EAX = EAX - EDI = 63E40040
ROL 10就是将高低调换一下位置,最后
EAX = 004063E4
这时候查看数据
004063E4 7C812C8D kernel32.GetCommandLineA
004063E8 7C810082 kernel32.GlobalUnlock
004063EC 7C839418 kernel32._lread
目前就分析到此了,能力有限还没法修复脱壳后的程序。被替换的函数有好多呢,不知道哪位高人有没有简单易懂的方法快速替换。看了几个脱这个壳的例子,都没看懂。有人用脚本,这个更不懂了。最后说下怎么快速到达入口004010CC,教程上的方法适合第一次跟踪。如果像我这样不停的CTRL+F2那就有点费时了。我的方法:
1、忽略所有异常 在004010CC下内存写入断点,F9;
2、如果没啥问题的话应该断在00382712,这时候在00382715(这个地址可以选别的)F2,清除内存断点,F9
3、中断在00382715,清除断点,然后在004010CC内存访问断点,F9;
4、最后就到达了00401CC了。
一些简单的壳分析http://bbs.pediy.com/showthread.php?t=106596 第二个例子就在其中
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!