手脱PESpin:Antidump Protection和remove OEP(学习历程)
本帖最后由 开始的复活节 于 2017-5-4 00:38 编辑声明:
1.纪录自己成长历程,与大家分享
2.由于技术与能力,如有疏漏错误,欢迎指出,高手轻喷
简述:
PESpin作为一个经典的强壳有多种保护方式,从小生我怕怕的吾爱破解脱壳练习-----PESpin 1.32认识这个壳后我尝试了自己加密了程序对比分析,脱壳破解是需要耐心和细心的,我就因为脱壳修复的时候因为细节问题导致脱壳后程序跑不起来,因为几个stolen code的16进制码没有填写对,在这里感谢帮我发现问题的人yujian1991,这个加壳工具共有5个保护选项:1.API重定向(API Redirection) 2.反内存储保护(Antidump protection) 3.移除OEP(Remove OEP) 4.代码重定向(Code redirection) 5.调试阻碍(Debug Blocker),先从最简单的两个分析吧,保护项仅选Antidump和保护项仅选remove oep,其实都是老生常谈了,Antidump用ESP定理法再单步跟;remove oep有stolen code,查找到代码后填充移除断再修复就可以了。
先OD打开原程序,直接在OEP
004010C0 >/$55 push ebp
004010C1|.8BEC mov ebp,esp
004010C3|.6A FF push -0x1
004010C5|.68 28214200 push Hello_Wo.00422128
004010CA|.68 C02F4000 push Hello_Wo._except_handler3NK_DATAing>;SE 处理程序安装
004010CF|.64:A1 0000000>mov eax,dword ptr fs:
004010D5|.50 push eax
004010D6|.64:8925 00000>mov dword ptr fs:,esp
004010DD|.83C4 A4 add esp,-0x5C
004010E0|.53 push ebx
004010E1|.56 push esi
004010E2|.57 push edi
004010E3|.8965 E8 mov ,esp
004010E6|.FF15 A0A14200 call dword ptr ds:[<&KERNEL32.GetVersion>;kernel32.GetVersion
004010EC|.A3 6C7C4200 mov dword ptr ds:,e>
004010F1|.A1 6C7C4200 mov eax,dword ptr ds:[_osvermSetgerListe>
004010F6|.C1E8 08 shr eax,0x8
004010F9|.25 FF000000 and eax,0xFF
1.先看Antidump的吧,用OD载入加密程序
0042B0D4 > /EB 01 jmp short Hello_Wo.0042B0D7 ;程序入口
0042B0D6 |68 60E80000 push 0xE860
0042B0DB 0000 add byte ptr ds:,al
0042B0DD 8B1C24 mov ebx,dword ptr ss: ; kernel32.7C817067
0042B0D7 60 pushad ;跳转后来到此处
0042B0D8 E8 00000000 call Hello_Wo.0042B0DD ;//ESP定理法
取消断点
0042CCB5 89C1 mov ecx,eax
0042CCB7 81D1 CBECEBB8 adc ecx,0xB8EBECCB
0042CCBD EB 01 jmp short Hello_Wo.0042CCC0
0042CCBF D5 0F aad 0xF
0042CCC1 c1d1 8d rcl ecx,0x8d
0042CCC4 15 744B527C adc eax,0x7C524B74
0042CCC9 87D2 xchg edx,edx ; ntdll.KiFastSystemCallRet
单步跟到OEP
004010C0 55 push ebp
004010C1 8BEC mov ebp,esp
004010C3 6A FF push -0x1
004010C5 68 28214200 push Hello_Wo.00422128
004010CA 68 C02F4000 push Hello_Wo.00402FC0
004010CF 64:A1 00000000mov eax,dword ptr fs:
004010D5 50 push eax
004010D6 64:8925 0000000>mov dword ptr fs:,esp
004010DD 83C4 A4 add esp,-0x5C
004010E0 53 push ebx
004010E1 56 push esi
004010E2 57 push edi
004010E3 8965 E8 mov dword ptr ss:,esp
004010E6 FF15 63FE4200 call dword ptr ds: ; kernel32.GetVersion
004010EC A3 6C7C4200 mov dword ptr ds:,eax
004010F1 A1 6C7C4200 mov eax,dword ptr ds:
004010F6 C1E8 08 shr eax,0x8
004010F9 25 FF000000 and eax,0xFF
我们自动查找IAT显示在此OEP入口点没有找到任何有用的信息,选择高级命令,获得API调用,多余指针剪切,直接修复.
2.Remoce OEP
程序入口处
0042B0D4 > /EB 01 jmp short Hello_Wo.0042B0D7 ;//跳转实现
0042B0D6 |68 60E80000 push 0xE860
0042B0DB 0000 add byte ptr ds:,al
0042B0DD 8B1C24 mov ebx,dword ptr ss: ; kernel32.7C817067
0042B0E0 83C3 12 add ebx,0x12
0042B0E3 812B E8B10600 sub dword ptr ds:,0x6B1E8
0042B0E9 FE4B FD dec byte ptr ds:
0042B0D7 60 pushad
0042B0D8 E8 00000000 call Hello_Wo.0042B0DD ;//此处可以用ESP定理法
0042B0DD 8B1C24 mov ebx,dword ptr ss: ; kernel32.7C817067
SHIFT+F9,观察跳转后的代码可以知道这段代码有不少花指令
0042CCB5 F7D2 not edx ; ntdll.KiFastSystemCallRet
0042CCB7 39C2 cmp edx,eax
0042CCB9 F7C0 74E7F921 test eax,0x21F9E774
0042CCBF 0facc2 48 shrd edx,eax,0x48
0042CCC3 0FBDC8 bsr ecx,eax
0042CCC6 C7C2 2431C7CD mov edx,0xCDC73124
0042CCCC 85C0 test eax,eax
0042CCCE 0FBAEA 31 bts edx,0x31
0042CCD2 F7D2 not edx ; ntdll.KiFastSystemCallRet
0042CCD4 F7C1 25C4A65C test ecx,0x5CA6C425
0042CCDA 3BD0 cmp edx,eax
0042CCDC 0FABC2 bts edx,eax
0042CCDF EB 01 jmp short Hello_Wo.0042CCE2
0042CCE1 dd0f fisttp qword ptr ds:
0042CCE3 AF scas dword ptr es:
0042CCE4 c8 55eb 01 enter 0xeb55,0x1
0042CCE8 0D 8BECEB01 or eax,0x1EBEC8B
0042CCED- E9 6AFFEB01 jmp 022ECC5C
0042CCF2 1E push ds
0042CCF3 68 D56B3FC3 push 0xC33F6BD5
0042CCF8 810424 53B5023D add dword ptr ss:,0x3D02B553
0042CCFF 68 90368AD2 push 0xD28A3690
0042CD04 810424 30F9B52D add dword ptr ss:,0x2DB5F930
0042CD0B 64:A1 00000000mov eax,dword ptr fs:
0042CD11 EB 01 jmp short Hello_Wo.0042CD14
0042CD13 8f db 8f
0042CD14 50 push eax
0042CD15 EB 01 jmp short Hello_Wo.0042CD18
0042CD17 40 inc eax
0042CD18 64:8925 0000000>mov dword ptr fs:,esp
0042CD1F EB 01 jmp short Hello_Wo.0042CD22
0042CD21 9D popfd
0042CD22 83C4 A4 add esp,-0x5C
0042CD25 EB 01 jmp short Hello_Wo.0042CD28
0042CD27 26:53 push ebx
0042CD29 EB 01 jmp short Hello_Wo.0042CD2C
0042CD2B 41 inc ecx
0042CD2C 56 push esi
0042CD2D EB 01 jmp short Hello_Wo.0042CD30
0042CD2F A2 57EB0139 mov byte ptr ds:,al
0042CD34 8965 E8 mov dword ptr ss:,esp
0042CD37 EB 01 jmp short Hello_Wo.0042CD3A
0042CD39 CF iretd
0042CD3A FF15 63FE4200 call dword ptr ds: ; kernel32.GetVersion
0042CD40 EB 01 jmp short Hello_Wo.0042CD43
0042CD42^ 7F A3 jg short Hello_Wo.0042CCE7
0042CD44 6c ins byte ptr es:,dx
0042CD45 7C 42 jl short Hello_Wo.0042CD89
0042CD47 00EB add bl,ch
0042CD49 0146 A1 add dword ptr ds:,eax
0042CD4C 6c ins byte ptr es:,dx
0042CD4D 7C 42 jl short Hello_Wo.0042CD91
0042CD4F 00EB add bl,ch
0042CD51 0103 add dword ptr ds:,eax
0042CD53 C1E8 08 shr eax,0x8
0042CD56 EB 01 jmp short Hello_Wo.0042CD59
0042CD58 5D pop ebp ; kernel32.7C817067
0042CD59 25 FF000000 and eax,0xFF
0042CD5E EB 01 jmp short Hello_Wo.0042CD61
0042CD60 5C pop esp ; kernel32.7C817067
0042CD61 A3 787C4200 mov dword ptr ds:,eax
0042CD66 EB 01 jmp short Hello_Wo.0042CD69
0042CD68 F8 clc
0042CD69 8B0D 6C7C4200 mov ecx,dword ptr ds:
0042CD6F EB 01 jmp short Hello_Wo.0042CD72
0042CD71 DC81 E1FF0000 fadd qword ptr ds:
用吾爱OD自带的DeJunk可以帮助我们去除花指令,花指令类型选择TElock,除掉花指令后代码清晰多了,单步跟
0042CCB5 F7D2 not edx ; ntdll.KiFastSystemCallRet
0042CCB7 39C2 cmp edx,eax
0042CCB9 F7C0 74E7F921 test eax,0x21F9E774
0042CCBF 0facc2 48 shrd edx,eax,0x48
0042CCC3 0FBDC8 bsr ecx,eax
0042CCC6 C7C2 2431C7CD mov edx,0xCDC73124
0042CCCC 85C0 test eax,eax
0042CCCE 0FBAEA 31 bts edx,0x31
0042CCD2 F7D2 not edx ; ntdll.KiFastSystemCallRet
0042CCD4 F7C1 25C4A65C test ecx,0x5CA6C425
0042CCDA 3BD0 cmp edx,eax
0042CCDC 0FABC2 bts edx,eax
0042CCDF 90 nop
0042CCE0 90 nop
0042CCE1 90 nop
0042CCE2 0FAFC8 imul ecx,eax
0042CCE5 55 push ebp ;//第一处
0042CCE6 90 nop
0042CCE7 90 nop
0042CCE8 90 nop
0042CCE9 8BEC mov ebp,esp ;//第二处
0042CCEB 90 nop
0042CCEC 90 nop
0042CCED 90 nop
0042CCEE 6A FF push -0x1 ;//第三处
0042CCF0 90 nop
0042CCF1 90 nop
0042CCF2 90 nop
0042CCF3 68 D56B3FC3 push 0xC33F6BD5 ;//第四处
0042CCF8 810424 53B5023D add dword ptr ss:,0x3D02B553
0042CCFF 68 90368AD2 push 0xD28A3690 ;//第五处
0042CD04 810424 30F9B52D add dword ptr ss:,0x2DB5F930
0042CD0B 64:A1 00000000mov eax,dword ptr fs: ;//第七处
0042CD11 90 nop
0042CD12 90 nop
0042CD13 90 nop
0042CD14 50 push eax ;//第八处
0042CD15 90 nop
0042CD16 90 nop
0042CD17 90 nop
0042CD18 64:8925 0000000>mov dword ptr fs:,esp ;//第九处
0042CD1F 90 nop
0042CD20 90 nop
0042CD21 90 nop
0042CD22 83C4 A4 add esp,-0x5C ;//第十处
0042CD25 90 nop
0042CD26 90 nop
0042CD27 90 nop
0042CD28 53 push ebx ;//第十一处
0042CD29 90 nop
0042CD2A 90 nop
0042CD2B 90 nop
0042CD2C 56 push esi ;//第十二处
0042CD2D 90 nop
0042CD2E 90 nop
0042CD2F 90 nop
0042CD30 57 push edi ;//第十三处
0042CD31 90 nop
0042CD32 90 nop
0042CD33 90 nop
0042CD34 8965 E8 mov dword ptr ss:,esp;//第十四处
0042CD37 90 nop
0042CD38 90 nop
0042CD39 90 nop
0042CD3A FF15 63FE4200 call dword ptr ds: ; kernel32.GetVersion ;//第十五处
0042CD40 90 nop
0042CD41 90 nop
0042CD42 90 nop
0042CD43 A3 6C7C4200 mov dword ptr ds:,eax;//第十六处
0042CD48 90 nop
0042CD49 90 nop
0042CD4A 90 nop
0042CD4B A1 6C7C4200 mov eax,dword ptr ds:;//第十七处
0042CD50 90 nop
0042CD51 90 nop
0042CD52 90 nop
0042CD53 C1E8 08 shr eax,0x8 ; ;//第十八处
0042CD56 90 nop
0042CD57 90 nop
0042CD58 90 nop
0042CD59 25 FF000000 and eax,0xFF ;//第十九处
0042CD5E 90 nop
0042CD5F 90 nop
0042CD60 90 nop
0042CD61 A3 787C4200 mov dword ptr ds:,eax ;//第二十处
0042CD66 90 nop
0042CD67 90 nop
0042CD68 90 nop
0042CD69 8B0D 6C7C4200 mov ecx,dword ptr ds: ;//第二十一处
0042CD6F 90 nop
0042CD70 90 nop
0042CD71 90 nop
0042CD72 81E1 FF000000 and ecx,0xFF
0042CD78 90 nop
0042CD79 90 nop
0042CD7A 90 nop
0042CD7B- E9 8F43FDFF jmp Hello_Wo.0040110F //跳向伪OEP
整理后如下,但是我们对比后发现有两处和原程序的OEP不同,这需要我们通过OEP修改
0042CCF3 68 D56B3FC3 push 0xC33F6BD5 ;//第四处
0042CCF8 810424 53B5023D add dword ptr ss:,0x3D02B553 ;//0x38565B8A-0x38987CB2=422128(运行到下一句就能在堆栈窗口看到422128)
0042CCFF 68 90368AD2 push 0xD28A3690 ;//第五处
0042CD04 810424 30F9B52D add dword ptr ss:,0x2DB5F930 ;//0xED3AA144+0x13058E7C=100402FC0(最高位溢出)
0042CD0B 64:A1 00000000mov eax,dword ptr fs: ;//(运行到这句就能在堆栈窗口看到402FC0)
整理后的16进制码为:
55 8B EC 6A FF 68 28 21 42 00 68 C0 2F 40 00 64 A1 00 00 00 00 50 64 89 25 00 00 00 00 83 C4 A4
53 56 57 89 65 E8 FF 15 63 FE 42 00 A3 6C 7C 42 00 A1 6C 7C 42 00 C1 E8 08 25 FF 00 00 00 A3 78
7C 42 00 8B 0D 6C 7C 42 00 81 E1 FF 00 00 00
单步后进入大跳伪OEP,向上拉看到缺少的代码段
0040110F 890D 747C4200 mov dword ptr ds:,ecx
00401115 8B15 747C4200 mov edx,dword ptr ds:
0040111B C1E2 08 shl edx,0x8
0040111E 0315 787C4200 add edx,dword ptr ds:
00401124 8915 707C4200 mov dword ptr ds:,edx
0040112A A1 6C7C4200 mov eax,dword ptr ds:
004010C0 0000 add byte ptr ds:,al
004010C2 0000 add byte ptr ds:,al
004010C4 0000 add byte ptr ds:,al
004010C6 0000 add byte ptr ds:,al
004010C8 0000 add byte ptr ds:,al
004010CA 0000 add byte ptr ds:,al
004010CC 0000 add byte ptr ds:,al
004010CE 0000 add byte ptr ds:,al
004010D0 0000 add byte ptr ds:,al
004010D2 0000 add byte ptr ds:,al
004010D4 0000 add byte ptr ds:,al
004010D6 0000 add byte ptr ds:,al
004010D8 0000 add byte ptr ds:,al
004010DA 0000 add byte ptr ds:,al
004010DC 0000 add byte ptr ds:,al
004010DE 0000 add byte ptr ds:,al
004010E0 0000 add byte ptr ds:,al
004010E2 0000 add byte ptr ds:,al
004010E4 0000 add byte ptr ds:,al
004010E6 0000 add byte ptr ds:,al
004010E8 0000 add byte ptr ds:,al
004010EA 0000 add byte ptr ds:,al
004010EC 0000 add byte ptr ds:,al
004010EE 0000 add byte ptr ds:,al
004010F0 0000 add byte ptr ds:,al
004010F2 0000 add byte ptr ds:,al
004010F4 0000 add byte ptr ds:,al
004010F6 0000 add byte ptr ds:,al
004010F8 0000 add byte ptr ds:,al
004010FA 0000 add byte ptr ds:,al
004010FC 0000 add byte ptr ds:,al
004010FE 0000 add byte ptr ds:,al
00401100 0000 add byte ptr ds:,al
00401102 0000 add byte ptr ds:,al
00401104 0000 add byte ptr ds:,al
00401106 0000 add byte ptr ds:,al
00401108 0000 add byte ptr ds:,al
0040110A 0000 add byte ptr ds:,al
0040110C 0000 add byte ptr ds:,al
0040110E 0089 0D747C42 add byte ptr ds:,cl
在4010C0起始处把整理的十六进制代码粘贴,在4010C0处转为新的eip
004010C0 55 push ebp ;//设为新的EIP
004010C1 8BEC mov ebp,esp
004010C3 6A FF push -0x1
004010C5 68 28214200 push Hello_Wo.00422128
004010CA 68 C02F4000 push Hello_Wo.00402FC0
004010CF 64:A1 00000000mov eax,dword ptr fs:
004010D5 50 push eax
004010D6 64:8925 0000000>mov dword ptr fs:,esp
004010DD 83C4 A4 add esp,-0x5C
004010E0 53 push ebx
004010E1 56 push esi
004010E2 57 push edi
004010E3 8965 E8 mov dword ptr ss:,esp
004010E6 FF15 63FE4200 call dword ptr ds: ; kernel32.GetVersion
004010EC A3 6C7C4200 mov dword ptr ds:,eax
004010F1 A1 6C7C4200 mov eax,dword ptr ds:
004010F6 C1E8 08 shr eax,0x8
004010F9 25 FF000000 and eax,0xFF
004010FE A3 787C4200 mov dword ptr ds:,eax
00401103 8B0D 6C7C4200 mov ecx,dword ptr ds:
00401109 81E1 FF000000 and ecx,0xFF
0040110F 890D 747C4200 mov dword ptr ds:,ecx
00401115 8B15 747C4200 mov edx,dword ptr ds:
0040111B C1E2 08 shl edx,0x8
0040111E 0315 787C4200 add edx,dword ptr ds:
00401124 8915 707C4200 mov dword ptr ds:,edx
0040112A A1 6C7C4200 mov eax,dword ptr ds:
0040112F C1E8 10 shr eax,0x10
00401132 25 FFFF0000 and eax,0xFFFF
00401137 A3 6C7C4200 mov dword ptr ds:,eax
然后用LoadPE修正镜像大小,用importREC的高级命令获取API调用后剪切无效指针,修复就可以
感谢分享, 学习了 感谢分享 感谢分享学习经验。现在还不能完全看懂!努力中 太详细了慢慢看得了 感谢分享学习经验
页:
[1]