看流星社区

 找回密码
 注册账号
查看: 1912|回复: 0

[备忘]栈 EBP ESP

[复制链接]

该用户从未签到

发表于 2017-6-1 12:56:22 | 显示全部楼层 |阅读模式
这个虽然简单,但我啊,总是忘,老啦老啦~
还是写下来备忘吧


未进行函数梗之前 此时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/

8771824
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-3-19 11:17

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表