您的位置:首页 > 其它

[备忘]栈 EBP ESP

2016-05-02 07:16 295 查看
这个虽然简单,但我啊,总是忘,老啦老啦~

还是写下来备忘吧

未进行函数梗之前 此时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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: