upx手动脱壳
虽然UPX本身提供脱壳器,但是修改后可能导致官方版本的UPX脱壳失败,因此需要学习upx手动脱壳。
使用OD在win10系统上脱壳会遇到部分API更改导致OllyDump基址无法正确填入的问题,x64DBG解决了这一问题。
一般情况下,已有栈的内容不会更改,upx会把这样的信息压栈,x86汇编指令pushad可以一次性压栈,载入后发现程序最开始为pushad指令。
如果在pushad执行后在栈顶下硬件读取断点,那么当程序执行完后续代码,使用popad恢复寄存器时就会中断。
于是,先单步执行pushad,再设置硬件读取断点。
按F9运行程序,程序中断在popad之后,看到后面是一个栈空间减少0x80的循环,后面接着一个较远的跳转,壳程序一般与原程序在不同区段,因此相隔较远,可以猜测较远的跳转指向原代码。
删除硬件断点,然后使用F4运行到较远的跳转,再单步运行一次。
可以看到程序执行到了很像原程序的代码。
打开Scylla插件如下。
使用IATAutosearch自动填入导入地址,再使用GetImports去掉imports中有红叉的部分。
点击Dump将内存转为可执行文件,然后点击Fix Dump修复导入表。
将脱壳后的文件使用IDA打开,可以发现程序已经被还原。
ps:这种方法生成的程序只能在IDA中分析,无法正常运行,因为程序的重定位信息仍未被修复,可以通过修改Nt Header的方式阻止系统对这个程序进行重定位进而正常运行。