好友
阅读权限10
听众
最后登录1970-1-1
|
本帖最后由 a1250377248 于 2014-2-10 22:41 编辑
【Armadillo脱壳知识和方法大全】
近日对Armadillo壳很感兴趣,缘于它的多种组合的变化,但仔细看来,其保护的解决方法又有相对固定。方法无外乎那么几种脱壳方法(当然排除有key和cc),本人在本论坛已对标准壳的脱壳方法发贴,但后来有所更新,干脆总结在一块吧,以方便大家。大家可以复制下来,放在手边,脱壳时按步骤来。我还是一小鸟,同大家一样在逐渐成长中,有不对的地方和不成熟的地方,望大家批评指正,共同进步。
一、基本知识:
该壳有如下保护:
(1)Debug-Blocker(阻止调试器)--解决方法就是忽略所有异常,隐藏好OD,如果加载时,老出错,就多换几个OD试试。
(2)CopyMem-II(双进程保护)---解决方法是:用手动或者脚本使双变单。
(3) Enable Import Table Elimination(IAT保护) –解决方法是用工具ArmaDetach再次载入加壳程序,记下子进程ID,用另一OD载入,利用断点GetModuleHandleA,找到MagicJump,修改Magic Jump,得到正确的IAT。
(4)Enable Strategic Code Splicing(远地址跳) ,解决方法就是用Arminline工具。
(5) Enable Nanomites Processing(简称CC),就是把一些retn代码变成CC(INT型),解决方法:用Arminline工具或Enjoy工具。
(6)Enable Memory-Patching Protections(内存保护)
二、脱此类壳常用的断点:
1、WaitForDebugEvent(用于寻找非标准OEP和做补丁用)
2、WriteProcessMemory(用于寻找非标准OEP)
3、DebugActiveProcess(找子程)
4、OpenMutexA(双进程转单进程)
5、GetSystemTime(补丁KEY)
6、VirtualProtect(用于5.x)
7、CreateFileMappingA(用于5.x)
8、GetModuleHandleA/LoadLibraryA (用于找Magic Jump)
9、CreateThread(寻找OEP)
三、种类及脱壳方法
说明:对于此壳一般要隐藏OD。如果按以下方法下断OD断不下来,出错,就多换几个OD试试,在我脱壳中,就有个情况,下断点后,老断不下来,多换了几个OD就成功了。
(一)单线程标准方式
具体方法:2次断点法加修改Magic Jump。
1、找Magic Jump
方法有二:
方法一、下断点Bp GetModuleHandleA/he GetModuleHandleA/bp GetModuleHandleA+5/he GetModuleHandleA+5,按shift+f9运行,当经过一个call缓冲有点大时,一般是在堆栈窗口出现ASCII "kernel32.dll"和ASCII "VirtualFree“后,再运行一次,出现"kernel32.dll",就是返回时机,取消断点,按alt+f9执行到返回。
方法二、也可以下bp LoadLibraryA断点,当在堆栈窗口出现MSVBVM60.Dll函数时,返回时机,在kernel32.LoadLibraryA下面有一个跳转,一般情况下,这个跳转比较大的话,就改为jmp,而跳转比较小的话,就改nop)。[注:下此断点的目的是找到Magic Jump,修改Magic Jump目的是避开的IAT的加密。]
2、找OEP
下断点bp GetCurrentThreadId/bp CreateThread,shift+f9运行,中断后,取消断点,Alt+F9返回,单步执行,看到一个call edi之类的。F7进入,即到oep。OD不要关!打开import--选择进程--OEP输入va--自动搜索IAT--获取输入表--显示无效函数--CUT!
(二) 双线程的标准壳
总体步骤:
1、要双变单;
2、处理IAT,
修改Magic Jump;
3、寻找OEP;
4、修复
1、双变单,方法有三。
方法一:PATCH代码法
下断bp OpenMutexA,断下后,ctrl+g到00401000,将空数据改为如下代码:
00401000 60 pushad
00401001 9C pushfd
00401002 68 A0FD1200 push xxxx (注:此处的 xxxx为断下后mutex name前的数值。)
00401007 33C0xoreax,eax
00401009 50 push eax
0040100A 50 push eax
0040100B E8 E694A677 call KERNEL32.CreateMutexA
00401010 9D popfd
00401011 61 popad
00401012 - E9 8F9FA777 jmp KERNEL32.OpenMutexA
点右键选择重建eip,f9运行,断下后,取消断点, ctrl+g到00401000,恢复修改。
方法二,下断点:bp OpenMutexA,SHIFT+F9,断下后, ALT+F9返回,返回后,将返回代码下面的第一个跳转改为相反跳转,再次SHIFT+F9,断下后,ALT+F9返回,再次将返回代码下面的第一个跳转改为相反跳转。然后再一次SHIFT+F9,取消断点,至此,同样,双进程转单进程完毕!
方法三、除了用双变单的脚本外,还可以用一个工具ARMADETACH,将带壳的程序拖入,记下子进程的ID。
2、处理IAT,修改Magic Jump。
用OD附加该子进程,加载后,ALT+F9返回,修改前两个字节为加壳程序载入时的前两个字节。
下断点bp GetModuleHandleA, Shift+F9运行,一般是在堆栈窗口出现ASCII "kernel32.dll"和ASCII "VirtualFree“后,再运行一次,出现
"kernel32.dll",就是返回时机,中断后alt+f9返回,在KERNEL32.LoadLibraryA下面找到Magic Jump!修改为jmp。再下断点bp GetCurrentThreadId/bp CreateThread(或往下拉找到两个salc,在其上面的jmp上下断,Shift+F9,断下!如果文件有校验,则要撤消Magic Jump处的修改!打开内存镜像,在00401000段下断。运行,中断后,删除断点,alt+f9返回),F8单步走,到第一个CALL ECX之类的东西时,F7进入。到oep。
注:(对于有些OD有一个字符串溢出漏洞,尽量用一些修正些错误的OD,有些程序需要处理Anti,方法如下:下断点he OutputDebugStringA
断下后,选中%s%之类的字符,在数据窗口跟随,点右键-二进制-使用00填充,中断2次!都如上修改,删除此断点!)
3、修复。
(三)CopyMem-ll +Debug-Blocke保护方式
1、先找OEP,两个断点。(1)断点bp WaitForDebugEvent,运行,中断后看堆栈,在一行有“pDebugEvent”字样的那一行右键点击“数据窗口跟随”,取消断点。(2)bp WriteProcessMemory,运行,中断后,在数据窗口(要地址显示)发现oep。
2、patch代码,解码。方法:重新载入,bp WaitForDebugEvent,运行,中断,取消断点,alt+f9返回,CTRL+F搜索命令:or eax,0FFFFFFF8,找到后,先往上看,可以看到两个CMP,一个是“cmp dword ptr ss:XXXX,0”在这里下硬件执行断点,Shift+F9运行,中断后取消断点。这时看信息窗口:SSXXXXX=00000000,如果这个值不为0的话,需要将其清0,如果为0就不用了。第二个CMP,cmp ecx,dword ptr ds:XXXX,下面开始解码。在这里要记下几个地址:(1)cmp dword ptr ss:XXXX,0前的地址和内的值。(2)第二个CMP中中的值。接着or eax,0FFFFFFF8处往下,可以找到一处为and eax,0FF的代码,从这里开始Patch,代码如下:
inc dword ptr ds: //第一个CMP内的值
mov dword ptr ds:XXXX+4,1 //XXXX为第二个CMP内的值
jmp XXXX //第一个CMP前的地址
修改好后,去掉所有断点,向下找到第一个CMP下面的跳转所跳到的地址,来到这个地址,下硬件执行断点,Shift+F9运行,此时代码解压完毕
,可以脱壳。
3、脱壳。运行LordPE,将子进程dump出来,这里的子进程就是LordPE第2个进程(有2个同名进程)。Dump后用LordPE修改入口点为在第一步中查到的OEP。
4、修复输入表、IAT的寻找
脱壳后不要急着去修复输入表,得先把RVA数据获取,用OD载入Dump出来的程序,右键搜索二进制字符串,输入FF25,找到一个函数,在数据窗口跟随,在数据窗口向上找到 |
|
发帖前要善用【论坛搜索】功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。 |
|
|
|
|