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

How to read the function parameters from call stack frames programmatically in Windows?

本文关键字:调用 堆栈 读取 参数 函数 方式 Windows 编程      更新时间:2023-10-16

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

然而,作为StackWalk64的返回值的STACKFRAME64中的DWORD64 Params[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。为什么应该有,现代操作系统对一些人玩这些东西不感兴趣。如前所述,编译器可以自由地进行优化,因此您不能使用任何确定性工具来进行优化。但是,有启发法!如果在调用前解析汇编或在调用后解析ret,您就可以知道函数中有多少参数,您总是有返回地址,可以检查它是否在CS中。

最重要的是,你应该阅读术语"堆栈展开"。