![]() |
1
25
为此,有一个GCC内置:
见 http://gcc.gnu.org/onlinedocs/gcc/Return-Address.html 在某些架构中,您可以在堆栈中相对于第一个参数找到它。例如,在ia32上,参数被推送(按相反的顺序),然后调用将推送返回地址。记住,堆栈几乎总是(在ia32上)增长 向下地 . 尽管技术上你需要 阿比 或 调用规则 (有时打电话 链接约定 )对于您的语言和硬件平台,在实践中,您通常可以猜测您是否知道过程调用machine op是如何工作的。 函数的第一个参数和返回地址在堆栈上的位置之间的关系比本地地址和返回地址之间的关系更可能是可靠的固定值。但是,您当然可以打印出本地和第一个参数的地址,并且您经常会发现PC就在这两者之间。
|
![]() |
2
3
例如,当您声明局部变量时,它们也在堆栈-x上。
如果您随后声明
没有什么可以阻止你减少指针,让它在前面看一看,或者增加它以便以后看。这附近有你的寄信人地址。 |
![]() |
3
2
要知道寄信人的地址,你需要知道
calling convention
是。这通常由编译器设置,并取决于平台,但您可以用特定于平台的方式强制它,例如使用
除非使用编译器内置程序来获取返回地址,否则必须使用内联汇编程序来获取值。其他在调试中起作用的技术对于编译器的优化来说是非常有用的。 |
![]() |
4
2
你可以像这样在烟囱周围探测
您可以摆脱这一点,因为C以索引数组的方式不是特别出名。在这里,您在堆栈上声明一个虚拟数组,然后查看与之相关的+/-。 正如RobWalker所指出的,您肯定需要了解编译器调用约定,以了解您正在查看的数据。您可以打印出一些函数的地址,并查找类似范围内的值,并在返回地址所在的位置直观地相对于虚拟数组。 注意一点-阅读所有你想要的,但不要使用该数组修改任何东西,除非(a)你完全确定你要修改的是堆栈的哪个部分,或者(b)只是想看到一个有趣的/不可预测的崩溃模式。 |
![]() |
5
1
请注意,一般来说,C语言不能保证您的返回地址在堆栈上,或者实际上在RAM中的任何地方。 有些处理器体系结构将返回地址存储在寄存器中,只有在调用开始嵌套时才使用RAM。还有其他的架构,其中有一个单独的返回地址堆栈,CPU不可读。这两种方法都可以为它们实现C编译器。 这就是为什么你需要更清楚地了解你的环境。 |
![]() |
6
-1
试试这个
输出应该像
|
![]() |
Doohyeon Won · 内联函数上的奇怪现象?[关闭] 5 月前 |
![]() |
MysteryMoose · GCC下故意忽略初始化器警告中的过量元素 6 月前 |
|
Ken P · 如何利用[*]printf格式类型规范警告? 10 月前 |
![]() |
fghoussen · 在C结构体中,为什么打包、对齐似乎会进行填充? 10 月前 |
![]() |
adversarr · 全局变量何时导出到可执行文件? 10 月前 |