gpt4 book ai didi

windows - 符号如何解决在 x86 调试中使用 FPO 遍历堆栈?

转载 作者:可可西里 更新时间:2023-11-01 10:03:10 25 4
gpt4 key购买 nike

在这个答案中:https://stackoverflow.com/a/8646611/192359 ,解释了在调试 x86 代码时,即使使用了 FPO(帧指针省略),符号也允许调试器显示调用堆栈。

给出的解释是:

On the x86 PDBs contain FPO information, which allows the debugger to reliably unwind a call stack.

我的问题是这些信息是什么?据我了解,仅知道函数是否具有 FPO 并不能帮助您找到堆栈指针的原始值,因为这取决于运行时信息。

我在这里错过了什么?

最佳答案

从根本上说,总是可以用足够的信息遍历堆栈1,除非堆栈或执行上下文已被不可恢复地损坏。

例如,即使 rbp 没有被用作帧指针,返回地址仍然在堆栈的某个地方,您只需要知道它在哪里。对于不在函数体中(间接或直接)修改 rsp 的函数,它将位于 rsp 的简单固定偏移处。对于在函数体中修改 rsp 的函数(即具有可变堆栈大小的函数),rsp 的偏移量可能取决于函数中的确切位置。

PDB 文件仅包含此“边带”信息,它允许某人确定函数中任何指令的返回地址。 Hans 链接了一个相关的内存结构 above - 你可以看到,因为它知道局部变量的大小等,所以它可以计算 rsp 和框架基址之间的偏移量,从而获得返回地址。它还知道有多少指令字节是“prolog”的一部分,这很重要,因为如果 IP 仍在该区域中,则适用不同的规则(即,堆栈尚未调整以反射(reflect)此函数中的局部变量)。

在 64 位 Windows 中,确切的函数调用 ABI 变得更加具体,所有函数通常都必须提供展开信息:不在 .pdb 但直接在二进制文件中包含的部分中。因此,即使没有 .pdb 文件,您也应该能够展开结构正确的 64 位 Windows 程序。它允许任何寄存器用作帧指针,并且仍然允许省略帧指针(有一些限制)。详情请start here .


1 如果这不是真的,问问自己当前运行的函数如何返回?现在,技术上您可以设计一个程序,该程序以无法返回的方式破坏或忘记堆栈,并且永远不会退出或使用类似 exit()abort() 终止。这是非常不寻常的,不可能在装配之外。

关于windows - 符号如何解决在 x86 调试中使用 FPO 遍历堆栈?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45714943/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com