用内存断点加esp定律脱 PEtite 2.2 -> Ian Luck  脱壳手记


0046D042 >  B8 00D04600     MOV EAX,AD_CM#3.0046D000     //用OD载入后，停在这里。不忽略所有异常。F9运行，两次SHIFT +F9后，程序运行 
0046D047    68 B4A64500     PUSH AD_CM#3.0045A6B4
0046D04C    64:FF35 0000000>PUSH DWORD PTR FS:[0]
0046D053    64:8925 0000000>MOV DWORD PTR FS:[0],ESP
0046D05A    66:9C           PUSHFW
0046D05C    60              PUSHAD


0045A74D    5A              POP EDX       ; AD_CM#3.0046D1B8      //重来，在通过第一次异常后，下内存访问断点
0045A74E    64:8F05 0000000>POP DWORD PTR FS:[0]
0045A755    58              POP EAX
0045A756    6A 00           PUSH 0
0045A758    53              PUSH EBX


内存镜像，项目 19
 地址=00401000
 大小=0005A000 (368640.)
 Owner=AD_CM#3  00400000
 区段=.petite
 包含=code                          //此处下内存访问断点
 类型=Imag 01001002
 访问=R
 初始访问=RWE


0045A976    33C0            XOR EAX,EAX                         //中断在此，然后取消内存断点，再用esp定律在0012ffc0处下硬件写入-dword断点。在0012ffa0下断也可以，不过要多走几步才能到程序的入口处。
0045A978    64:8B18         MOV EBX,DWORD PTR FS:[EAX]
0045A97B    8B1B            MOV EBX,DWORD PTR DS:[EBX]
0045A97D    8D63 AE         LEA ESP,DWORD PTR DS:[EBX-52]
0045A980    61              POPAD


004584C1    8BEC            MOV EBP,ESP              //硬件中断后就来到程序的入口处了。我们将鼠标上移，代码变成了如下：
004584C3    83C4 F4         ADD ESP,-0C
004584C6    B8 70834500     MOV EAX,AD_CM#3.00458370
004584CB    E8 60DAFAFF     CALL AD_CM#3.00405F30
004584D0    A1 80A54500     MOV EAX,DWORD PTR DS:[45A580]


004584BF    0055 8B         ADD BYTE PTR SS:[EBP-75],DL          //上移后，指令变成这样。看来 此处有一花指令，把00 nop掉
004584C2    EC              IN AL,DX                                 ; I/O 命令
004584C3    83C4 F4         ADD ESP,-0C
004584C6    B8 70834500     MOV EAX,AD_CM#3.00458370
004584CB    E8 60DAFAFF     CALL AD_CM#3.00405F30
004584D0    A1 80A54500     MOV EAX,DWORD PTR DS:[45A580]


004584C0    55              PUSH EBP                     //nop后变成这样，看，是不是入口处!!快点dump吧。
004584C1    8BEC            MOV EBP,ESP
004584C3    83C4 F4         ADD ESP,-0C
004584C6    B8 70834500     MOV EAX,AD_CM#3.00458370
004584CB    E8 60DAFAFF     CALL AD_CM#3.00405F30
004584D0    A1 80A54500     MOV EAX,DWORD PTR DS:[45A580]


用impr修复后正常运行，但就是退出有异常。我们再载入脱壳修复后的程序看看，不忽略所有异常，F9，运行，再点关闭。很快就出现异常了。看堆栈：
0012FF7C   0040364C  返回到 1_.0040364C               //注意0040364C这个地址了，应该就是这里出的错!
0012FF80   0012FFB4  指针到下一个 SEH 记录
0012FF84   0040365A  SE 句柄
0012FF88   0012FF98


好，现在我们重新载入脱壳修复后的程序，CTRL+G ，输入0040364C，
00403648   . /74 02         JE SHORT 1_.0040364C      // 在这里下断。点关闭程序，中断在些。此处未跳到0040364C，修改为jmp
0040364A   . |FFD0          CALL EAX                  //不能执行此句，否则就引起异常了
0040364C   > \85DB          TEST EBX,EBX
保存后就一切OK了。正常运行，没有任何错误了。收工了。

附件下载请到
http://www.chinadfcg.com/viewthread.php?tid=6452
我已经将动画，脱文和脱壳目标一起打包了。（这里提供空间太小，不方便上传）
