脱壳、PESpin壳
前言经过一段时间的汇编、逆向、脱壳技术的学习,今天来实现脱PESpin壳方法。
打开OD调试程序
首先我们要找到OEP,我们先尝试ESP定律发现断点并不会触发,程序直接运行了。说明硬件断点被清空,程序可能带有反调试。
所以需要换个方法,查找特征值找到OEP的地址
首先我们要知道是什么编译器的程序
点击OD中M,选择代码段
在代码段中大致浏览代码会发现使用FF15 CALL来调用IAT,这是VC编译器的特征,所以可以用VC的关键API来下断点来查找API,VC程序OEP第一个调用的API是GetVersion,所以我们重新运行程序Ctrl+g输入GetVersion,找到API添加断点。
然后运行程序,通过查看掉用附近的代码来找到OEP(我是第二次断下查看调用附近代码找到)
查看IAT数组发现被加密了,所以我们在IAT处下一个硬件写入断点来查看是谁来操作了IAT
重新运行程序发现只有刚才我们下的API断点触发,硬件写入断点并没有触发,证明我们下的硬件写入断点已经被程序擦除,所以我们需要找到更改硬件断点的地方,这就跟异常有关,需要设置一下OD(不同的版本OD可能有差异)
首先先把原程序的所有断点设置都清空一下,重新操作OD
首先OD的选项—》调试设置—》异常 改为设为图中设置,确定
然后插件—》StrongOD—》OPtions将图中对号取消,确定
设置好后我们就可以重新运行程序会触发多次违规Shift+F9忽略异常,共有九次 ,我们在这些异常中查找擦除硬件断点的地方
为了查找我们的硬件断点是哪里被改,所以我们在每个异常触发上下一个硬件断点,来判断是否在这个异常前断点被去除,经测试在第四处异常前断点被修改,我们需要在第三次异常时查看SEH。
双击查看代码
进来后发现一下代码,硬件断点有四个,而下面代码正好将四个看似CONTEST的结构置零,为了方便观察我们在此处dump,拿到IDA中观察则更为明显
Dump后IDA运行添加CONTEXT结构体
F5查看看似清空硬件断点的c代码,右键变量添加刚才的CONTEXT结构体
显而易见这就是清空断点的地方
回到OD,既然找到罪魁祸首我们就需要操作了在更改处前一条代码下硬件执行断点
然后把更改处NOP至Return(return不nop)
将开始的设置异常全都设置回来,方便操作
首先OD的选项—》调试设置—》异常 改回设置,确定
然后插件—》StrongOD—》OPtions改回设置,确定
重新运行程序,用esp定律或根据第一次找到OEP地址找到OEP(中间会断到nop处,将刚才代码NOP掉)来从新给调用IAT的地址下硬件访问断点再次重新运行
断到SEH处再次nop,运行,会断到这里,因为代码有混淆所以我们Ctrl+上键来查看
这不是IAT写入的特征,再次运行
这也不像,但是我们Ctrl+上几次查看(3次)
这就是典型的IAT写入的特征,记住它的地址,方便我们写脚本,这里是加密IAT地方,我已我们要在这附近查找获取原始API的地方
经过跟踪我们找到了获取原始API的地方(寻找过程中有循环跟踪运行有耐心找到,该壳比对的是函数的hash值来获取)在下图处获取
既然知道了原始API函数名获取地址,写入IAT地址我们就可以写脚本了
我们需要用到OD脚本编译工具,编写脚本,用到的是汇编语言,如下写完保存到一个地方
用OD加载脚本,打开刚才保存的地方
去泡一杯茶,等它完成
完成后不要dump,查看IAT表
发现IAT表并不是完整的,它发生了偏移,中间会有00隔开,所以我们只能修复或重建IAT,但这是极其麻烦的一件事,还好我们有工具
进程id用任务管理器查看
代码起始结束查看与计算得到
新的IAT地址我们把它放在壳存在的区段,因为脱壳后该区段不会对程序造成影响,所以放在这里
修复之后发现IAT已经修复,然后我们开始收尾dump工作
使用工具ImportREC工具修复IAT
转存到刚才dump的文件,点击运行生成的文件
运行成功,脱壳成功
总结
1找到OEP
硬件断点失效,使用关键API来找到OEP
2找到擦出硬件断点的异常函数
配置异常环境,尽可能接受所有异常,用过设置硬件断点在异常函数前,来判断此异常是否清除代码。(此程序为第三个异常STI特权指令异常清除)
3解密IAT
在OEP处的GetVeision处设置硬件写入断点来找到填充IAT的地方,再通过跟踪找到获取API地址的地方编写脚本(脚本需要编写nop掉擦出硬件断点的代码)
4修复代码段,重建IAT
使用通用导入表工具修复5dup,修复IAT
5dump、修复IAT
以上