【学习总结】脱穿山甲
看了天草的教程,穿山甲全保护自己终于可以轻松搞定了。把记录整理以下。呵呵,给需要的人吧。论坛上有个穿山甲的帖子,不知道会不会重复了用PEid查得是Armadillo(穿山甲),然后用Armadillo find protected 查得具体保护选项
Debug-Blocker 阻止调试器
CopyMem-II 双进程
Enable Import Table Elimination 输入表乱序
Enable Strategic Code Splicing 代码拼接
Enable Nanomites Processing CC保护,Armadillo最让人头痛的保护措施。
Enable Memory-Patching Protections 内存校验
以上是穿山甲的四大保护
****************第一步、到达OEP(脚本来完成)***********************************************
1.OD忽略所有异常
2.记住入口点头字节558b
3.用脚本:Armadillo Detach from Client + Unpack (Ricardo 1000 Bytes Method) v0.1
4.点击软件弹出的试用按钮
5.在脚本弹出的框里,记下OEP头字节558b(显示是8b55)
6.在脚本弹出的框里,记住子进程pid(000007F8)和OEP(0056AF60)
7.附加000007F8,ALT+F9返回,此时应该就是返回到OEP(0056AF60)了
8.还原OEP头字节558b(选中一块-->二进制--->编辑--> 558b)
****************第二步、找、处理IAT*******************************************************
10.打开ArmaDetach(可以绕过Debug-Blocker),把要脱壳的软件OnlineTV拖到里面,显示如下:
DONE!
Child process ID: 00000560
Entry point: 005FC5E3
Original bytes: 558B
11.开一个空OD附加00000560,ALT+F9返回,还原入口点头字节558b,下面绕过IAT加密:
方法一:
Ctrl+G 查找:GetModuleHandleA,在下面的第一个ge处下硬件执行断点,然后找返回时机,如果有注册对话框的那种,就是点试用后断下来的第一次,取消硬件断点,Alt+F9返回,修改je为jmp,然后,在jmp跳去的那个jmp处F2,然后F9,然后取消以前的修改,取消断点,此时IAT处理完毕。在00401000段下断,直接F9,到达OEP。
(此种方法的返回时机有个明显的标志:VirtualAlloc和VirtualFree。
倒数第二次:
001294FC /0012EC44
00129500 |00CC7A7A 返回到 00CC7A7A 来自 kernel32.GetModuleHandleA
00129504 |00CDCCFC ASCII "kernel32.dll"
00129508 |00CDE014 ASCII "VirtualAlloc"
倒数第一次
001294FC /0012EC44
00129500 |00CC7A97 返回到 00CC7A97 来自 kernel32.GetModuleHandleA
00129504 |00CDCCFC ASCII "kernel32.dll"
00129508 |00CDE008 ASCII "VirtualFree"
0012950C |00CE0CC8
00129510 |7C9210E0 ntdll.RtlLeaveCriticalSection
这一次就返回了
001294D8 00CE0CC8
001294DC 0BE165E4
001294E0 00000000
001294E4 00000000
001294E8 00CE0CC8
001294EC 001294D8
001294F0 0012EC44
001294F4 0012EC34 指向下一个 SEH 记录的指针
001294F8 00CD6100 SE处理程序
)
方法二:
Ctrl+G 查找:VirtualProtect,F2下好断点,开始shift+F9,找缓冲非常大的那次(第一次不算),找到后,取消断点,alt+F9返回,ctrl+G查找push 100,向上看,有个push ebp ,改成retn,这样就处理完了iat,然后Ctrl+G 查找:CreateThread,F2下好断点,shift+f9一次,取消断点,Alt+F9返回,一路上F8,找到call ecx,F7就到了OEP。
(这种方法,大的缓冲很明显,适用于找不到上一种方法明显标志的时候)
12.这时程序的OEP已经扭曲变形,但无关紧要,我们要利用他的IAT。
回到第一步中的那个OD里,去查找IAT,CtrL+B,查找FF25(整个块),Ctrl+L找下一个,直到找到API,右键-->数据窗口中跟随-->内存地址。在数据窗口,右键--->长型--->地址。找到IAT的最上面。附近选上两个连续的并在同一个库函数内的API,二进制复制。74 9B 80 7C E1 9A 80 7C
然后在回到第二步的这个OD里,Alt+M,CtrL+B 整个块中查找74 9B 80 7C E1 9A 80 7C,找到后,右键--->长型--->地址。找到IAT的最上面。二进制复制整个IAT,然后二进制粘贴到第一步的OD里,注意对准地址。
此时IAT处理完毕。就可以关掉第二步打开的OD和ArmaDetach了。
****************第三步、Code Splicing(代码拼接)处理****************************************
13.打开 ArmInline (用来处理穿山甲的四大加密保护,支持 Armadillo v3.5-4.4),选中要脱壳的文件.
14.拼接代码起点:一般是程序段(程序运行所需要的DLL也是)末尾最下面的那个段,大小一般是20000,程序一般会自动检测到。
15.代码拼接长度填20000(程序默认的是10000),点 删除拼接代码。
16.可能会弹出个对话框让你手动修复(fix this manually) ,此时要记下那个地址 424116,等自动拼接完成后,CtrL+G来到这个地方,
00424114 33C0 xor eax,eax
00424116 E9 F2767402 jmp 02B6B80D //很明显,jmp转去的这部分代码并不是在的程序地址内
0042411B F7D3 not ebx
-------------------------------------------------------------------------------------------
在上面Enter,到02B6B80D
02B6B80D 50 push eax
02B6B80E 50 push eax
02B6B80F 50 push eax
02B6B810 50 push eax
02B6B811 50 push eax
02B6B812 50 push eax
02B6B813 50 push eax
02B6B814 50 push eax
02B6B815 87F9 xchg ecx,edi //代码混乱
02B6B817 66:87FB xchg bx,di //代码混乱
02B6B81A 56 push esi //代码混乱
02B6B81B 7B 02 jpo short 02B6B81F //代码混乱
02B6B81D 7B 09 jpo short 02B6B828 //代码混乱
02B6B81F 5E pop esi //代码混乱
02B6B820 66:87FB xchg bx,di //代码混乱
02B6B823 87F9 xchg ecx,edi //代码混乱
02B6B825 8B55 0C mov edx,dword ptr ss:
02B6B828 2E:8BC0 mov eax,eax //复制到这里结束,下面跳回程序了
02B6B82B E9 EB888BFD jmp UnPackMe.0042411B
02B6B830 87D3 xchg ebx,edx
02B6B832 66:87D1 xchg cx,dx
50 50 50 50 50 50 50 50 87 F9 66 87 FB 56 7B 02 7B 09 5E 66 87 FB 87 F9 8B 55 0C 2E 8B C0
------------------------------------------------------------------------------------------
并不是所有的代码都有用,只提取不是代码混乱的代码。
02B6B80D 50 push eax
02B6B80E 50 push eax
02B6B80F 50 push eax
02B6B810 50 push eax
02B6B811 50 push eax
02B6B812 50 push eax
02B6B813 50 push eax
02B6B814 50 push eax
02B6B825 8B55 0C mov edx,dword ptr ss:
02B6B828 2E:8BC0 mov eax,eax
50 50 50 50 50 50 50 50 8B 55 0C 2E 8B C0
------------------------------------------------------------------------------------------
CtrL+G来到刚才提示让你手动修复(fix this manually)的地址 424116,右键-->二进制编辑-->把刚才的代码50 50 50 50 50 50 50 50 8B 55 0C 2E 8B C0粘贴上,注意不要选上保持大小。
至此Code Splicing处理完毕。
*****************第四步、Import Table Elimination(输入表乱序) 挪动IAT**********************
17.利用ArmInline中的'输入表乱序'
目前的IAT基址:就是输入表头地址,注意看程序是否自动识别正确
目前的IAT长度:长度写1000,或者990
IAT新基址 :重建输入表乱序后存储的位置,有SFX段的话用SFX段最好,没有的话,idata或者text段也行。
18.点寻回IAT基址。此时在OD里,会发现api地址变化了,CtrL+B,查找FF25(或者FF15),注意内存地址,是不是程序内的地址。(只是核对,一般都没问题)
19.如果都没问题,此时就可以用lordpe来DUMP了,然后用importREC修复,此时OD本来就停在OEP的。剪掉无效指针(因为IAT已经准确处理好了)
*****************第五步、Nanomites Processing处理(CC保护)**********************************
16.在ArmInline中的Nanomites里,点定位,在弹出的软件试用框中点试用,等修复成功后,点转储修复到刚才的脱壳文件即可。
17.修复了CC的程序查找不到字符串,但未修复之前的那个可以查找到字符串,可以结合起来使用。
*****************第六步、处理程序中的自校验(可能有)****************************************
这就是程序自己编写的自校验了,与壳已经无关了。至此,穿山甲全保护,脱壳完成! 2# ant007
其实穿山甲的脱壳机早就有了,而且很好用。。 :lol建议楼主测试测试6.24版本的,哈哈,难度就感觉到了 穿山甲是软柿子,人人都能捏 穿山甲 确实有事让人头痛 非常好的教程,我刚开始知道和接触的壳就是穿山甲这个壳。当时看到那个憨态可掬的穿山甲的时候其实对它挺有好感的。虽然知道这个壳有些硬,但是还是想学习破解一下,感谢楼主的分享!
页:
[1]