c++ - 如何在 Windows 中以编程方式从调用堆栈帧中读取函数参数?

标签 c++ windows winapi windbg callstack

我试图遍历调用堆栈帧并从中提取一些信息。我能够使用来自 WinDBG 的 StackWalk64SymGetSymFromAddr64SymGetLineFromAddr64 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/

相关文章:

windows - 在 Windows 8 上声明每个窗口的高 DPI 感知

c++ - 如何在 Qt Creator 的控制台应用程序中将日志打印到文件中?

c++ - 链表析构函数与 Valgrind 一起执行,但不单独执行

c++ - 如何在 Windows 上紧密打包结构?

windows - 在 Windows 7 上以不同用户身份运行的单行命令也包含密码

.net - 32 位和 64 位系统上的 P/Invoke

c++ - 准确地创建范围 [a,b) 中的浮点值

c++ - 区分选定单元格和编辑单元格

windows - 使用 os.walk 时如何绕过窗口的最大路径长度限制?

windows - 访问非常长的文件名的 ntfs 流失败