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.0040100B0040100A C3 retn0040100B C3 retn0040100C 74 23 je short SoWorker.004010310040100E C039 74 sar byte ptr ds:[ecx],7400401011 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 eax00C339F6 833D B07EC300 0>cmp dword ptr ds:[C37EB0],000C339FD 74 14 je short 00C33A1300C339FF 6A 0C push 0C00C33A01 B9 B07EC300 mov ecx,0C37EB000C33A06 8D45 F8 lea eax,dword ptr ss:[ebp-8]00C33A09 BA 04000000 mov edx,400C33A0E E8 2DD1FFFF call 00C30B4000C33A13 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],000C33A1F 74 02 je short 00C33A2300C33A21 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 ; //最近的tetn00C33A2A 5F pop edi00C33A2B 5E pop esi00C33A2C 5B pop ebx
4.程序运行到最近的retn后,我们就可以开始寻找丢失的代码了。不过这里可以先给大家看下假的OEP,打开内存窗口,在401000处下段然后shift+F9运行一次就来到假的OEP,落点处就是假的OEP,代码往上拉可以看到很多空的位置,这里就是待会找回丢失的代码后需要补充的位置了。
004F27A7 ^\EB F8 jmp short SoWorker.004F27A1004F27A9 0000 add byte ptr ds:[eax],al004F27AB 0000 add byte ptr ds:[eax],al004F27AD 0000 add byte ptr ds:[eax],al004F27AF 0000 add byte ptr ds:[eax],al004F27B1 0000 add byte ptr ds:[eax],al004F27B3 0000 add byte ptr ds:[eax],al004F27B5 0000 add byte ptr ds:[eax],al004F27B7 0000 add byte ptr ds:[eax],al004F27B9 0000 add byte ptr ds:[eax],al004F27BB 0000 add byte ptr ds:[eax],al004F27BD 0000 add byte ptr ds:[eax],al004F27BF 0000 add byte ptr ds:[eax],al004F27C1 0000 add byte ptr ds:[eax],al004F27C3 0000 add byte ptr ds:[eax],al004F27C5 0000 add byte ptr ds:[eax],al004F27C7 0000 add byte ptr ds:[eax],al004F27C9 0000 add byte ptr ds:[eax],al004F27CB 0000 add byte ptr ds:[eax],al004F27CD 0000 add byte ptr ds:[eax],al004F27CF FF15 9CC25200 call dword ptr ds:[52C29C] ; //假的OEP004F27D5 33D2 xor edx,edx004F27D7 8AD4 mov dl,ah004F27D9 8915 34306900 mov dword ptr ds:[693034],edx004F27DF 8BC8 mov ecx,eax004F27E1 81E1 FF000000 and ecx,0FF004F27E7 890D 30306900 mov dword ptr ds:[693030],ecx004F27ED C1E1 08 shl ecx,8004F27F0 03CA add ecx,edx004F27F2 890D 2C306900 mov dword ptr ds:[69302C],ecx004F27F8 C1E8 10 shr eax,10004F27FB A3 28306900 mov dword ptr ds:[693028],eax004F2800 6A 01 push 1004F2802 E8 933B0000 call SoWorker.004F639A
5.然后重新载入程序,运行完步骤1-3的操作,也就是让程序运行到最近的一个retn处。然后看堆栈窗口第四行(也就是程序名下面第二行)的值”0012ffa4”
0012FF5C 00C45A1C //第一行0012FF60 00400000 SoWorker.004000000012FF64 E3DE72280012FF68 0012FFA40012FF6C 00C20000
6.命令行下硬件访问断点”hr 0012ffa4”然后shift+F9运行一次,落脚后先F8单步跟一会。
00C45C07 /26:EB 01 jmp short 00C45C0B ; //落脚点00C45C0A |C7 ??? 00C45C0B \EB 02 jmp short 00C45C0F00C45C0D CD20 83EC372E vxdjump 2E37EC8300C45C13 EB 01 jmp short 00C45C1600C45C15 - E9 8D642479 jmp 79E8C0A700C45C1A 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 0188B89500C45C48 9A E969F29A 5DF>call far F35D:9AF269E900C45C4F EB 02 jmp short 00C45C5300C45C51 CD20 1BE9EB02 vxdjump 2EBE91B00C45C57 CD20 33E8EB02 vxdjump 2EBE83300C45C5D CD20 EB010F8D vxdcall 8D0F01EB
8.F7跟进后我们继续往下走,寻找丢失的代码,走到下面代码的位置的时候我们可以看到有好几个jmp,并且从第一个jmp后面的代码就比较熟悉了push ebp…其实这就是我们要寻找的丢失的代码了,每两个jmp中间除去问号剩下的就是我们应该要寻找的丢失的代码了。直到两个jmp中间只剩下问号为止,仔细看下下面的代码,总共是5段,我们再分别把5段代码连同二进制代码复制下来
00C45C66 5D pop ebp00C45C67 EB 01 jmp short 00C45C6A ;//jmp00C45C69 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 ;//jmp00C45C81 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 ;//jmp00C45C8F C7 ??? 00C45C90 53 push ebx ; //第三段00C45C91 EB 01 jmp short 00C45C94 ;//jmp00C45C93 C7 ??? 00C45C94 56 push esi ; //第四段00C45C95 EB 01 jmp short 00C45C98 ;//jmp00C45C97 C7 ??? 00C45C98 57 push edi ; //第五段00C45C99 8965 E8 mov dword ptr ss:[ebp-18],esp ; //第五段00C45C9C 26:EB 01 jmp short 00C45CA0 ;//jmp00C45C9F C7 ??? 00C45CA0 EB 02 jmp short 00C45CA4 ;//jmp00C45CA2 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.004F27A1004F27A9 0000 add byte ptr ds:[eax],al ; //从这里开始004F27AB 0000 add byte ptr ds:[eax],al004F27AD 0000 add byte ptr ds:[eax],al004F27AF 0000 add byte ptr ds:[eax],al004F27B1 0000 add byte ptr ds:[eax],al004F27B3 0000 add byte ptr ds:[eax],al004F27B5 0000 add byte ptr ds:[eax],al004F27B7 0000 add byte ptr ds:[eax],al004F27B9 0000 add byte ptr ds:[eax],al004F27BB 0000 add byte ptr ds:[eax],al004F27BD 0000 add byte ptr ds:[eax],al004F27BF 0000 add byte ptr ds:[eax],al004F27C1 0000 add byte ptr ds:[eax],al004F27C3 0000 add byte ptr ds:[eax],al004F27C5 0000 add byte ptr ds:[eax],al004F27C7 0000 add byte ptr ds:[eax],al004F27C9 0000 add byte ptr ds:[eax],al004F27CB 0000 add byte ptr ds:[eax],al004F27CD 0000 add byte ptr ds:[eax],al ; //到这里结束004F27CF FF15 9CC25200 call dword ptr ds:[52C29C] ; //假的OEP004F27D5 33D2 xor edx,edx004F27D7 8AD4 mov dl,ah004F27D9 8915 34306900 mov dword ptr ds:[693034],edx004F27DF 8BC8 mov ecx,eax004F27E1 81E1 FF000000 and ecx,0FF10.粘贴好的OEP应该是这样子的,我们在粘贴好的代码的第一行,也就是那个push ebp的位置右键–新建EIP004F27A7 ^\EB F8 jmp short SoWorker.004F27A1004F27A9 55 push ebp ; //此处新建OEP004F27AA 8BEC mov ebp,esp004F27AC 6A FF push -1004F27AE 68 78E35300 push SoWorker.0053E378004F27B3 68 407B4F00 push SoWorker.004F7B40004F27B8 64:A1 00000000 mov eax,dword ptr fs:[0]004F27BE 50 push eax004F27BF 64:8925 0000000>mov dword ptr fs:[0],esp004F27C6 83EC 58 sub esp,58004F27C9 53 push ebx004F27CA 56 push esi004F27CB 57 push edi004F27CC 8965 E8 mov dword ptr ss:[ebp-18],esp004F27CF FF15 9CC25200 call dword ptr ds:[52C29C] ; //假的OEP004F27D5 33D2 xor edx,edx004F27D7 8AD4 mov dl,ah
11.至此我们就可以进行脱壳了,记得脱壳后修复的时候使用插件修复。
12.运行查壳
运行OK,查壳:Microsoft Visual C++ v6.0