bob123 发表于 2009-9-12 21:43

【学习总结】脱穿山甲

看了天草的教程,穿山甲全保护自己终于可以轻松搞定了。把记录整理以下。呵呵,给需要的人吧。论坛上有个穿山甲的帖子,不知道会不会重复了



用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的程序查找不到字符串,但未修复之前的那个可以查找到字符串,可以结合起来使用。

*****************第六步、处理程序中的自校验(可能有)****************************************

这就是程序自己编写的自校验了,与壳已经无关了。至此,穿山甲全保护,脱壳完成!

bob123 发表于 2009-9-14 17:51

2# ant007
其实穿山甲的脱壳机早就有了,而且很好用。。

cjteam 发表于 2009-9-14 18:54

:lol建议楼主测试测试6.24版本的,哈哈,难度就感觉到了

小马甲 发表于 2009-9-14 20:37

穿山甲是软柿子,人人都能捏

wqaq1992 发表于 2009-9-21 17:28

穿山甲 确实有事让人头痛

wenbo998 发表于 2013-7-1 22:33

非常好的教程,我刚开始知道和接触的壳就是穿山甲这个壳。当时看到那个憨态可掬的穿山甲的时候其实对它挺有好感的。虽然知道这个壳有些硬,但是还是想学习破解一下,感谢楼主的分享!
页: [1]
查看完整版本: 【学习总结】脱穿山甲