逆向基础:软件手动脱壳技术入门( 二 )


2.4一步到达OEP
所谓的一步到达OEP的脱壳方法,是根据所脱壳的特征,寻找其距离OEP最近的一处汇编指令,然后下int3断点,在程序走到OEP的时候dump程序 。如一些压缩壳往往popad指令距离OEP或者Magic Jump特别近,因此使用的搜索功能,可以搜索壳的特征汇编代码,达到一步断点到达OEP的效果 。
2.5最后一次异常法
最后一次异常法的原理是,程序在自解压或自解密过程中,可能会触发无数次的异常 。如果能定位到最后一次程序异常的位置,可能就会很接近自动脱壳完成位置 。现在最后一次异常法脱壳可以利用的异常计数器插件,先记录异常数目,然后重新载入,自动停在最后一次异常处 。
2.6 模拟跟踪法
模拟跟踪法的原理就是使用下条件断点,SFX相当于是一个自解压段,在自解压段结束时(eip的值转到代码段时),已经距离OEP很近,但是这种跟踪方法会比较耗时 。
2.7 “SFX”法
“SFX”法利用了自带的OEP寻找功能,可以选择直接让程序停在OD找到的OEP处,此时自解压已经完成,可以直接dump程序 。
3一些脱壳实践
下面给出整理的使用以上方法,自己尝试手动脱这几种常用壳的脱壳笔记 。
3.1UPX脱壳笔记
首先进行侦壳:
首先把程序扔到里面可以看到:
然后这里尝试使用ESP定理:即在ESP第一次改变时,对ESP的地址设置硬件字访问断点,这样可以在代码被UPX算法还原之后,跳转到程序的正常入口处 。
然后F5运行,并没有直接到跳转到程序入口处的大跳位置,但是可以看到UPX的大跳就在眼前:
所以被还原后的程序入口点就是(通过单步往下走,F4略过往回走的循环语句,也可以看到这个大跳的位置 。)接下来走到大跳位置,跳到正常程序入口处:
然后去掉硬件断点,并使用的dump功能dump目标程序:
先修正映像大小,然后再选择完整脱壳,这样可以得到第一步dump的程序,然后再使用修复dump程序的OEP,OEP的信息通过OD自带的dump功能查询或者直接填45151:
将正确的入口地址填入中,然后自动搜索IAT信息:
然后点击获取输入表得到修正IAT之后的程序函数输入表,然后再点击显示无效函数,愉快地发现没有无效函数,那么就可以直接修复转存文件了 。
选择刚刚第一步dump下来的转储文件进行修复,修复完成之后脱壳完成:
这里对于压缩壳UPX,直接使用了ESP定律,可以很方便找到OEP并dump程序 。
4.2 脱壳笔记
这里脱的是一个的壳:
1、先使用最简单的最后一次异常法:首先把程序扔到里面设置OD调试选项中的异常选项,
仅保留内存非法访问异常,然后使用异常计数器插件,在使用前要清空断点设置:
等到程序正常运行后,重新加载程序,再选择第二步,停在最后一次异常之前:
然后用Alt+M转到内存窗口,对主程序code段下内存断点,SHIFT+F9执行:
这样程序就中断在了正确的OEP处,可以选择从模块中删除分析以显示正常分析的汇编代码 。然后使用 dump程序,并修正程序映像大小 。但是在使用 v1.6F Fix版,输入正确的OEP,获取函数输入表信息时,会发现无效的指针 。使用方法一修复后,再使用方法三可以完全修复
再点击Fix dump,可以修复之前dump下来的程序,脱壳完成:
2、使用二次内存断点法:首先载入程序,将所有的异常类型忽略,然后在idata段设置内存断点, 然后SHIFT+F9:
停下来后再次在code段设置内存断点,再次SHIFT+F9执行,可以直接达到正确的OEP中:
然后 dump,然后修复IAT 。修复方法同方法1 。
3、寻找magic jump以及修复函数表完成后dump程序:前两步还是加内存断点(idata、code),然后定位到程序的正确OEP处