所以,假设我可以访问程序的寄存器。我可以访问 esp、ebp 和 eip。 eip指向下一条需要执行的指令,ebp指向另一个帧指针,esp指向堆栈顶部。我理解这一点,但是我不理解堆栈的其余部分或如何解析它。
例如,如果我想获取帧的局部变量,我是否应该减去ebp - esp
(知道ebp
是一个比ebp更大的地址) code>esp
) 然后遍历这些地址并取消引用它们?这是从特定框架获取局部变量的正确方法吗?
另一个问题,找出与每个框架相关的函数的最佳方法是什么?如果我将 ebp
地址减去 1,然后取消引用该值,我是否应该得到返回地址“0x804...”?这个地址和函数有什么关系呢?例如,如果 Foo() 的高 pc 地址为 0x8045555
,低 pc 地址为 0x8045550
,则我将得到的返回地址位于两者之间这些地址?
非常感谢,如果我不够清楚,请告诉我..
注意:如果有人有更好的标题建议,我没有找到更好的标题。
最佳答案
详细信息取决于您的 CPU 指令集架构(您显然使用的是 32 位 x86)和您的编译器工具链(我无法猜测)。一般来说,您不想自己重写代码来遍历堆栈帧,因为它复杂且脆弱,并且取决于编译器的优化和调试设置。
如果您尝试调试程序,您应该首先让您平台的调试器尝试整理堆栈。例如,使用 gdb
,您可以运行 bt
来获取“回溯”。
如果您尝试在相关程序内部执行此操作,并且您正在使用 GNU C 库,那么您可以使用 backtrace(3)
功能。
如果您只是想了解事情的真正运作方式,这里有一篇有用的博客文章:http://eli.thegreenplace.net/2011/02/04/where-the-top-of-the-stack-is-on-x86/
要更深入地了解,请尝试维基百科的 x86 Calling Conventions文章。要更深入地了解,如果您使用的是基于 ELF 的架构(例如 Linux),请参阅 ELF ABI specifications ..
关于c - 解析堆栈和寄存器(EBP、EIP、ESP)并找出与每个帧相关的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13281254/