C-解析堆栈和寄存器(EBP,EIP,ESP),并弄清楚哪些功能与每个帧有关



所以,假设我可以访问程序的寄存器。我可以访问ESP,EBP和EIP。EIP指出了需要执行的下一个指令,EBP指向另一个帧指针,ESP指向堆栈的顶部。我理解这一点,但是我不了解其余的堆栈或如何解析。

例如,如果我想获取帧的局部变量,我是否应该减去ebp - esp(知道ebpesp更大的地址),然后浏览这些地址并取消它们?这是从该特定帧获取本地变量的正确方法吗?

另一个问题,找出哪个功能与每个帧有关的最佳方法是什么?如果我将1减为 ebp地址,然后取消该值,我是否应该获得返回地址" 0x804 ..."?这个地址和功能之间有什么关系?例如,如果foo()具有0x8045555的高PC地址和0x8045550的低PC地址,那么我将要在这些地址之间进入的返回地址?

非常感谢Advanced,让我知道我是否还不够清晰。

注意:如果有人有更好的标题建议,我找不到更好的标题。

此详细信息取决于您的CPU指令集体系结构(显然您使用的是32位X86)和编译器工具链(我无法猜到)。通常,您不想重写代码以自己行走堆栈框架,因为它很复杂且脆弱,并且取决于编译器的优化和调试设置。

如果您要调试程序,则应首先让调试器的平台尝试整理堆栈。例如,使用gdb,您可以运行bt以获取"后跟踪"。

如果您想从相关程序内部执行此操作,并且正在使用GNU C库,则可以使用backtrace(3)函数。

如果您只想了解事情的真正起作用,这是一篇有用的博客文章:http://eli.thegreenplace.net/2011/02/04/where-the-the-the-top-top-oc--o--o--o-----------------------X86/

要深入了解,请尝试Wikipedia的X86召集惯例文章。要更深入,如果您使用的是基于ELF的体系结构,例如Linux,请参阅Elf ABI规格。

寄存器中和堆栈中的数据只是一系列字节。数据是由将字节放入该系列的各种指令和应用程序构成的,但是有关字节结构的信息不是一系列字节的一部分,而是可能可用或可能无法可用的其他信息。

例如,当编译源代码并且二进制代码由编译器生成二进制代码时,二进制代码将包含其他描述性信息。其他描述性信息的数量将取决于所选择的编译器选项以及所使用工具链中各种其他工具的功能。

例如,如果选项要创建带有其他信息(例如函数名称)的调试构建,并且工具链使用其他信息支持二进制代码的显示,那么您可以很好地了解变量,功能名称,并在源代码级别浏览代码。

另一方面信息不存在,工具链无法在源代码级别显示二进制代码,显示源,变量,功能名称等线等。

因此,为了完成您想做的事情,您需要拥有其他信息,以便将二进制代码与其他信息结合在一起。没有其他信息,您拥有的只是内存中的一堆字节。您可以以各种方式显示这些字符,例如将它们解释为汇编代码,也可以将其解释为文本字符串。但是,没有其他信息,您只是在做出猜测,但是受过教育。

不同平台和操作系统上的不同编译器和工具链将生成不同类型的其他信息。因此,您需要获得有关工具链提供的特定信息的信息。

最新更新