ESP手动和自动脱壳 教程
基本原理
ESP
是一个特殊的通用寄存器,用于表示栈顶的地址。也就是下图这个东西。
想要了解更多?查看我另一篇关于逆向所需要的汇编基础:http://poilzero.sipc115.club/index.php/archives/53/
堆栈平衡
ESP定律基于堆栈平衡的原理,对于解壳中为什么存在堆栈平衡呢?和堆栈平衡究竟是什么呢?
- 众所周知,.exe程序初始运行的时候会被系统分配一些数据,其中那么多寄存器的初始值就是被分配的,这些值对程序运行至关重要的。
- 而各种无论是加密壳还是压缩壳,本质上都是由几个部分组成,其中第一部分的壳程序,负责解析真正的程序。
- 但是第一部分的壳程序在运行过程中肯定会改变寄存器的值,怎么办呢?
- 学过一点汇编的很容易想到
pushad和popad
这两哥用于保存寄存器的值到栈和还原的指令。 - 于是我只要在开头和结尾分别使用这两个指令,就不会影响后续的程序运行了。
- 但是这的前提就是在
pushad
后,和popad
前,的堆栈顶的相同的,要不然popad
的值就错乱了。 - 而恰好
popad
后就是下一个部分程序运行了,一般就是真正的程序了。
ESP定律
基于堆栈平衡原理,我们只要找到pushad
后栈顶的位置,然后下硬件访问断点到这个位置,这样当程序运行到断点处,也代表着加密程序结束了,接下来的jmp
一般就是到真正的程序入口处了,也就是OEP
自动脱壳原理
就是用程序自动寻找OEP
,使用对应的脱壳软件进行脱壳,比如upx压缩壳就使用upx unpack之类的软件,或者指令实现。
案例CrackMe4
例题备份:
这里使用手动脱壳,自动的就不讲了
使用PEID查询发现是UPX壳
使用OD打开,第一行就是pushad
了,按F8单步运行
可以发现ESP寄存器发生突变(因为pushad把寄存器的值入栈了),因此我只要找到下一次访问这个地址的时候肯定就是要还原寄存器的时候了!也就是真正程序入口位置OEP前了。
因此输入指令对这个栈位置下硬件访断点hr 0012FFA4
然后按F9直接运行,运行到下的硬件断点处暂停了,发现这一处就是要jmp
,说明要跳转到真正程序位置了
按F8执行跳转指令,就到了程序的真正入口处了!(程序入口处一般是push 某个东西开始
)
以上就用ESP定律找到了OEP处了,接下来用程序保存一下即可。
在空白处右键选择如图的选项-解壳,然后保存为你想要导出的exe文件名就好
至此,壳就解完了。ESP是比较通用,比较基础的手动解壳方法,虽然这种简单壳后期都是用软件直接自动解壳,但是作为学习的话掌握这一种也是很有必要的。