-
-
[原创]02 C语言-嵌套函数的栈空间布局
-
2021-3-23 15:56
7976
-
02 C语言下嵌套函数的栈空间布局
前言
该文章主要描述说明C语言Debug环境下,函数调用函数它的内存布局是如何的一样状态。
1;测试代码
int a(int x, int y) {
return x + y;
}
int b(int x, int y, int z) {
int m = a(x, y);
return z + m;
}
int main() {
int c;
c = b(1, 2, 3);
return c;
}
2;分析代码
首先,我们先简单说明一下上述代码,程序会在main() 位置开始执行,执行到“c = b(1,2,3)”会调用b()函数,在b()函数内部又调用了a()函数。最终,执行的值放入变量c当中。
接下来,我们先将内存布局图画出来,然后在逐步分析为什么会产生这样的内存布局。如果不了解如何画出内存布局,可以参考我之前的文章。连接如下:https://bbs.pediy.com/thread-266576.htm
接下来,我们来具体分析一下这张图,我们,我们先将程序使用OD打开,并且定位到地址“00881858”位置。详细如下图:
该位置执行了三个push 指令以及一个call 指令,完成了参数的传递以及函数的调用。执行完成栈空间的状态如下图。此时我们发现b()函数的参数已经进入栈中,并且b()函数的返回地址已经压入栈区。
执行完call 指令,代码定位到如下图位置。此时,会执行保存上个栈底,初始化新的b()函数的栈帧,划分cc大小的缓冲区,初始化缓冲区为cc指令以及保存环境的操作。
上述红框当中代码执行完成之后,栈空间状态如下图:
这个时候,我们的c语言已经执行完成了b()函数的栈空间准备工作,接下来是执行b()函数体内容。即如下图位置:
我们发现这里又是执行了调用一个a()函数的操作。那么,我们在汇编代码当中来查看。我们发现,函数a()的传参是由之前调用b()函数压入的栈参数调用并且放入寄存器,最后压入栈当中。
执行两个push ,call 指令之后,我我们观看栈空间,详细如下图:
这个时候,我们又发现了一个熟悉的汇编代码,接下来,就是重复之前函数b()的准备工作。
执行完成之后,我们再次观察栈空间。此时,栈空间已经在嵌套调用函数情况下变成了如下图的 模样。
3;总结
1;在函数的嵌套调用当中,栈空间会重复执行如图的栈帧初始化,形成对应函数的对应栈帧。且是一直是向上生长。
[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界
最后于 2021-3-23 16:24
被天象独行编辑
,原因: