ESP寻址原理

来源:互联网 发布:数据标准化作用 编辑:程序博客网 时间:2024/05/17 02:07

正常情况下我们栈的寻址方式是EBP+偏移的方式来寻址的,我们先来看一段代码,这是一段裸函数的汇编

//保留调用前的栈底PUSH EBP//这里会保留栈底//提升堆栈MOV EBP,ESP//我们可以知道这种方式EBP(栈底)寻址时是不会发生变化的,栈底我们是不会去改变它的,所以我们在寻址时都是EBP+...SUB ESP,0x40//保留现场PUSH EBXPUSH ESIPUSH EDI//开始填充缓冲区MOV EAX,0xCCCCCCCCMOV ECX,0x10LEA EDI,[EBP-0x40]REP STOSD//恢复现场POP EDIPOP ESIPOP EBX//降低堆栈MOV ESP,EBPPOP EBPRET
但是这种方式不是编译器所采用的方式,而编译器会采用如下的方式来寻址,我们来看看


可以看到,编译器并没有像我们那样利用EBP,并没有保存栈底,而是直接将栈顶提高一定的数量
这里编译器利用SUB ESP,54来开栈,这时候ESP+54里面存的就是返回地址
那么编译器是如何找到我们所需要的参数的呢?我们来看一下
我们先来看看当程序运行到这一行时ESP的值



ESP的值为0012FEE4,我们先记住这个值

然后我们来看看编译器是如何寻址的


我们发现编译器利用ESP+偏移的形式来找到我们的数据,注意上面画红线的地方有一个push,那么问题来了,一旦发生了push我们的ESP就会发生变化,也就是说现在的ESP已经不是我们上面的ESP的值了,我们来看看


现在的ESP值为0012FEE0,接下来我们来看看编译器是怎样找到我们的参数的
上面ESP+5C,5C是一个偏移量,什么?你问我为什么要+5C? 因为编译器在开栈的时候用的是SUB ESP,54,也就是说编译器直接把栈顶提高了0x54,0x54是返回地址,那么+5C就是第一个参数


从堆栈窗口我们可以看到,+5C就是我们的第一个参数,它的值为004000000也就是我们的程序领空,也就是ImageBase
也就是我们入口函数的第一个参数HINSTANCE hInstance的值



总结:
编译器并不是我们想象的那样利用EBP来寻址,而是利用ESP来寻址
ESP的值会随时发生变化,而EBP寻址方式EBP的值在寻址时是不会发生变化的

0 0
原创粉丝点击