关于函数栈帧的有趣代码

 1 [cc lang="c"]
 2 #include "stdafx"
 3 void surprise()
 4 {
 5     printf("surprise!\n");
 6     exit(0);
 7 }
 8 
 9 void test()
10 {
11     int tmp = 10;
12     int *p = (int *)(&tmp + 4); //这里所加的值与代码编译环境有关
13                                 //此处的4是在VS2017中测试所得
14     *p = (int)surprise;
15 }
16 
17 int main()
18 {
19     test();
20     return 0;
21 }
22 [/cc]

 

初看到这个代码,完全不理解这是个什么意思
学习过函数的栈帧后,就觉得很容易理解了。

其结果为程序运行了surprise函数。

过程其实很简单。


首先main函数调用test函数。
在test函数中,先定义了一个int型变量,
然后定义了一个指针p,这个指针指向tmp地址加4的地址,
最后把这个地址里的数据改为surprise函数的指针。
其实这个地址存的就是main函数调用test函数之后要返回的指令的地址。

无图无真相,下面是我在vs2017中分析的过程:

首先我们在main处设置断点,以便于接下来的调试。
对于main之前的过程这里不做分析。

接下来按f5进入调试,在代码上右键点击选择转到反汇编。

我们就会看到如下汇编代码:

 1 [cc lang="c"]int main()
 2 {
 3 002A17C0 push ebp 
 4 002A17C1 mov ebp,esp 
 5 002A17C3 sub esp,0C0h 
 6 002A17C9 push ebx 
 7 002A17CA push esi 
 8 002A17CB push edi 
 9 002A17CC lea edi,[ebp-0C0h] 
10 002A17D2 mov ecx,30h 
11 002A17D7 mov eax,0CCCCCCCCh 
12 002A17DC rep stos dword ptr es:[edi] 
13 test();
14 002A17DE call _test (02A1384h) 
15 return 0;
16 002A17E3 xor eax,eax 
17 }[/cc]

其中有两个指针寄存器
ESP:栈指针寄存器(extended stack pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的栈顶。
EBP:基址指针寄存器(extended base pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的底部。

我们可以看到前三句指令就是为main函数在内存中分配了一个大小为0C0h的栈。
接着将ebx,esi,edi入栈,这里暂且不管这三个寄存器作用。
然后下面到call之前的代码是将之前分配的栈初始化。

call指令调用test函数(02A1384h) ,这里我们先记下return指令的地址:002A17E3

在VS2017中选择 “调试-->窗口-->内存-->内存1 ” 进入内存查看窗口:

运用逐语句及逐过程调试菜单将汇编代码运行至call指令处,
过程中在内存窗口中我们可以通过esp所指向的地址来查看相应内存变化。
可以观察到,0x0135FC5C - 0x0135FD24为main函数的栈。

接着按f11(逐语句)执行call命令,
我们会发现在main函数的栈顶压入了一个地址002A17E3,
对,就是刚才main中test()的下一条指令return的地址。

划重点,后面在test函数中就是通过改变这个地址的值为surprise函数的地址,
使程序在test函数执行后跳转至surprise函数的。

逐步执行程序,可以得知如下图所示信息,
因为内存中栈是由高地址向低地址扩展的,因此test的栈底紧挨着main的栈顶,
从而可以在test函数中根据tmp的地址增加4来找到main的返回地址,进而改变程序的运行。

在test的汇编中有这么几句,暂时不太理解其含义。

mov  eax,dword ptr  [__security_cookie(02AA000h)]
mov  eax,ebp
mov  dword ptr [ebp-4],eax

到此,关于这个代码的分析就结束了。

当然,日常编码中我觉得没人会这么干。
不过,这个有趣的代码加深了我对栈帧的理解。

posted @ 2018-07-24 23:33  Rohdea  阅读(201)  评论(0)    收藏  举报