[备忘]栈 EBP ESP

这个虽然简单,但我啊,总是忘,老啦老啦~

还是写下来备忘吧


未进行函数梗之前 此时ebp无效

还没push ebp
esp = 返回地址
esp + 4 参数1
esp + 8 参数2
esp = 0020FC84
0020FC84  01071597  返回到 EbpEsp.01071597 来自 EbpEsp.0107109B // esp 返回地址
0020FC88  00000003  //esp + 4 参数1
0020FC8C  00000004 //esp + 8 参数2


push 后 并执行mov ebp,esp后
ebp = esp
esp + 4 返回地址 = ebp + 4
esp + 8 = 参数1 = ebp + 8
esp + c = 参数2 = ebp + c
esp = 0020FC80 = ebp
0020FC80  0020FD5C
0020FC84  01071597  返回到 EbpEsp.01071597 来自 EbpEsp.0107109B // esp(ebp)+4 返回地址
0020FC88  00000003 //esp/ebp + 8参数1
0020FC8C  00000004 //esp/ebp + c参数2


函数梗:
010713F0 >  55              push ebp
010713F1    8BEC            mov ebp,esp
010713F3    81EC D8000000   sub esp,0xD8


在执行一句sub esp,0xD8就跑去记录其它的了,此时我们只需要记住ebp
在vc6中,此时
ebp - 4 = 局部变量1 
ebp - 8 = 局部变量2
.....


在vs2008 + 
多了一个检测溢出的call
所以是
ebp - 8 = 局部1
ebp - c = 局部2 //第一个ebp - 8是固定的,但ebp - c是不固定的


000413FC    8DBD 28FFFFFF   lea edi,dword ptr ss:[ebp-0xD8]
00041402    B9 36000000     mov ecx,0x36
00041407    B8 CCCCCCCC     mov eax,0xCCCCCCCC
0004140C    F3:AB           rep stos dword ptr es:[edi]
0004140E    C745 F8 0000000>mov dword ptr ss:[ebp-0x8],0x0
00041415    C745 EC 0000000>mov dword ptr ss:[ebp-0x14],0x0
0004141C    8B45 08         mov eax,dword ptr ss:[ebp+0x8]
0004141F    8945 F8         mov dword ptr ss:[ebp-0x8],eax
00041422    8B45 0C         mov eax,dword ptr ss:[ebp+0xC]
00041425    8945 EC         mov dword ptr ss:[ebp-0x14],eax //局部变量2不是ebp - 0xc了
00041428    8B45 F8         mov eax,dword ptr ss:[ebp-0x8]
0004142B    0345 EC         add eax,dword ptr ss:[ebp-0x14]
0004142E    5F              pop edi                                  ; 0039F9C8


我测试的时候定义
int add(int a,int b)
{
int x = 0;
int s = 0;
x = a;
s = b;
return x + s;
}
局部变量s 是ebp - 0x14




总结:
在vc6中
前面跟上面说的一样
不同的是ebp - 4就是局部变量1了
此时ebp = 0018FEE8
0018FEDC  CCCCCCCC
0018FEE0  00000004 //局部2 ebp - 8
0018FEE4  00000003  //局部1 ebp - 4
0018FEE8  0018FF48  老esp
0018FEEC  00401161  返回到 EbpEsp.00401161 来自 EbpEsp.0040100A //返回地址ebp + 4
0018FEF0  00000003 //参数1 ebp + 8
0018FEF4  00000004 //参数2 ebp + c
0018FEF8  00000000


汇编代码:
00401100 >  55              push ebp
00401101    8BEC            mov ebp,esp
00401103    83EC 48         sub esp,0x48
00401106    53              push ebx
00401107    56              push esi
00401108    57              push edi
00401109    8D7D B8         lea edi,dword ptr ss:[ebp-0x48]
0040110C    B9 12000000     mov ecx,0x12
00401111    B8 CCCCCCCC     mov eax,0xCCCCCCCC
00401116    F3:AB           rep stos dword ptr es:[edi]
00401118    8B45 08         mov eax,dword ptr ss:[ebp+0x8]//参数1
0040111B    8945 FC         mov dword ptr ss:[ebp-0x4],eax//局部1
0040111E    8B4D 0C         mov ecx,dword ptr ss:[ebp+0xC]//参数2
00401121    894D F8         mov dword ptr ss:[ebp-0x8],ecx//局部2
00401124    8B45 FC         mov eax,dword ptr ss:[ebp-0x4]//局部1
00401127    0345 F8         add eax,dword ptr ss:[ebp-0x8]//局部2
0040112A    5F              pop edi                                  ; EbpEsp.00401161
0040112B    5E              pop esi                                  ; EbpEsp.00401161
0040112C    5B              pop ebx                                  ; EbpEsp.00401161
0040112D    8BE5            mov esp,ebp
0040112F    5D              pop ebp                                  ; EbpEsp.00401161
00401130    C3              retn






vc6 +
ebp = 0020FC80
0020FC68  CCCCCCCC
0020FC6C  00000004 //ebp - 0x14 参数2 这里不遵循了
0020FC70  CCCCCCCC
0020FC74  CCCCCCCC
0020FC78  00000003 //ebp - 8 参数1 这是固定的
0020FC7C  CCCCCCCC //用于检测溢出的 ebp - 4
0020FC80  0020FD5C ebp
0020FC84  01071597  返回到 EbpEsp.01071597 来自 EbpEsp.0107109B //ebp + 4 返回地址
0020FC88  00000003 //ebp + 8 参数1
0020FC8C  00000004 //ebp + c 参数2
0020FC90  00000000
0020FC94  00000000


汇编代码:
010713F0 >  55              push ebp
010713F1    8BEC            mov ebp,esp
010713F3    81EC D8000000   sub esp,0xD8
010713F9    53              push ebx
010713FA    56              push esi
010713FB    57              push edi
010713FC    8DBD 28FFFFFF   lea edi,dword ptr ss:[ebp-0xD8]
01071402    B9 36000000     mov ecx,0x36
01071407    B8 CCCCCCCC     mov eax,0xCCCCCCCC
0107140C    F3:AB           rep stos dword ptr es:[edi]
0107140E    8B45 08         mov eax,dword ptr ss:[ebp+0x8]//参数1
01071411    8945 F8         mov dword ptr ss:[ebp-0x8],eax//局部1
01071414    8B45 0C         mov eax,dword ptr ss:[ebp+0xC]//参数2
01071417    8945 EC         mov dword ptr ss:[ebp-0x14],eax//局部2
0107141A    8B45 F8         mov eax,dword ptr ss:[ebp-0x8]//局部1
0107141D    0345 EC         add eax,dword ptr ss:[ebp-0x14]//局部2
01071420    5F              pop edi
01071421    5E              pop esi
01071422    5B              pop ebx
01071423    8BE5            mov esp,ebp
01071425    5D              pop ebp
01071426    C3              retn




也就是说




在未执行函数梗之前
我们可以根据esp来得到参数
此时
esp = 返回地址
esp + 4 参数1
esp + 8 参数2


执行函数梗后
我们应用ebp来寻址
此时
........
ebp - 8 vc6中为局部2, vc6+中为局部1
ebp - 4 vc6中为局部1 vc6+此位置用于防止溢出
ebp 老esp
ebp + 4 返回地址
ebp + 8 参数1
ebp + c 参数2

........

至于x64,是使用寄存器传参的

也就是fastcall

可以参考

http://hyperiris.blog.163.com/blog/static/1808400592011715111957863/

http://blog.csdn.net/cosmoslife/article/details/8771824










你可能感兴趣的:([备忘]栈 EBP ESP)