Upx脱壳
#Upx脱壳
脚本脱壳:
放入Exeinfo PE中检测,发现是UPX壳,而且提示可以用upx.exe -d进行脱壳处理
upx.exe -d 程序.exe
手动脱壳
法一:根据跨段指令寻找OEP
绝大多数加壳程序会在被加密的程序中加上一个或多个段,在最后跳转至OEP时一般都是通过一个跨段跳转指令,所以一句跨段的转移指令(远JMP等)就可找到真正的入口点,在改跳转指令前一般会有POPAD/POPFD指令出现(用于回复入口现场)可以用作定位参考
首先是pushad,将全部的通用寄存器入栈,那么我们往下面翻,找到远跳转指令
主要是找远跳转指令的机器码(E9),普通的jmp是E8,找到E9后,对其下断点,运行到此处
按F8步入后就是OEP了
法二:根据堆栈平衡原理寻找OEP
该方法即为”ESP定律”法,对绝大部分压缩壳都很有效,原理便是基于栈平衡,壳段代码在保存现场后,我们队ESP指向的内存单元下硬件访问断点,那么在壳段代码恢复现场时定会访问到这个单元,此时我们EIP所处的位置处于壳段代码末端,距离跳转至OEP也就不远了
先单步执行pushad指令,然后对此时的ESP下断点(就是此时的栈顶,右下角)对此处下硬件断点访问
R运行后,可以发现从popad断下来了
法三:根据内存断点寻找OEP
内存断点的作用:在程序对一端内存进行访问时断下该程序,一般借用对内存保护属性进行修改,触发一场来实现中断。
壳必须要解压和解密原来的代码,这个过程可以看做对原程序指令所处的代码段的写入,壳最后还需要转交执行权给原程序,会触发对原程序指令所处的代码段的执行,这两个点都可以被用来监控壳段代码的行为以及寻找OEP
在x32dbg/x64dbg中的内存布局中对UPX0右键内存断点->执行->一次性
R运行,就会直接断到EOP位置(时间有点慢)
最后使用Scylla进行Dump!
可是还没有结束!!!!
导入ida发现IAT需要修复!
IAT修复:Dump出来的程序一般是无法直接运行的,因为缺少了必要的信息,PE加载器不能正确地填充IAT,导致所有的动态链接库API调用都不能正确寻址,如下:
解决方法:重建INT(用工具修复法)
我们这里所说的INT(Import Address Table)并非我们所说的导入表(Import Table),但是在一个PE文件中,这两个表的内容是完全一致的
在OEP位置搜索ITA,在Scylla中按IAT Autosearch,结果如下
按get import获取导入信息
把划×的给删除就行了
然后点击fix dump,选择我们之前dump出来的程序
最后提示导入信息重建成功
然后运行我们的修复后的dump_SCY,发现还是跑不了
用dbg打开发现OEP正常了,如图1,但是F9运行下去说异常于0x0063175D如图2
图1 OEP正常了
图2 异常于0x0063175D,而且说EB3004是无效的地址
用CFF Exploer VIII把unpack_test_dump_SCY中的可选头中的DLL can move这个选项给去掉
点击保存后,再打开,这个时候就去壳成功了!
补充:看看去壳成功后和刚才异常的区别
把刚刚去DLL的程序再还原一下(即再勾选一次)
在异常的代码(机器码那个位置)那里复制它的二进制
用dbg再次打开,ctrl + b搜索特征码
dbg搜索的时候在打开文件的时候先要F9运行到真正的程序开始,否则搜不到
此时发现都是地址都有值了,都是EB开头,也没有问号了