神奇的栈帧
来源:互联网 发布:php开源三级分销商城 编辑:程序博客网 时间:2024/06/06 02:27
C语言中,每个栈帧对应着一个未运行完的函数。栈帧中保存了该函数的返回地址和局部变量。
先看张图对栈的位置有个基本的印象哈:
首先必须明确一点也是非常重要的一点,栈是向下生长的,所谓向下生长是指从内存高地址->低地址的路径延伸,那么就很明显了,栈有栈底和栈顶,那么栈顶的地址要比栈低低。
寄存器ebp在未受改变之前始终指向栈帧的开始,也就是栈底,所以ebp的用途是在堆栈中寻址用的。
寄存器esp是会随着数据的入栈和出栈移动的,也就是说,esp始终指向栈顶。
下面我们看一个有趣的程序:
感兴趣的童鞋可以运行试试哈(先保证没有重要的临时文件在运行,害怕你到时砍我),整个程序运行起来你的电脑就会重启,很好看出来,重启的程序在fun函数中,可是整个过程看起来我们并没有调用fun,为什么它还是run起来了?
原因就在这栈帧之中,首先先说明一点,ELF格式的入口是_start而不是mian,也就是说在mian函数的栈帧之前还有一个_start函数,我们先转到汇编,看看函数的栈帧到底是怎么开辟的:
先是_start的函数栈帧:
再看看main的:
通过简单的图来表示下就是这样的:
关键的部分是fun1的汇编,它具体给我们展示了到底为什么fun会被调用,下面看看吧:
再来张示意图:
结合上面两个图和注释可以看出,在fun1调用完后我们需要返回到之前保存的地址中去,而在fun1中我们将其返回的地址改成了fun函数的入口地址,所以在fun1结束后我们就跳到了fun函数,然后就悲催了。。。。。
如果我们了解了栈帧的原理,那可以做很多神奇的事情,比如在fun1中我们可以不使用b变量就将b的值改掉,很简单,通过上面的汇编可以看出只要将fun1中的p--,改成p++;就找到b变量的地址啦,然后解引用就可以修改啦,不信可以去试试喽。
- 神奇的栈帧
- 神奇的的调色板
- 神奇的*号
- 一组神奇的图片
- 神奇的一天
- 神奇的预言
- 神奇的jsfl!
- 神奇的VIM
- 神奇的猴子Mono
- 神奇的xx宏
- 神奇的视觉艺术
- 神奇的上班路上
- 神奇的视觉艺术
- 神奇的 DataGrid
- 神奇的食物
- 神奇的 DataGrid
- 神奇的 DataGrid
- 神奇的fork
- {小结}2016.6.11【初中部 NOIP提高组 】模拟赛C
- jquery animate自定义动画的使用感受
- 用共轭梯度法求函数极小值和最优解,其中用进退法求步长区间,用黄金分割法求最佳步长
- Mybatis动态SQL--采用开发案例讲解
- 剑指offer(五十九)之二叉搜索树的后序遍历序列
- 神奇的栈帧
- 面向对象——this和super
- [Java] 对象的声明与实例化
- C++ 理解二维数组的指针
- Shell脚本编程之函数
- android通讯录之短信
- win10系统下搭建cocos2d-x v3.11.1版本开发环境
- Jzptab [Bzoj 2693]
- Linux修改用户所在组方法