ESP定律
dlytgaowen 的 ESP定律
一、ESP定律
EQ:何为ESP定律;为什么我们在脱壳的时候在程序载入OD后F8单步对寄存器ESP值地址下硬件断点后会来到壳跳向程序OEP的地方?
AS:ESP定律就是“堆栈平衡”原理也就是壳入栈和出栈的地址为对应
我们来看下面的图:
―――――――――――――――――――――――――――――――――――――――
程序载入OD时CPU主线程:
寄存器:
堆 栈:
当我们F8单步后的图:
CPU主线程:
寄存器:
此时的堆栈和寄存器的对比图:
―――――――――――――――――――――――――――――――――――――
通过此图大家可以看出壳在压栈也就是把寄存器的值全部压入堆栈,那么即然是“堆栈平衡”原理,在壳的出口也就是将要到达OEP时的值也应该是一样的,再看下图是程序将要到达OEP图:
和加壳程序载入OD的堆栈图比较一下大家就明白了:
除了EIP不同以外,eax保存当前OEP值,其他都样。 为什么会这样呢?我们来看看 A:PUSHAD
B:CALL
C:popad
D:JNZ
――――――――――――――――――――――――――――――――――――――
0040D000
A> 60 pushad //注意这里ESP=0012FFC4(壳入口)
0040D001 E8
00000000 call
ASPACK.0040D006 //ESP=0012FFA4
PUSHAD就是把所有寄存器压栈!我们在到壳的最后看看:
0040D558
61 popad //ESP=0012FFA4(壳出栈口)
0040D559 75 08
jnz short ASPACK.0040D563
//注意这里ESP=0012FFC4
―――――――――――――――――――――――――――――――――――――――
现在大家可以看出什么来了吧……两两对应。
―――――――――――――――――――――――――――――――――――――――
也就是说当我们对ESP的0012FFA4下硬件访问断点之后。当程序要通过堆栈访问这些值
,从而恢复原来寄存器的值,准备跳向OEP的时候,OD帮助我们中断下来。
我们可以把壳假设为一个子程序,当壳把代码解压前和解压后,他必须要做的是遵循堆栈平衡的原理。那怕就是有些壳偷代码抽取字节表面是不遵循堆栈平衡的原理实际上还是遵循的,也有的不把值放在ESP中而是放在了其它的地方,以防止ESP定律脱壳。
因为大家对ESP理解各有异同,但是,大同小异!一般理解可以为: 1、在命令行下断hr
esp-4(此时的ESP就是OD载入后当前显示的值)
如果在载入OD后的pushad时的(ESP值-4)值,此例为(0012FFC4-4=0012FFC0)下断运行断下的地方刚好就是POPAD出栈。
2、hr
ESP(关键标志下一行代码所指示的ESP值(F8单步通过))
3.是不是只能下断12FFA4的访问断点?
当然不是,那只是ESP定律的一个体现,我们运用的是ESP定律的原理,而不应该是他的具体数值,不能说12FFA4,或者12FFC0就是ESP定律,他们只是ESP定律的一个应用罢了!
―――――――――――――――――――――――――――――――――――――――