【问题标题】:Parsing the Stack and Registers (EBP, EIP, ESP) and figuring out which function is related to each frame解析堆栈和寄存器(EBP、EIP、ESP)并找出与每一帧相关的函数
【发布时间】:2012-11-08 01:44:50
【问题描述】:

所以,假设我可以访问程序的寄存器。我可以访问 esp、ebp 和 eip。 eip 指向下一条需要执行的指令, ebp 指向另一个帧指针, esp 指向栈顶。我理解这一点,但是我不理解堆栈的其余部分或如何解析它。

例如,如果我想获取框架的局部变量,我是否应该只减去ebp - esp(知道ebp 是比esp 更大的地址)然后遍历这些地址并取消引用它们?这是从该特定框架获取局部变量的正确方法吗?

另一个问题,找出与每一帧相关的函数的最佳方法是什么?如果我将 ebp 地址减去 1,然后取消引用该值,我应该得到返回地址“0x804 ...”吗?这个地址和函数有什么关系?例如,如果 Foo() 的高地址为 0x8045555,低地址为 0x8045550,那么返回地址是否会在这两个地址之间?

非常感谢,如果我不够清楚,请告诉我..

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

【问题讨论】:

    标签: c pointers assembly stack cpu-registers


    【解决方案1】:

    这方面的细节取决于您的 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/

    要更深入地了解,请尝试 Wikipedia 的 x86 Calling Conventions 文章。更深入地了解,如果您使用的是基于 ELF 的架构,例如 Linux,请参阅ELF ABI specifications..

    【讨论】:

    • 好吧,我想我想要一个全面的了解。我现在正在使用 Pin 来读取程序中的寄存器,并且我正在研究类似于调试器的东西。问题是我有 EBP 的地址,我认为通过减去 1 然后取消引用它,我会得到帧的返回地址,但我没有得到。感谢您的链接,我会检查它们! @JameySharp
    • 您可能需要减去 4,而不是 1,因为在汇编级别,所有指针运算都是面向字节的。 (至少,在 x86 上...)
    【解决方案2】:

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

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

    例如,如果选项是使用附加信息(例如函数名称)创建调试版本,并且工具链支持使用附加信息显示二进制代码,那么您可以很好地查看变量、函数名称,并在源代码级别单步执行代码。

    另一方面,如果选项是在没有附加信息的情况下创建优化的构建,那么即使工具链可能支持使用附加信息来显示二进制代码,以便以更易读的视图呈现二进制代码,因为信息不存在,工具链无法在源代码级别显示二进制代码,显示源代码行、变量、函数名称等。

    因此,为了完成您想要做的事情,您需要拥有附加信息,以便您可以将二进制代码与附加信息结合起来。如果没有额外的信息,你所拥有的只是内存中的一堆字节。您可以以各种方式显示这些字节,例如将它们解释为汇编代码或将它们解释为文本字符串。然而,如果没有额外的信息,你只是在猜测,不管有多么受过教育。

    不同平台和操作系统上的不同编译器和工具链会生成不同类型的附加信息。因此,您需要了解您的工具链提供的具体信息。

    【讨论】:

    猜你喜欢
    • 2012-01-11
    • 2015-02-03
    • 2016-06-07
    • 2017-03-12
    • 2012-12-20
    • 2019-06-18
    • 2014-01-08
    • 2016-12-17
    • 2016-10-01
    相关资源
    最近更新 更多