壳的装载过程
1.获取壳自己所需要使用的API地址
2.解压或解密原程序的各个区块
3.进行必要的重定位
4.跳转到程序原入口点(OEP)
壳的分类
压缩壳:
ASPacK
UPX
PECompact
加密壳:
ASProtect
Armadillo
EXECryptor
Themida
VMProtect
加密壳的设计重点是抵抗各种调试器及逆向,压缩壳则是想方设法减少可执行文件的尺寸,为了达到保护程序的目的,加密壳通常会在可执行文件中添加大量的干扰和加密代码使得可执行文件的大小骤然上涨。
根据堆栈平衡原理寻找OEP
利用壳程序在运行前后需要保存和恢复原程序的堆栈环境来实现的。我们可以把壳程序当作一个子程序,调用这个子程序前,肯定需要保存原程序的堆栈环境,子程序调用完毕之后,就需要pop处原堆栈的值从而实现堆栈平衡。通常来说,壳程序使用pushhad/pophad或者pushfd/popfd指令来实现。脱壳时可以实根据堆栈平衡原理对ESP下断(由于esp存储的是栈顶指针),找到OEP。
使用OD进行调试时重点关注ESP的变化,在ESP第一次发生变化的地方停止。然后跟踪数据段。在数据段中下一个硬件断点,重新载入程序。F9运行至断点处停下,这时候会看到一个_“jmp eax“指令 _这个指令将要跳转的地方就是程序正常的OEP。F8步过执行指令,跳转至程序OEP。到此OEP已经成功找到了,我们利用OD的插件将这个dump导出。然后用OD载入dump后的程序,查看程序入口地址。
重构PE结构。(LordPE工具)
用LordPE加载我们dump出来的程序。在这里我们要检查这里的代码基址,数据基址等等数据是否合理,并且对照OD中的PE格式(Alt+M)做出合理修改。多余区段清除(不是本程序),最后一步重建修改后的PE程序。