| 
注册时间2007-8-28
阅读权限20
最后登录1970-1-1UID35582 以武会友  
 
 该用户从未签到 | 
 
| 【文章标题】: 脱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:[0]
 004010D9            64:8925 00000000 mov dword ptr fs:[0],esp
 004010E0            33C0             xor eax,eax
 
 一看到fs:[0],本能猜到壳用到了异常,决定先用ESP定律试试,F8单步到:
 004010D9            64:8925 00000000 mov dword ptr fs:[0],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:[ecx]
 0040E89F            FFD0             call eax                                 ; kernel32.VirtualAlloc
 
 记住这个,这个对分析PECompact加壳的原理有用!
 0040E8E0            8B4B 0C          mov ecx,dword ptr ds:[ebx+C]
 0040E8E3            894E 14          mov dword ptr ds:[esi+14],ecx
 0040E8E6            FFD7             call edi
 //此处,我们可以跟进分析,也可以不跟进,往下看:
 0040E8E6            FFD7             call edi
 0040E8E8            8985 FA120010    mov dword ptr ss:[ebp+100012FA],eax
 0040E8EE            8BF0             mov esi,eax
 0040E8F0            8B4B 14          mov ecx,dword ptr ds:[ebx+14]
 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:[ecx]
 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:[ebx+57],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:[ebp+10001E29]         ; kernel32.VirtualAlloc
 
 00030AD8            68 00800000      push 8000
 00030ADD            6A 00            push 0
 00030ADF            FFB5 191E0010    push dword ptr ss:[ebp+10001E19]
 00030AE5            FF95 2D1E0010    call dword ptr ss:[ebp+10001E2D]         ; kernel32.VirtualFree
 //跟到些处,我们发现了与VirtualAlloc相对应的VirtualFree,也发现了大家常说的特征码:push 8000了,……#……
 
 00030AEB            8B46 0C          mov eax,dword ptr ds:[esi+C]
 //载入基址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:[ebp+10001E29]         ; 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:[ebp+10001E19]
 00030AE5            FF95 2D1E0010    call dword ptr ss:[ebp+10001E2D]         ; kernel32.VirtualFree
 
 现在我们明白了,就可以一次下断bp VirtualFree,连续按两次Shift+F9运行,然后按Alt+F9返回到程序领空,就可以到了最后一个关键点了,呵呵!
 试试了一下:汇编及VB,只要一次Shift+F9或F9就能OK,跟进了一个进去看,也是两次调用VirtualFree,不知为什么只一次就OK!Delphi、Borland C++、VC++需要两次!
 | 
 评分
查看全部评分
 |