0

我正在为一门课程编写一个回溯跟踪程序。提供的启动代码在崩溃时为我们提供了 %eip,我们应该打印运行时堆栈的回溯。

第一步似乎是获取顶部堆栈的 %ebp,我们的任务说“在 C 代码中可以访问的东西相对于当前基指针具有保证的固定位置”。

我唯一能想到的是将函数的参数存储在 %ebp 以上的固定位置,但我想不出任何可能的方式来使用这些信息。

什么是只用 C 代码(没有内联汇编或任何东西)找到​​这个 %ebp 的方法?

任何朝着正确方向发展的人都将不胜感激!我在 x86-32 位。

4

2 回答 2

1

我假设该任务是为 Linux/UNIX 提供的。

提供的启动代码在崩溃时为我们提供 %eip,

所以,你现在在 SIGSEGV 处理程序中并且有来自....上下文的 eip - 处理程序的第三个参数?

第一种方式:

信号处理程序在应用程序堆栈上启动;如果您将获取某个局部变量的地址,您将获得指向堆栈的指针:

 void sigsegv_handler(int signo, siginfo_t *info, void *context)
 {
   int a;
   void * ptr = &a;
   void * ptr_epb = ptr+0x**; 
   // 0x** is an unknown offset, find in disassembly or in debugger
 }

如果我们谈论一般情况(根据 C 编程语言标准和/或某些 UNIX 规范,这应该是未定义的行为),这通常不是“保证相对于当前基指针的固定位置”。但对于 x86/x86_64;一些固定的编译器;固定的编译器选项集;启用帧指针保存在堆栈中,则此偏移量将是恒定的。

第二种方式:

检查 ucontext.h (/usr/include/sys) 并通过处理程序的第三个参数侵入它。

于 2012-08-07T20:48:35.470 回答
1

在 GCC 中,使用__builtin_frame_address(level). 请参阅此页面。任何通过标准 C 结构查找 %ebp 的尝试都可能是一种无法保证有效的黑客攻击。

于 2012-08-07T21:00:31.260 回答