我试图遍历调用堆栈帧并从中提取一些信息。我能够使用来自 WinDBG 的 StackWalk64
、SymGetSymFromAddr64
和 SymGetLineFromAddr64
API 提取文件名、行号和函数名。
但是STACKFRAME64
中的DWORD64 Params[4]
是StackWalk64
的返回值,只支持回读4个64位来自帧的函数参数。更糟糕的是,在 32 位系统上,仅使用 Params[4]
的低 32 位,因此超过 32 位的单个参数需要两个或更多元素。
typedef struct _tagSTACKFRAME64 {
ADDRESS64 AddrPC;
ADDRESS64 AddrReturn;
ADDRESS64 AddrFrame;
ADDRESS64 AddrStack;
ADDRESS64 AddrBStore;
PVOID FuncTableEntry;
DWORD64 Params[4];
BOOL Far;
BOOL Virtual;
DWORD64 Reserved[3];
KDHELP64 KdHelp;
} STACKFRAME64, *LPSTACKFRAME64;
我找不到任何 API 来无限制地从堆栈帧中读取所有参数。
我正在考虑使用 ebp
/rbp
从堆栈 (x86/x64) 和寄存器 (x64) 中提取值。但是,如果我这样做,仍然只能获得参数的“可能”值。
有没有我可以用来获取准确值的 API?如果能得到参数的类型和名称就更好了。
最佳答案
它没有 API。为什么会有任何现代操作系统对某些玩这些东西的人不感兴趣。 如前所述,编译器可以自由进行优化,因此您无法使用任何确定性工具来进行优化。 但是,有启发式!如果在调用前解析汇编或在调用后返回,你可以知道函数中有多少参数,你总是有返回地址,你可以检查它是否在 CS 中。
最重要的是 - 您应该阅读术语“堆栈展开”。
关于c++ - 如何在 Windows 中以编程方式从调用堆栈帧中读取函数参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23144389/