学破解第125天,《UltraProtect 1.x》脱壳练习
前言:
从小学到大专(计算机网络技术专业),玩过去的,所以学习成绩惨不忍睹,什么证书也没考,直到找不到工作才后悔,不知道怎么办才好。
2017年12月16日,通过19元注册码注册论坛账号,开始做伸手党,潜水一年多,上来就是找软件。(拿论坛高大上的软件出去装X)
2018年8月某一天,报名了华中科技大学网络教育本科(计算机科学与技术专业)2018级秋季。(开始提升学历)
2019年6月17日,不愿再做小菜鸟一枚,开始零基础学习破解。(感谢小糊涂虫大哥在我刚开始学习脱壳时,录制视频解答我的问题)
2020年7月7日,感谢H大对我的鼓励,拥有了第一篇获得优秀的文章。(接下来希望学习逆向,逆天改命)
坛友们,年轻就是资本,和我一起逆天改命吧,我的学习过程全部记录及学习资源:https://www.52pojie.cn/thread-1208234-1-1.html
立帖为证!--------记录学习的点点滴滴
0x1查壳
1.练习程序下载地址:https://www.lanzoux.com/irzXwgbpi8d
2.PEID查壳,UltraProtect 1.x,UltraProtect 1.x旧版=现在的ACProtect。
3.脱壳前配置好调试器,stringOD插件里面取消skip some exception选项,OD调试器取消int3和内存断点勾选,忽略00-FF异常取消勾选。
4.脱壳与破解不一样,记得切换设置,哦,对了,还有数据窗口设置成长型-地址,方便看api。
0x2寻找OEP
1.观大佬们的脱壳方法,利用int和seh异常来脱壳,那我就照着葫芦画瓢吧。
2.OD载入程序,Shift+F9一次,停在了0041596B这,很明显这是一个int3异常
0041596A CC int3
0041596B 90 nop
0041596C 64:67:8F06 0000 pop dword ptr fs:[0] ; 0012FFE0
00415972 83C4 04 add esp,0x4
00415975 60 pushad
3.再来一次Shift+F9,程序停在了00415719,提示的是访问FFFFFFFF异常,在Shift+F9运行一次,程序跑飞。
00415717 33C0 xor eax,eax
00415719 CD 01 int 0x1
0041571B 40 inc eax
0041571C 40 inc eax
0041571D 0BC0 or eax,eax
4.那我们重来,Shift+F9两次,然后在code(401000)处F2下断点,Shift+F9到达OEP。(利用最后一次异常法)
004010D2 56 push esi
004010D3 FF15 E4634000 call dword ptr ds:[0x4063E4] ; UltraPro.0040D1BA
004010D9 8BF0 mov esi,eax
004010DB 8A00 mov al,byte ptr ds:[eax]
004010DD 3C 22 cmp al,0x22
5.不过我这还真没看出来它这是什么程序的OEP,接触的语言太少,看看别人补的代码:
004010CC 55 push ebp
004010CD 8BEC mov ebp,esp
004010CF 83EC 44 sub esp,0x44
004010D2 56 push esi
004010D3 FF15 E4634000 call dword ptr ds:[0x4063E4] ; UltraPro.0040D1BA
004010D9 8BF0 mov esi,eax
004010DB 8A00 mov al,byte ptr ds:[eax]
004010DD 3C 22 cmp al,0x22
6.看完后恍然大悟,函数调用时push ebp,mov ebp,esp保存现场,这是固定的,sub esp,0x44怎么来的呢?看看此时寄存器窗口:esp0012FF7C,ebp0012FFC0,开辟的栈空间可不就是ebp-esp = 0x44嘛。分配局部变量空间前ebp和esp应该是经过mov ebp,esp相等的,然后esp-44,此时寄存器中esp就比ebp小了44。
7.接下来就在前面6字节填上补充的代码,然后在push ebp这一行右键,新建EIP即可。
004010CC 55 push ebp
004010CD 8BEC mov ebp,esp
004010CF 83EC 44 sub esp,0x44
004010D2 56 push esi
004010D3 FF15 E4634000 call dword ptr ds:[0x4063E4] ; UltraPro.0040D1BA
004010D9 8BF0 mov esi,eax
004010DB 8A00 mov al,byte ptr ds:[eax]
0x3脱壳与修复
1.接下来直接在OD里面右键dump程序,查壳vc++6.0程序,成功运行程序。
2.看到一位坛友说IAT无法修复,我有点奇怪,不用修复啊,那我试试LordPE转存程序,然后IRI打开,发现有大量的未解密函数。
3.单步很快就看到了调用4063E4,而4063E4也是一个未解密IAT,以它为突破口。
004010D3 FF15 E4634000 call dword ptr ds:[0x4063E4] ; UltraPro.0040D1BA
4.跟进去之后看到如下的代码:
0040D1BA 68 55DE007C push 0x7C00DE55
0040D1BF 813424 E8F18100 xor dword ptr ss:[esp],0x81F1E8
0040D1C6 C3 retn
0040D1C7 68 B266027C push 0x7C0266B2
0040D1CC 813424 90998200 xor dword ptr ss:[esp],0x829990
0040D1D3 C3 retn
0040D1D4 68 AE120C7C push 0x7C0C12AE
0040D1D9 813424 50418F00 xor dword ptr ss:[esp],0x8F4150
0040D1E0 C3 retn
0040D1E1 68 D158097C push 0x7C0958D1
0040D1E6 813424 68A78900 xor dword ptr ss:[esp],0x89A768
0040D1ED C3 retn
5.秘密被我发现了,原来是先push 一个常数值,然后异或一个常数值得到真正的函数kernel32.GetCommandLineA,,继续单步走起,依次找到了
0012FF70 7C812FBD kernel32.GetCommandLineA
0012FF6C 7C801EF2 kernel32.GetStartupInfoA
6.按照上面的方法来找实在太慢了,看看有没有别的办法,找两个未解密的IAT地址,40635c和6340,下上硬件访问断点,按照找OEP的步骤来,然后断在了00418BC0这里,上面一句就是访问这个地址的地方,往上翻也就是说一会要关注eax的值,它的值决定了这里显示的地址。
00418BBE 8907 mov dword ptr ds:[edi],eax ; UltraPro.<ModuleEntryPoint>
00418BC0 8385 E6614000 0>add dword ptr ss:[ebp+0x4061E6],0x4
00418BC7 ^ E9 D3FEFFFF jmp UltraPro.00418A9F
00418BCC 83C6 14 add esi,0x14
00418BCF 8B95 EA614000 mov edx,dword ptr ss:[ebp+0x4061EA] ; UltraPro.00400000
接下来看到寄存器窗口,说明eax解密出来了应该是kernel32.DeleteFileA
EAX 7C831EDD kernel32.DeleteFileA
ECX 7C937DE9 ntdll.7C937DE9
EDX 7C99B178 ntdll.7C99B178
EBX 0040670A ASCII "DeleteFileA"
ESP 0012FF3C
EBP 0000C000
ESI 00406014 UltraPro.00406014
EDI 00406360 UltraPro.00406360
EIP 00418B07 UltraPro.00418B07
7.经过分析发现这三行就是获取函数的真实地址,函数调用完之后进行加密。
00418AFB FFB5 E2614000 push dword ptr ss:[ebp+0x4061E2] ; kernel32.7C800000
00418B01 FF95 449C4100 call dword ptr ss:[ebp+0x419C44] ; kernel32.GetProcAddress
00418B07 3B9D EA614000 cmp ebx,dword ptr ss:[ebp+0x4061EA] ; UltraPro.00400000
此时寄存器窗口,看到了吧,又解密出了kernel32._lclose函数
EAX 7C834E94 kernel32._lclose
ECX 7C937DE9 ntdll.7C937DE9
EDX 7C99B178 ntdll.7C99B178
EBX 004066F6 ASCII "_lclose"
ESP 0012FF3C
EBP 0000C000
ESI 00406014 UltraPro.00406014
EDI 00406364 UltraPro.00406364
EIP 00418B07 UltraPro.00418B07
8.应该是在到达OEP前这些函数都加密了,到达OEP之后再去解密执行,然后就在00418B07这里下断点,每执行一次,解密一个函数:
工作量太大了,不会汇编,不知道怎么写脚本脱壳,简直是个体力活,不搞了,就这样吧,明白的IAT的解密方式就行了。
0x4总结
1.每一次都是在00418B07这一行,eax显示出了真实的函数地址。
2.有没有什么办法从635C-63F0这段地址,解密一个函数,将地址放到这里面,解密一个放到这里面,这应该要用脚本吧。
3.UltraProtect 1.x壳会在程序到达OEP前加密IAT,到达OEP后,通过push值,然后异或,调用真实的函数。
4.IRI修复好像识别不出来这里面的函数,等级3跟踪卡死,开一个程序在等级3跟踪,一个也修复不了,OD直接dump出来的反而不用修复直接就可以运行。
5.直接用ACprotect插件就可以修复,其实之前学过的,忘了:https://www.52pojie.cn/thread-997836-1-1.html,ximo大大的第17课,18课有两种找被偷取的代码和通杀方法。
0x5参考资料
1.guoqiang5277坛友的文章
2.blackeyes的文章
PS:善于总结,善于发现,找到分析问题的思路和解决问题的办法。虽然我现在还是零基础的小菜鸟一枚,也许学习逆向逆天改命我会失败,但也有着成功的可能,只要还有希望,就决不放弃!