注意:附件(6楼)包涵例程...
以下是预览版本,附件含插图.
由4nil翻译,感谢linhanshi提供原文件....
由于学术问题,翻译不是周到...请指正.... Copyright 2004 Unpacking Gods Armadillo v3.xx 手工脱壳
适用于 Windows XP
用OD+DEBUG BLOCKER 手脱标准 Armadillo
然后给它打补丁,这样我们就可以用 ImpReC为它重建输入表 目标........: FlashFavorite v1.31
Download Target Version HERE
地址......: http://www.pipisoft.com/ or HERE
壳的种类..: ARMADiLLO v3.60 + Debug Blocker
难度....: 中高级 (需要了解一些调试技巧..)
需要的工具:
1.) Olly Debug v1.08 或更高版本
2.) LordPE Deluxe
3.) Import Reconstructor v1.6 Final
开始..
加载 Flash Favorite's Armadillo Protected exe 到 Olly Debug这个是 Armadillo's 入口...
入口看起来和 ASPACK.. 差不多,还有一些armadillo 看起来象C++编写.. 但事实是这是Armadillo..
这个 Armadillo检测是否被调试
所以我们下个 IsDebuggerPresent的断点 (或者用插件跳过这个部分..) :P
设好断点,按 SHIFT+F9 3次. 我们就在 IsDebuggerPresent断下.
提示:
你可以使用
任何
olly调试插件
来修改他 :P好,修改完垃圾的调试检测...
我们开始脱除Armadillo Debug Blocker feature
我们要获得子进程入口, 然后无限循环 (hex; EB FE)
我们找到这个无限循环,然后就可以在子进程入口断下:)
我们用API: WriteProcessMemory来达到这个目的
设断点 WriteProcessMemory - 按SHIFT+F9...
你会在一个特权指令停下..
按Shift+F9 跳过.
我们就在 WriteProcessMemory断下.
第一次断, 没什么用..
我们要的是第二次的.
例子:First off..
ARMADILLO 和 Debug Blocker Feature 是父子进程的关系.:
父进程用于加载-子进程是一般的被armadillo 保护的文件.
我们每个人载入的时候在OllyDebug中的地址都是不一样的.
更新版本的 Armadillo (v3.70) 会检测 OllyDebug.exe - 所以你就会想修改OllyDebug的文件名称...
这个方法对于 所有Armadillo v3.xx的壳都有效,除了CopyMEM2 和armadillo的其他一些自定义特性.
2..
Armadillo有很多读写违例(ACCESS VIOLATION)..
所以你可能要把C0000005 (ACCESS VIOLATION)添加到忽略列表
第二次在 WriteProcessMemory断下:
看栈窗口 (右下的窗口)
查看 缓冲(BUFFER) > buffer is writing the 2 bytes
查看地址 (Address) > 地址是缓冲要写的区域.
右击缓冲(BUFFER) 选择 跟踪入堆(Follow in DUMP)
有2个字节被改写
在我这里是: 60 E8 记住他们.
(我们要把他们改写回子进程一旦我们绑定它.)
现在我们将nbsp;60 E8 改写为 EB FE (相当于指令JUMP EIP)
我们让缓冲(buffer) 写的指令是直接跳转入口点(译者注:子进程),我们就可以恰好停在子进程的入口了. :) 如上图所示.现在我们把子进程的入口放到一个循环里面..
我们就可以绑定子进程...
但是Armadillo不允许!我们必须修改他 ...
在olly 用 SHIFT+F9运行, 当它在运行的时候, 在WaitForDebugEvent下断
(我们会一直在 WaitForDebugEvent停下来,因为这是一个循环体)
当你在 WaitForDebugEvent停下的时候,按CTRL+F9 (跟踪直到 RETN)
它会创建一个新线程.. :P (OLLY底部窗口回有提示.)
现在你会来到从 WaitForDebugEvent回来的RETN 按 F7 to 跟入 RETN.
确保EAX = 0 当你从WaitForDebugEvent retn时
你会到这里 TEST EAX,EAX - 举例:我们这样写:
PUSH PID (PID=Process ID)
CALL DebugActiveProcessStop <多亏是 winxp!>
你就可以在OD得到 正确的 PID.单击. 文件(File) > 附加(Attach) >
你会看见2个 FlashFavorite.exe's在运行 -选择那个没有红色高亮显示的.这个是我们要的PID.
我的真实PID是 03D0
所以我写成 PUSH 03D0
举例: 将这些汇编后..
按 F8 直到 NOP 指令 -
另外打开一个 OLLY DEBUG (这个让它开着).
注意: 电脑运行会很慢.. :|
现在到了Olly Debug 新程序 of .
单击 文件(File)>附加(Attach)> 选择你要 PUSH (PID)的进程当你绑定了 Olly的新进程
你会来到这里: (或相似的地方)
77F7F571 C3 RETN
77F7F572 8BFF MOV EDI,EDI
77F7F574 CC INT3
77F7F575 C3 RETN
77F7F576 8BFF MOV EDI,EDI
77F7F578 8B4424 04 MOV EAX,DWORD PTR SS:[ESP+4]
77F7F57C CC INT3
77F7F57D C2 0400 RETN 4
77F7F580 64:A1 18000000 MOV EAX,DWORD PTR FS:[18]
现在按下 F9 运行,按 F12 暂停
我们来到那个我们先前设定的 无限循环!! :D AKA: 子进程入口
举例:你的OD是不是看起来和上面的图一样啊..
恭喜! 你已经成功解除Armadillo的Debug Blocker Feature.
我们现在已经进入Armadillo创建的子进程里面了.
给我们机会破解这个*****的程序:) - 现在它就和一般的armadillo 壳一样了.
停下休息一会继续我们的Armadillo脱壳教程 :)
*****************..
剩下的工作就是...
把 EB FE [JMP EIP] 改回 原来的数据.
还记得吗,我要你记住的那个,在我这里是 60 E8 ..
把他改回60 E8就象下图所示.现在我们把JMP EIP改好了..
在子进程里面有个调试器检测
所以我们下个断在 on IsDebuggerPresent (或者用OD插件)
shift +F9运行 直到 在IsDebuggerPresent断下再次锁定在子进程IsDebuggerPresent .
现在
我们设个 断点在 CreateThread <有些armadillo.. 你必须设在 SetProcessWorkingSetSize>
SHIFT+F9运行直到被断在CreateThread
好
当我们用 Shift+F9运行的时候, 有时(在这个程序可以) 我们会看到一个弹出窗口
那个是 Armadillo's 时间检验弹出窗口 :) 这个是个好现象 :)
我们展开我们要破解的程序 :) (非常接近了^_^)
在Armadillo的弹出窗口单击OK ..
我们在 CreateThread
断下,当你在 on CreateThread断下的时候, 按一次 CTRL+F9, 你停在 RETN 18, 按 F7 跟入 RETN...
我们又来到 Armadillo的代码段,就是 Right Near 那个 调用原始入口的CALL!就会到这里..:
5E POP ESI
C9 LEAVE
C3 RETN
跟入这个RETN --^^^
我们来到RETN到的地方:
设置 断点在CALL EDI
按 F9一次我们被断在CALL EDI
当我们断在 CALL EDI的时候.. 这个 就是调用 OEP的CALL !! :D
用F7跟进CALL EDI哈,我们搞到原入口了!!! = 00414BCC
现在我们可以 LordPE 把文件给 脱出来了!
让Olly Debug 开着..
打开LordPE, 选中FlashFavorite.EXE(就是刚才绑定的真实的那个进程ID) .
好,现在右击它,选择 DUMP (FULL)..
保存DUMP出来的文件到目标文件夹.. :)
不错,虽然仅仅得到了armadillo + debug blocker的原入口 ;);)
但是接下来的任务比较艰巨了..
你的OD还开着把..
现在打开 Imprec ...
同样在Imprec里.. 选择FlashFavorite.EXE的真实进程ID
在ImpREC输入 OEP = 00414BCC - imagebase = 00014BCC .. 单击 IAT Auto SEARCH
举例:
当我们单击 IAT Auto Search后..
RVA 填入.. 这个例子里面 RVA是:
00017000 +imagebase= 00417000
总是保存 RVA地址(Always Save the RVA Address down). 当你获得RVA 地址后,你可以关闭 Imprec..
好,我们搞定快了,现在重新开始.. 再次破解Debug Blocker ...
你要确保你已经从 olly用LordPE包程序DUMP下来了 .
用文本保存 OEP 和 RVA 地址... 重新启动所有OD...
(别担心, 我们会再一次破解debug blocker,为了解决armadillo的入口窃取技术.) 第一部分:
破解Armadillo的Debug Blocker,获得Original Entry Point,还有 Dump出程序. 第二部分:
破解Armadillo的入口(Import) 伪装技术,用 ImpREC重建所有入口有些 Armadillo 很好修改.. 我写的所有就是让你更好的理解Armadillo的入口(Import)伪装技术.. 有时候很简单.. 有时候很复杂..
(虽然这个 Armadillo 有 Debug Blocker)..(更加费力)
对于很多 Armadillo 我们这里要讨论一下同样的修改技巧.. (有些可能有小小不同..) 所以这个对你以后的脱壳有帮助.在这里我们需要再次破解Debug Blocker Again
重复上面所以步骤..
当你再次绑定真实进程ID后..
把 EB FE,改为 60 E8... 在堆(Dump) 窗口... (左下的窗口) 右击,选择反汇编(Dissassemble)
来查看反汇编模式...
在堆窗口按 CTRL+G: 输入先前从Imprec得到的RVA ... 你不会没保存吧!?
RVA地址是 00417000.. 所以在堆窗口按CTRL+G , 输入00417000 确定.
我们就来到地址 417000...
右击RVA地址(417000) 选择断点(BreakPoint) > 硬件(Hardware) > 写内存(on Write) > DWORD------------->--------->如上图,我们对RVA (这个例子里是417000..)下硬件断点(HARDWARE BREAKPOINT)>写内存(on Write)>双字(Dword)..
记住: 我们仍需要修改IsDebuggerPresent...
所以我们下个断点在IsDebuggerPresent.. Shift+F9 直到断下.. 然后修改IsDebuggerPresent.
按SHIFT+F9 直到我们又看到那个弹出窗口..
弹出窗口 按 OK...
好!
我们被断了: Hardware BreakPoint 1 at 00xxxxxx <地址不一样没关系
举例:按 CTRL+F9 回到最近的 RETN... 按 F7 跟入...
到了这里:现在:
当你到了这个地方,记住它是什么样子的.. (大多数情况下有VirtualProtect Calls在 ADD ESP,0C下面...) 这样很容易辨认!
(很多时候都是这样修改... 但是有时候不一样.)我们到了如上图所示的地方..
按 CTRL+F9 你可能会被警告读写错误(access violation) ,怎么样不会呢.. 按 F7 假如你被警告读写错误(access violation)..
假如你被硬件断点断下
再按 CTRL+F9 ... 不管怎么样,你最终会停在这里: ..我们到这里.. (在本例子里..) 你一会可能还会停在这里 (下图..)
调用VirtualProtect的Call别弄糊涂了... 你用多了就小菜一碟了.
执行上图的JNZ ...
来到这里
我们要打补丁的数据..这个Armadillo的技术在于他加密这部分数据然后再解密..
简单的是.. Armadillo为我们解密了..我们在解密代码内部打一个jump补丁.
进入上图指出的CALL? :)
我们可以这样辨认这个CALL,它旁边有3条指令:
FFB5 BCE9FFFF PUSH DWORD PTR SS:[EBP-1644] <--
E8 A0B1FEFF CALL 00D45A1E
8985 94E7FFFF MOV DWORD PTR SS:[EBP-186C],EAX <--
83BD 94E7FFFF CMP DWORD PTR SS:[EBP-186C],0 <--
这个解密 Call我们要打补丁, 这样我们就可以重建输入表
选中那个Call , 回车> 回车跟入CALL地址
(你发现这个call还没有执行!!)
到这里
但首先...好,当你到这里...
这些跳来跳去就是用来解密的..
所以我们往下翻 直到看到几个NOP (4,5个NOP)
如下图
..保存这个NOP的地址.. (我们会需要调用它: 解密NOP :))
这个就是我们给armadillo打补丁的地方,这样我们就可以用Imprec重建输入表 :)
但是我们的目标程序有 debug blocker.. 所以要在子进程下硬件断点,硬件 bpx不会被保存..
so 我们要保存这个NOP的地址 把地址保存到文本文档.
现在我们又要重启OD了...
又要破解Debug Blocker ..
再次绑定子进程..略..
现在当我们绑定那个进程后, 记住:
我们 仍旧需要修改IsDebuggerPresent...
所以我们在OD主窗口..
设断点在 on IsDebuggerPresent... (它现在还不会被断下... 假如你被断了, 改..)
按SHIFT+F9 2次 > 按 CTRL+G,输入解密NOP的地址:
在这个解密NOP上下一个断点
SHIFT+F9运行,你在IsDebuggerPresent断下..: 修改 IsDebuggerPresent....
修改完 IsDebuggerPresent后..
按Press Shift+F9再次运行.. 来到弹出窗口, 单击OK :) 在解密NOP断下 :D<---------我们在NOP断下:)
现在.. 我们可以辨认这个jump了,找TEST DL,0..
有2个Jump在TEST DL,80下面 :)
所以我们NOP掉这个JE :)
打了这个补丁,armadillo就一个输入也没碰到了:)
留下6个THUNK要剪切
现在取消NOP的硬件断点..
你可以单击 > 调试(Debug) > OD内的硬件断点(Hardware Breakpoints in olly debug)..
现在,以 SHIFT+F9运行 ONE TIME
(注意):
(大多数情况下: 你打完补丁后,程序就不能执行.. 你会到一个特级指令,或者.. 你可以用imprec修改..)
但是这个例子里面.. 当我们打补丁后这个程序可以运行 !!!
我们已经给 Arma-Fucking-DILLO脱壳!先不要关闭OD.. 让它开着
打开ImpREC..
1.) 输入OEP (00414BCC)-ImageBase= 00014BCC
2.)选择 IAT AutoSearch:
3.) 选择 Get Imports (呵呵,所有输入都在那边)
4.) 选择 Show Invalid (显示错误,选择所有)
5.) Right click on the Invalid THUNK's and Click CUT THUNKS!
错误是armadillo留下的.. 仅仅在IAT周围... (我们只要剪掉剩下的thunk)
好,所有 THUNKS都可以用了!!
选择ImpREC底部的FIX DUMP
接着选择我们先前 DUMP的文件!!!!
现在关掉OD.. 现在运行DUMP后并且修改输入表后的文件..
OK!!可以运行了!
假如你的也可以运行了,恭喜你!! 假如没有,继续努力 :)
Armadillo不是很难,仔细看看就可以 :)我希望你从这篇教程学到了一些关于Armadillo v3的知识!
注意:
这些脱debug blocker,修复输入表的方法对其他armadillo也有效..
还有另外一种偷取输入表的方式, 和这个差不多,别混淆了.
尽情享受吧..
Sincerly..
MEPHiST0
Unpacking Gods 感谢所有帮助过我的人..
特别感谢 l0sts0ul, 他给予我莫大帮助. :)谢阅have fUn with armadillo! 这个教程会具体清楚的给你讲述如何用debug blocker的特性手工脱armadillo v3的壳。
smoke a bowl, and enjoy.
:LEGAL:
This Tutorial is to NOT BE READ by ANYONE
Unpacking Gods是一个专门以学习为目的而研究壳的组织
本文章技术版权归作者所有.
所有图标,文件,和名称所有权归作者所有,并只用于教学目的.
本教程只用于研究学习之用.
3 goats, and every ford mustang were harmed in the making of this tutorial.
.. ...Unpacking Gods没有责任对任何人因使用本教程而造成的后果负责.
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)