概述
关于IA32下函数调用栈的理解与利用以及对于Linux64bit函数调用栈的变化的疑问
通过图和阅读CSAPP可知调用函数时会先开辟一定空间的栈帧来为函数调用
每个函数调用开头的会有
push %ebp
movl %esp,%ebp
sub %xx,%esp ;这里是为新函数开辟xx字节的空间
可知进入新函数后,区间[esp,ebp]之间的范围就是新函数的空间
而新函数传入的参数则是保存到[ebp+4h] [ebp+8h]…等
比如,存在函数func
void func(int a);
通过调用func函数后,ebp和esp的指向的是func的栈帧空间,此时[ebp+8h]就是a的空间。而调用func的函数的返回地址则保存在[ebp+4h],通过修改
返回地址我们可以使得func返回后不回到main函数,而是去到我们修改后的函数的地址,比如这段程序
#include <stdio.h>
void call(void){
printf("call men");
}
int func(int a,int b){
int *p = &a;
p[-1] = &call;
return 0;
}
int main(void){
func(5,5);
return 0;
}
运行结果,
当然,这是在啊哈C这款轻量级的IDE上面调试出来的结果
可是,这段代码在gcc version 8.3.0 (Debian 8.3.0-6)环境下面是无法调用出来的,而且此时传入的参数地址不再是当前函数栈帧的ebp + 08h.这是比较纳闷的,
1148: 55 push %rbp
1149: 48 89 e5 mov %rsp,%rbp
114c: 89 7d ec mov %edi,-0x14(%rbp)
116 114f: 48 8d 45 ec lea -0x14(%rbp),%rax ;此时a 的地址为(rbp-0x14)
且本地变量仍然保存在当前[ebp-08h],传进去的参数的地址却变了.这是比较纳闷的,可能我看的CSAPP第二版比较老,在一些比较新的gcc和Linux下面出现了变化。。。。。
这里先挖个坑,等哪天搞懂了再来补充.。。。
最后
以上就是诚心菠萝为你收集整理的关于IA32下函数调用栈的简单理解与利用以及对于Linux64位函数调用栈的变化的疑问的全部内容,希望文章能够帮你解决关于IA32下函数调用栈的简单理解与利用以及对于Linux64位函数调用栈的变化的疑问所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复