本周学习手动脱壳
壳通常分为两种,压缩壳和加密壳
逆向中常见的UPX属于压缩壳,还要北斗压缩壳(nsPack)等等
壳的一般运行规则就是通过特定的算法将程序整体加密,在程序实际运行的时候拿到控制权,在内存区将程序还原执行,在这一步可以附加其他功能,例如程序使用次数、注册机等(大致是这样,详细请查具体资料)。
壳通常会把程序真正的入口点(OEP)隐藏,而我们要做的就是将OEP找出来。
但有时不止需要找出OEP,还要修复修改后的程序才能正常运行。
(PS:还有其他专业术语例如modified、IAT、call指令(push+jmp)、mov指令(拷贝)、cmp指令(比较)、test指令这些汇编指令ret函数(返回值)等)dump,
脱壳的一般会用OD,但OD只能脱32位,所以也可以用X64dbg(32和64都可以)
脱壳方法常见的有以下四种
1.单步跟踪法
运用F7(步进,会进入函数内部)和F8(步过,不会进入函数内部)跟踪程序运行过程,硬啃,据说能提升对程序了解程度
2.esp定律法
利用堆栈平衡来快速找到OEP(注意关键词pushad和popad,lea rax,qword ptr ss:[rsp-80]等),通常只需要很少步骤就能找到入口。
以下为比较深入的方法,仅提出标记一下(适合比较复杂的壳)
3.最后一次异常法
4.内存镜像法
目前主要运用esp定律法
使用X64dbg时有一个小细节,内存区窗口内的关键数据在32位版本会显示ESP和EIP,而在64位版本会显示RSP和RIP。
下面讲一个学着的例题
攻防世界,crackme
32位,nsp,是北斗压缩壳(nsPack),修改前
32位,进X32DBG
点击工具栏笔记和内存布局中间的断点
然后ctrl+*设置为EIP
发现关键词pushad,f8单步运行到目标点
发现ESP和EIP同时红了,该下断点了,对ESP进行在内存窗口转到
下硬件,访问,2字节断点,然后运行,发现停到jmp指令,到401336
且发现上面就是popad关键词,下面进行dump
打开自带的插件,修改OEP为401336,点击dump,新保存,接下来进行IAT(导入函数地址)修复,点击IAT autosearch
然后再点击get imports输出,再点击fix dump修复,点击之前保存的文件,修复完成
第二和三反了,第二为最终效果,拖入ida
壳已脱完,可正常逆向。