1.载入PEID
ASProtect v1.23 RC1
常见ASprotect版本壳:
ASProtect 1.23 RC4 按shift+f9键26次后来到典型异常
ASProtect 1.31 04.27 按shift+f9键36次后来到典型异常
ASProtect 1.31 05.18 按shift+f9键40次后来到典型异常
ASProtect 1.31 06.14 按shift+f9键38次后来到典型异常
2.载入OD,不勾选内存访问异常,其他异常全部勾选,然后使用最后一次异常法,应该是第26次,第27次就会跑飞
00401000 > 68 01C06D00 push SoWorker.006DC001 ; //入口点 00401005 E8 01000000 call SoWorker.0040100B 0040100A C3 retn 0040100B C3 retn 0040100C 74 23 je short SoWorker.00401031 0040100E C039 74 sar byte ptr ds:[ecx],74 00401011 0FD19CA4 0599E0>psrlw mm3,qword ptr ss:[esp+CFE09905] 00401019 AA stos byte ptr es:[edi]
3.落脚点在这个位置,还是像之前脱ASProtect一样,往下拉找到最近的一个retn,然后让程序运行过去
00C339EC 3100 xor dword ptr ds:[eax],eax ; //落脚点 00C339EE 64:8F05 0000000>pop dword ptr fs:[0] 00C339F5 58 pop eax 00C339F6 833D B07EC300 0>cmp dword ptr ds:[C37EB0],0 00C339FD 74 14 je short 00C33A13 00C339FF 6A 0C push 0C 00C33A01 B9 B07EC300 mov ecx,0C37EB0 00C33A06 8D45 F8 lea eax,dword ptr ss:[ebp-8] 00C33A09 BA 04000000 mov edx,4 00C33A0E E8 2DD1FFFF call 00C30B40 00C33A13 FF75 FC push dword ptr ss:[ebp-4] 00C33A16 FF75 F8 push dword ptr ss:[ebp-8] 00C33A19 8B45 F4 mov eax,dword ptr ss:[ebp-C] 00C33A1C 8338 00 cmp dword ptr ds:[eax],0 00C33A1F 74 02 je short 00C33A23 00C33A21 FF30 push dword ptr ds:[eax] 00C33A23 FF75 F0 push dword ptr ss:[ebp-10] 00C33A26 FF75 EC push dword ptr ss:[ebp-14] 00C33A29 C3 retn ; //最近的tetn 00C33A2A 5F pop edi 00C33A2B 5E pop esi 00C33A2C 5B pop ebx
4.程序运行到最近的retn后,我们就可以开始寻找丢失的代码了。不过这里可以先给大家看下假的OEP,打开内存窗口,在401000处下段然后shift+F9运行一次就来到假的OEP,落点处就是假的OEP,代码往上拉可以看到很多空的位置,这里就是待会找回丢失的代码后需要补充的位置了。
004F27A7 ^EB F8 jmp short SoWorker.004F27A1 004F27A9 0000 add byte ptr ds:[eax],al 004F27AB 0000 add byte ptr ds:[eax],al 004F27AD 0000 add byte ptr ds:[eax],al 004F27AF 0000 add byte ptr ds:[eax],al 004F27B1 0000 add byte ptr ds:[eax],al 004F27B3 0000 add byte ptr ds:[eax],al 004F27B5 0000 add byte ptr ds:[eax],al 004F27B7 0000 add byte ptr ds:[eax],al 004F27B9 0000 add byte ptr ds:[eax],al 004F27BB 0000 add byte ptr ds:[eax],al 004F27BD 0000 add byte ptr ds:[eax],al 004F27BF 0000 add byte ptr ds:[eax],al 004F27C1 0000 add byte ptr ds:[eax],al 004F27C3 0000 add byte ptr ds:[eax],al 004F27C5 0000 add byte ptr ds:[eax],al 004F27C7 0000 add byte ptr ds:[eax],al 004F27C9 0000 add byte ptr ds:[eax],al 004F27CB 0000 add byte ptr ds:[eax],al 004F27CD 0000 add byte ptr ds:[eax],al 004F27CF FF15 9CC25200 call dword ptr ds:[52C29C] ; //假的OEP 004F27D5 33D2 xor edx,edx 004F27D7 8AD4 mov dl,ah 004F27D9 8915 34306900 mov dword ptr ds:[693034],edx 004F27DF 8BC8 mov ecx,eax 004F27E1 81E1 FF000000 and ecx,0FF 004F27E7 890D 30306900 mov dword ptr ds:[693030],ecx 004F27ED C1E1 08 shl ecx,8 004F27F0 03CA add ecx,edx 004F27F2 890D 2C306900 mov dword ptr ds:[69302C],ecx 004F27F8 C1E8 10 shr eax,10 004F27FB A3 28306900 mov dword ptr ds:[693028],eax 004F2800 6A 01 push 1 004F2802 E8 933B0000 call SoWorker.004F639A
5.然后重新载入程序,运行完步骤1-3的操作,也就是让程序运行到最近的一个retn处。然后看堆栈窗口第四行(也就是程序名下面第二行)的值”0012ffa4”
0012FF5C 00C45A1C //第一行 0012FF60 00400000 SoWorker.00400000 0012FF64 E3DE7228 0012FF68 0012FFA4 0012FF6C 00C20000
6.命令行下硬件访问断点”hr 0012ffa4”然后shift+F9运行一次,落脚后先F8单步跟一会。
00C45C07 /26:EB 01 jmp short 00C45C0B ; //落脚点 00C45C0A |C7 ??? 00C45C0B EB 02 jmp short 00C45C0F 00C45C0D CD20 83EC372E vxdjump 2E37EC83 00C45C13 EB 01 jmp short 00C45C16 00C45C15 - E9 8D642479 jmp 79E8C0A7 00C45C1A 64:EB 01 jmp short 00C45C1E
7.一直到程序运行到这里,之前应该是没有call的,下面开始可能就会有call了。ASProtect的call可能会经常跑飞,所以我们遇到call就F7跟进去,没有call还是可以使用F8,当然你也可以一直使用F7,效果是一样的。
00C45C3B BD 415CC400 mov ebp,0C45C41 ; //到这里 00C45C40 FF55 03 call dword ptr ss:[ebp+3] ; //这里就F7跟进 00C45C43 E8 4D5CC400 call 0188B895 00C45C48 9A E969F29A 5DF>call far F35D:9AF269E9 00C45C4F EB 02 jmp short 00C45C53 00C45C51 CD20 1BE9EB02 vxdjump 2EBE91B 00C45C57 CD20 33E8EB02 vxdjump 2EBE833 00C45C5D CD20 EB010F8D vxdcall 8D0F01EB
8.F7跟进后我们继续往下走,寻找丢失的代码,走到下面代码的位置的时候我们可以看到有好几个jmp,并且从第一个jmp后面的代码就比较熟悉了push ebp…其实这就是我们要寻找的丢失的代码了,每两个jmp中间除去问号剩下的就是我们应该要寻找的丢失的代码了。直到两个jmp中间只剩下问号为止,仔细看下下面的代码,总共是5段,我们再分别把5段代码连同二进制代码复制下来
00C45C66 5D pop ebp 00C45C67 EB 01 jmp short 00C45C6A ;//jmp 00C45C69 C7 ??? 00C45C6A 55 push ebp ; //第一段 00C45C6B 8BEC mov ebp,esp ; //第一段 00C45C6D 6A FF push -1 ; //第一段 00C45C6F 68 78E35300 push 53E378 ; //第一段 00C45C74 68 407B4F00 push 4F7B40 ; //第一段 00C45C79 64:A1 00000000 mov eax,dword ptr fs:[0] ; //第一段 00C45C7F EB 01 jmp short 00C45C82 ;//jmp 00C45C81 C7 ??? 00C45C82 50 push eax ; //第二段 00C45C83 64:8925 0000000>mov dword ptr fs:[0],esp ; //第二段 00C45C8A 83EC 58 sub esp,58 ; //第二段 00C45C8D EB 01 jmp short 00C45C90 ;//jmp 00C45C8F C7 ??? 00C45C90 53 push ebx ; //第三段 00C45C91 EB 01 jmp short 00C45C94 ;//jmp 00C45C93 C7 ??? 00C45C94 56 push esi ; //第四段 00C45C95 EB 01 jmp short 00C45C98 ;//jmp 00C45C97 C7 ??? 00C45C98 57 push edi ; //第五段 00C45C99 8965 E8 mov dword ptr ss:[ebp-18],esp ; //第五段 00C45C9C 26:EB 01 jmp short 00C45CA0 ;//jmp 00C45C9F C7 ??? 00C45CA0 EB 02 jmp short 00C45CA4 ;//jmp 00C45CA2 CD20 68CF274F vxdjump 4F27CF68
- 第一段:
00C45C6A 55 push ebp ; //第一段 00C45C6B 8BEC mov ebp,esp ; //第一段 00C45C6D 6A FF push -1 ; //第一段 00C45C6F 68 78E35300 push 53E378 ; //第一段 00C45C74 68 407B4F00 push 4F7B40 ; //第一段 00C45C79 64:A1 00000000 mov eax,dword ptr fs:[0] ; //第一段
55 8B EC 6A FF 68 78 E3 53 00 68 40 7B 4F 00 64 A1 00 00 00 00
- 第二段
00C45C82 50 push eax ; //第二段 00C45C83 64:8925 0000000>mov dword ptr fs:[0],esp ; //第二段 00C45C8A 83EC 58 sub esp,58 ; //第二段
50 64 89 25 00 00 00 00 83 EC 58
- 第三段
00C45C90 53 push ebx ; //第三段
53
- 第四段
00C45C94 56 push esi ; //第四段
56
- 第五段
00C45C98 57 push edi ; //第五段 00C45C99 8965 E8 mov dword ptr ss:[ebp-18],esp ; //第五段
57 89 65 E8
9.OK,这样被偷取的代码我们就找回来了,然后你可以选择继续F8走到假的OEP或者是重新载入一下来到假的OEP位置。这个都无所谓的。我们先把程序运行到假的OEP位置,然后把五段被偷取的二进制代码整合一下,然后假的OEP往上拉,把空的代码行选中,二进制把被偷取代码粘贴进去
55 8B EC 6A FF 68 78 E3 53 00 68 40 7B 4F 00 64 A1 00 00 00 00 50 64 89 25 00 00 00 00 83 EC 58 53 56 57 89 65 E8
004F27A7 ^EB F8 jmp short SoWorker.004F27A1 004F27A9 0000 add byte ptr ds:[eax],al ; //从这里开始 004F27AB 0000 add byte ptr ds:[eax],al 004F27AD 0000 add byte ptr ds:[eax],al 004F27AF 0000 add byte ptr ds:[eax],al 004F27B1 0000 add byte ptr ds:[eax],al 004F27B3 0000 add byte ptr ds:[eax],al 004F27B5 0000 add byte ptr ds:[eax],al 004F27B7 0000 add byte ptr ds:[eax],al 004F27B9 0000 add byte ptr ds:[eax],al 004F27BB 0000 add byte ptr ds:[eax],al 004F27BD 0000 add byte ptr ds:[eax],al 004F27BF 0000 add byte ptr ds:[eax],al 004F27C1 0000 add byte ptr ds:[eax],al 004F27C3 0000 add byte ptr ds:[eax],al 004F27C5 0000 add byte ptr ds:[eax],al 004F27C7 0000 add byte ptr ds:[eax],al 004F27C9 0000 add byte ptr ds:[eax],al 004F27CB 0000 add byte ptr ds:[eax],al 004F27CD 0000 add byte ptr ds:[eax],al ; //到这里结束 004F27CF FF15 9CC25200 call dword ptr ds:[52C29C] ; //假的OEP 004F27D5 33D2 xor edx,edx 004F27D7 8AD4 mov dl,ah 004F27D9 8915 34306900 mov dword ptr ds:[693034],edx 004F27DF 8BC8 mov ecx,eax 004F27E1 81E1 FF000000 and ecx,0FF 10.粘贴好的OEP应该是这样子的,我们在粘贴好的代码的第一行,也就是那个push ebp的位置右键–新建EIP 004F27A7 ^EB F8 jmp short SoWorker.004F27A1 004F27A9 55 push ebp ; //此处新建OEP 004F27AA 8BEC mov ebp,esp 004F27AC 6A FF push -1 004F27AE 68 78E35300 push SoWorker.0053E378 004F27B3 68 407B4F00 push SoWorker.004F7B40 004F27B8 64:A1 00000000 mov eax,dword ptr fs:[0] 004F27BE 50 push eax 004F27BF 64:8925 0000000>mov dword ptr fs:[0],esp 004F27C6 83EC 58 sub esp,58 004F27C9 53 push ebx 004F27CA 56 push esi 004F27CB 57 push edi 004F27CC 8965 E8 mov dword ptr ss:[ebp-18],esp 004F27CF FF15 9CC25200 call dword ptr ds:[52C29C] ; //假的OEP 004F27D5 33D2 xor edx,edx 004F27D7 8AD4 mov dl,ah
11.至此我们就可以进行脱壳了,记得脱壳后修复的时候使用插件修复。
12.运行查壳
运行OK,查壳:Microsoft Visual C++ v6.0