[转载]Armadillo4.40.CUSTOM.最大保护下脱壳教程
<P>文章作者:badyfox</P><P><FONT face=宋体>译者说:<BR>1.声明:我翻译的所有文章仅限于翻译,没有其它目的.<BR>2.来源:[url]http://www.exetools.com/forum/showthread.php?t=8919[/url]<BR>3.作者:DappA<BR><BR>【翻译】Armadillo4.40.CUSTOM.最大保护下脱壳教程<BR><BR><IMG alt="" src="http://bbs.pediy.com/upload/2006/8/image/protection.gif_386.gif" border=0><BR><BR>基本信息:<BR>壳:Armadillo4.40CopyMem-II,IATElimination,StrategicCodeSplicing<BR>MemoryPatchprotection,CustomBuild<BR>目标:dUP2.10patcher<BR>工具:OllyDbg1.10,HideOD,PUPE,一些需要的ollyscripts<BR>难度:6/10<BR><BR>扫描目标:<BR><BR>最新PEID可以扫描出最新的Armadillo,扫描后得到:<BR><BR><IMG alt="" src="http://bbs.pediy.com/upload/2006/8/image/peidscan.gif_659.gif" border=0><BR><BR>设置"异常"<BR><BR>打开程序前,我们需要进一步设置"异常"<BR><BR><IMG alt="" src="http://bbs.pediy.com/upload/2006/8/image/exceptions.gif_741.gif" border=0><BR><BR>一.解决CopyMemII和DebugBlocker<BR><BR>进入正题.<BR>这部分有些枯燥,如果想跳过,可以使用"DetachFarther_MethodTenketsu_hipu<BR>_benina.txt".<BR>我将会解释怎样手动解决.我们进入:<BR><BR><IMG alt="" src="http://bbs.pediy.com/upload/2006/8/image/start.gif_942.gif" border=0><BR><BR>现在"bpWaitForDebugEvent"<BR><BR><IMG alt="" src="http://bbs.pediy.com/upload/2006/8/image/waitfordebug.gif_996.gif" border=0><BR><BR>由于内存补丁保护是开启的,Armadillo将会检测我们的断点是否下在API的头5个字节上.<BR>因此我们需要把断点移向API5个字节后或使用内存断点.我使用后者.<BR><BR><IMG alt="" src="http://bbs.pediy.com/upload/2006/8/image/membreakwait.gif_172.gif" border=0><BR><BR>我不会每次都用图,而会用文字说明代替.<BR>断点下好后,运行一下.经过一些非API的地方后,我们来到:<BR><BR><IMG alt="" src="http://bbs.pediy.com/upload/2006/8/image/pdebug.gif_278.gif" border=0><BR><BR>保存以下信息:<BR>0012DC6400431D86/CALLtoWaitForDebugEventfromtest.00431D80<BR>0012DC680012ED54|pDebugEvent=0012ED54<BR>0012DC6C000003E8\Timeout=1000.ms<BR><BR>CTRL+F2重起程序,在WriteProcessMemory上下新的断点.SHIFT+F9运行直到看到<BR>1000字节转换为止.<BR><BR><IMG alt="" src="http://bbs.pediy.com/upload/2006/8/image/100bytes.gif_508.gif" border=0><BR><BR>注意BytesToWrite==1000.这里是我们首个CopyMemcrypttransfer.也保存一下<BR><BR>0012DB0400435D57/CALLtoWriteProcessMemoryfromtest.00435D51<BR>0012DB0800000048|hProcess=00000048(window)<BR>0012DB0C00401000|Address=401000<BR>0012DB10003A3988|Buffer=003A3988<BR>0012DB1400001000|BytesToWrite=1000(4096.)<BR>0012DB180012DC20\pBytesWritten=0012DC20<BR><BR>在同一个窗口中,下滚知道发现主程序返回.你还会发现有个小循环:<BR><BR><IMG alt="" src="http://bbs.pediy.com/upload/2006/8/image/scroll1000.gif_715.gif" border=0><BR><BR>我把它粘贴到这里:0012DC2C|004349C5RETURNtotest.004349C5fromtest.00434D0D<BR>这部分很重要,它将会带领我们到达用来控制CopyMem函数的cryptocall中.<BR><BR><IMG alt="" src="http://bbs.pediy.com/upload/2006/8/image/gotogrpto.gif_844.gif" border=0><BR><BR>CTRL+G前往表达.你会来到PUSHEBP指令.选中它,CTRL+R得到所有关于此指令的<BR>参考.<BR><BR><IMG alt="" src="http://bbs.pediy.com/upload/2006/8/image/referencecall.gif_947.gif" border=0><BR><BR>双击第二个CALL,你会来到此CALL.NOP掉它.<BR><BR><IMG alt="" src="http://bbs.pediy.com/upload/2006/8/image/noppedcall.gif_012.gif" border=0><BR><BR>很好.现在你将去找子进程的OEP.CTRL+F9,F8退出WriteProcessMemory,DUMP窗口中CTRL+G,键入pDebugEvent地址:0012ED54<BR><BR><IMG alt="" src="http://bbs.pediy.com/upload/2006/8/image/childoepdump.gif_155.gif" border=0><BR><BR>第一行,子进程OEP为00401FAA.我们稍后会需要这三个地址.<BR><BR>0012ED6C00401FAAtest.00401FAA(OEP)<BR>0012ED7000000002<BR>0012ED7400000000<BR>0012ED7800401FAAtest.00401FAA<BR>0012ED7C00401FAAtest.00401FAA<BR><BR>修改子进程为无限循环<BR><BR>现在我们将修改OEP处的子进程为无限循环.打开PUPE,打开程序(记得使用正确<BR>的进程),键入OEP.<BR><BR><IMG alt="" src="http://bbs.pediy.com/upload/2006/8/image/pupepatch.gif_437.gif" border=0><BR><BR>记下原字节:8D9B<BR>修改它.<BR><BR>关闭PUPE.回到Olly,在WaitForDebugEvent上设置内存断点.中断后,前往正确的<BR>dump节并"反汇编跟随":0012DC6400431D86/CALLtoWaitForDebugEventfromtest.00431D80<BR>在CPU窗口中NOP掉WaitForDebugEvent,在"TESTEAX,EAX"选上择"新的起源":<BR><BR><IMG alt="" src="http://bbs.pediy.com/upload/2006/8/image/nopwaitfor.gif_652.gif" border=0><BR><BR>现在你将会跳到.text节,你可以写下自己的代码:<BR><BR><IMG alt="" src="http://bbs.pediy.com/upload/2006/8/image/jmp401000.gif_730.gif" border=0><BR><BR>走至JMP,回车.这就是我们将会用一些代码处理CopyMemII和DebugBlocker的地方.<BR>添加以下内容:<BR><BR>0040103C81056CED120000100000ADDDWORDPTRDS:[12ED6C],1000<BR>00401046810578ED120000100000ADDDWORDPTRDS:[12ED78],1000<BR>0040105081057CED120000100000ADDDWORDPTRDS:[12ED7C],1000<BR>0040105A813D7CED120000104000CMPDWORDPTRDS:[12ED7C],00401000<BR>00401064^74D6JESHORT00401000<BR>00401066813D7CED120000304000CMPDWORDPTRDS:[12ED7C],00403000<BR>00401070-0F85150D0300JNZ00431D8D<BR>0040107668400B0000PUSH0B40(PID!)<BR>0040107BE81193457CCALLDebugActiveProcessStop<BR>0040108090NOP<BR><BR>我来解释一下.记得先前的3行吗?<BR><BR>0012ED6C00401FAAtest.00401FAA<BR>0012ED7000000002<BR>0012ED7400000000<BR>0012ED7800401FAAtest.00401FAA<BR>0012ED7C00401FAAtest.00401FAA<BR><BR>因此我们添加了1000字节到这三个地址,接着用最后的地址与.text节的401000<BR>进行比较.相等则重新执行直到完成.<BR>接下来比较.rdata节.非0则跳回"JMP401000"下的NOP.<BR><BR>首先修正指针:<BR><BR><IMG alt="" src="http://bbs.pediy.com/upload/2006/8/image/edit40000.gif_160.gif" border=0><BR><BR>在最后的NOP上设置断点,SHIFT+F9运行:<BR><BR><IMG alt="" src="http://bbs.pediy.com/upload/2006/8/image/nopbreak.gif_230.gif" border=0><BR><BR>现在添加子进程,运行,暂停(SHIFT+F9,F12).把无限循环改回原代码:8D9B<BR><BR><IMG alt="" src="http://bbs.pediy.com/upload/2006/8/image/childoep.gif_389.gif" border=0><BR><BR>祝贺你,你现在得到了"干净"的OEP.我们解决了CopyMemII和DebugBlocker.不要关闭.下面我们解决IAT重定向,IATElimination和CodeSplicing.<BR><BR>二.输入表重定向和Elimination+SplicedCode<BR>现在探讨重定向部分.<BR>Armadillo的IAT重定向有一张重定向表,它被用来抽取原代码,以自己的方式来处理.<BR>我们的目标就是阻止Armadillo重定向任何API.<BR><BR>首先,我们需要找一个当前进程的API.进入第一个CALL,查找API.任选一个.我选择了以下:<BR>00402AAE-FF25980BD800JMPDWORDPTRDS:[D80B98];GDI32.SetTextColor<BR><BR>DUMP窗口中跟随地址.修改"查看"为"长型地址".你可以看到许多API,上滚至IAT<BR>表头:<BR><BR><IMG alt="" src="http://bbs.pediy.com/upload/2006/8/image/iatstart.gif_045.gif" border=0><BR><BR>00000000表示开始.现在下滚至:<BR><BR><IMG alt="" src="http://bbs.pediy.com/upload/2006/8/image/iatend.gif_120.gif" border=0><BR><BR>现在我们打开新的Armadillo程序.我们不需要干净的代码,只要干净的IAT就可以了.我们将修正IAT重定向.<BR>运行,暂停,修改字节.就这样做.<BR><BR>SHIFT+F9运行,直到PrivilegedInstruction异常停止.<BR>bpVirtualProtect,运行,中断.CTRL+F9,退出API.你到达了Armadillo代码中.<BR>CTRL+F查找命令PUSH100.来到PUSHEBP.修改为RET.<BR><BR><IMG alt="" src="http://bbs.pediy.com/upload/2006/8/image/push100.gif_428.gif" border=0><BR><BR>搞定IAT重定向.运行直到OEP.很简单.<BR>bpCreateThread,SHIFT+F9,CTRL+F9,F8,下滚直到CALLECX,bp,F7进入.<BR><BR>到达OEP.但我们需要的是干净的IAT.得到先前API的16进制代码:<BR><BR><IMG alt="" src="http://bbs.pediy.com/upload/2006/8/image/apihex.gif_632.gif" border=0><BR><BR>ALT+M打开内存镜像,查找二进制.记得选中头地址,查找整个镜像.<BR><BR><IMG alt="" src="http://bbs.pediy.com/upload/2006/8/image/searchapi.gif_727.gif" border=0><BR><BR>这就是完成的过程.现在我们要做的就是复制整个新的IAT到已损坏的IAT中.<BR><BR><IMG alt="" src="http://bbs.pediy.com/upload/2006/8/image/newiat.gif_825.gif" border=0><BR><BR>回到OEP,你会看见GetCommandLineA,之前是没有的,因为壳把它重定向到自己的代码中了.<BR><BR>现在我们用ArmInline修正splicedcode和IATelimination.很简单.我们先找到splicedcode.进入修正的IAT进程的第二个CALL中.发现00402BF9-E912E4C001JMP02011010<BR>它前往高内存地址,因此它就是splicedcode.<BR><BR>ALT+M打开内存镜像,查找分配的部分:<BR><BR><IMG alt="" src="http://bbs.pediy.com/upload/2006/8/image/splicedsection.gif_115.gif" border=0><BR><BR>spliced部分往往在分配地址的底部.在每次重起程序时,分配地址是任意的,这是因为壳通过经时间API的任意函数分配地址.打开ArmInline,填入以下数据:<BR><BR><IMG alt="" src="http://bbs.pediy.com/upload/2006/8/image/armsplice.gif" border=0><BR><BR>目标代码开始于.text节,长度为.text节的长度.选择"removeSplices".解决!<BR>下面是IATElimination:<BR><BR><IMG alt="" src="http://bbs.pediy.com/upload/2006/8/image/armiat.gif" border=0><BR><BR>00D809CC-IATSTART<BR>00D80D20-IATEND<BR>IATSIZE:354<BR><BR>新的RVA基地址在.adata节中,分配给00455000.<BR>我们现在用LordPE来dump目标程序.完成后,打开ImportREC重建IAT.使用当前的<BR>OEP,IAT大小前面有,"cutthunk(s)",添加IAT到dumped.exe中.试试.正确运行!<BR><BR><IMG alt="" src="http://bbs.pediy.com/upload/2006/8/image/iatfinal.gif" border=0><BR><BR>致<BR>DappA<BR><BR>感谢:Hacnho的精彩教程和视频,向这些不错的工具,Tenketsu和Ricardo写的一些<BR>Ollystripts致敬.<BR><BR>鸣谢:ICU,TSRH,SND,ARTEAM和MP2K</FONT><BR></P>
页:
[1]