iawen 发表于 2007-9-28 22:20:06

脱PECompact2.7壳的总结

【文章标题】: 脱PECompact2.7壳的总结
【文章作者】: iawen
【作者邮箱】: [email protected]
【作者QQ号】: 160193626
【软件名称】: 记事本notepad.exe
【软件大小】: 52KB
【下载地址】: 自己搜索下载
【保护方式】: PECompact2.7
【编写语言】: VC++
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
      用PEid检测为:
      PECompact 2.x -> Jeremy Collake

      用OD载入:
004010CC notepad.>B8 48E84000      mov eax,notepad.0040E848
004010D1            50               push eax
004010D2            64:FF35 00000000 push dword ptr fs:
004010D9            64:8925 00000000 mov dword ptr fs:,esp
004010E0            33C0             xor eax,eax

      一看到fs:,本能猜到壳用到了异常,决定先用ESP定律试试,F8单步到:
004010D9            64:8925 00000000 mov dword ptr fs:,esp

   此时ESP=0013FFBC,下断:hr 0013FFBC,然后按Shift+F9,断下:
0040E877            83C4 04          add esp,4
0040E87A            55               push ebp
0040E87B            53               push ebx
0040E87C            51               push ecx
0040E87D            57               push edi
0040E87E            56               push esi

      一步步单步跟进:
0040E89B            03CA             add ecx,edx
0040E89D            8B01             mov eax,dword ptr ds:
0040E89F            FFD0             call eax                                 ; kernel32.VirtualAlloc

      记住这个,这个对分析PECompact加壳的原理有用!
0040E8E0            8B4B 0C          mov ecx,dword ptr ds:
0040E8E3            894E 14          mov dword ptr ds:,ecx
0040E8E6            FFD7             call edi
//此处,我们可以跟进分析,也可以不跟进,往下看:
0040E8E6            FFD7             call edi
0040E8E8            8985 FA120010    mov dword ptr ss:,eax
0040E8EE            8BF0             mov esi,eax
0040E8F0            8B4B 14          mov ecx,dword ptr ds:
0040E8F3            5A               pop edx
0040E8F4            EB 0C            jmp short notepad.0040E902
0040E8F6            03CA             add ecx,edx
0040E8F8            68 00800000      push 8000
0040E8FD            6A 00            push 0
0040E8FF            57               push edi
0040E900            FF11             call dword ptr ds:
0040E902            8BC6             mov eax,esi
0040E904            5A               pop edx
0040E905            5E               pop esi
0040E906            5F               pop edi
0040E907            59               pop ecx
0040E908            5B               pop ebx
0040E909            5D               pop ebp
0040E90A            FFE0             jmp eax//此处就是跳到OEP了

      我们还是跟进一下,看看壳是如何处理的吧!
0003094B            0053 57          add byte ptr ds:,dl
0003094E            56               push esi
0003094F            55               push ebp
00030950            E8 00000000      call 00030955

000309CC            6A 40            push 40
000309CE            68 00100000      push 1000
000309D3            51               push ecx
000309D4            6A 00            push 0
000309D6            FF95 291E0010    call dword ptr ss:         ; kernel32.VirtualAlloc

00030AD8            68 00800000      push 8000
00030ADD            6A 00            push 0
00030ADF            FFB5 191E0010    push dword ptr ss:
00030AE5            FF95 2D1E0010    call dword ptr ss:         ; kernel32.VirtualFree
      //跟到些处,我们发现了与VirtualAlloc相对应的VirtualFree,也发现了大家常说的特征码:push 8000了,……#……

00030AEB            8B46 0C          mov eax,dword ptr ds:
//载入基址00400000
00030AEE            03C7             add eax,edi
//eax=00400000+10CC,就是OEP了

00030AF0            5D               pop ebp
00030AF1            5E               pop esi
00030AF2            5F               pop edi
00030AF3            5B               pop ebx
00030AF4            C3               retn//恢复堆栈后,返回

0040E904            5A               pop edx
0040E905            5E               pop esi
0040E906            5F               pop edi
0040E907            59               pop ecx
0040E908            5B               pop ebx
0040E909            5D               pop ebp
0040E90A          - FFE0             jmp eax             ; notepad.<模块入口点>
看看此时的寄存器值:
EAX 004010CC notepad.<模块入口点>
ECX 0013FFB0
EDX 7C9585EC ntdll.KiFastSystemCallRet
EBX 7FFD7000
ESP 0013FFC4
EBP 0013FFF0
ESI 00000000
EDI 00000000
EIP 0040E90A notepad.0040E90A

对比一下程序载入时的值:
EAX 00000000
ECX 0013FFB0
EDX 7C9585EC ntdll.KiFastSystemCallRet
EBX 7FFD8000
ESP 0013FFC4
EBP 0013FFF0
ESI 00000000
EDI 00000000
EIP 004010CC notepad.<模块入口点>

=================呵呵,明白了吧!
…………
=================不过,你明白了,我自己却还是糊涂着呢!^#^

      还有一种快捷方式:
        1、OD载入后,直接下断点:bp VirtualFree,然后按Shift+F9,就会断在第一次调用处:
000309D6            FF95 291E0010    call dword ptr ss:         ; kernel32.VirtualAlloc
        2、然后搜索特征码:Ctrl+F,搜索push 8000,就会来到第二次调用VirtualFree前:
00030AD8            68 00800000      push 8000
00030ADD            6A 00            push 0
00030ADF            FFB5 191E0010    push dword ptr ss:
00030AE5            FF95 2D1E0010    call dword ptr ss:         ; kernel32.VirtualFree

现在我们明白了,就可以一次下断bp VirtualFree,连续按两次Shift+F9运行,然后按Alt+F9返回到程序领空,就可以到了最后一个关键点了,呵呵!
试试了一下:汇编及VB,只要一次Shift+F9或F9就能OK,跟进了一个进去看,也是两次调用VirtualFree,不知为什么只一次就OK!Delphi、Borland C++、VC++需要两次!

yingfeng 发表于 2007-9-28 22:29:44

不错,菜鸟我也来学习下.

jinbbs 发表于 2007-9-28 22:47:32

我也来学习一下了

zhangyun 发表于 2007-9-29 09:00:22

支持写的不错 值得学习

温柔 发表于 2007-9-29 11:25:18

本菜来好好学习下。。。。

ABCdiyPE 发表于 2007-10-2 16:07:56

顶你一下。。。。

不懂破解 发表于 2007-10-3 01:34:00

先回复
然后再学习
LZ总结的真是精辟

longyun 发表于 2007-10-3 10:36:18

支持写的不错 值得学习

nykj 发表于 2007-10-4 01:54:24

我还没遇见过这样的壳,先留下

brantjun 发表于 2007-10-5 15:53:18

向高手学习!向高手学习!
页: [1] 2
查看完整版本: 脱PECompact2.7壳的总结