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

时间:2014-04-17 22:16:16

标签: c++ windows winapi windbg callstack

我试图遍历调用堆栈帧并从中提取一些信息。我可以使用WinDBG中的StackWalk64SymGetSymFromAddr64SymGetLineFromAddr64 API来提取文件名,行号和函数名。

但是,DWORD64 Params[4]中的STACKFRAME64(来自StackWalk64的返回值)仅支持从帧中读回四个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来获取准确的值?如果我能得到参数的类型和名称会更好。

1 个答案:

答案 0 :(得分:1)

它没有API。为什么会有这样的现代操作系统对一些玩这种东西的人不感兴趣。 如前所述,编译器可以自由地进行优化,因此您无法使用任何确定性工具来执行此操作。 但是,有启发式!如果在调用之前解析汇编或在调用之后退出,您可以知道函数中有多少参数,您总是有返回地址,可以检查它是否在CS中。

最重要的是 - 你应该阅读有关术语'堆栈展开'的信息。