我正在为一门课程编写一个回溯跟踪程序。提供的启动代码在崩溃时为我们提供了 %eip,我们应该打印运行时堆栈的回溯。
第一步似乎是获取顶部堆栈的 %ebp,我们的任务说“在 C 代码中可以访问的东西相对于当前基指针具有保证的固定位置”。
我唯一能想到的是将函数的参数存储在 %ebp 以上的固定位置,但我想不出任何可能的方式来使用这些信息。
什么是只用 C 代码(没有内联汇编或任何东西)找到这个 %ebp 的方法?
任何朝着正确方向发展的人都将不胜感激!我在 x86-32 位。
我假设该任务是为 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) 并通过处理程序的第三个参数侵入它。
在 GCC 中,使用__builtin_frame_address(level)
. 请参阅此页面。任何通过标准 C 结构查找 %ebp 的尝试都可能是一种无法保证有效的黑客攻击。