我试图遍历调用堆栈帧并从中提取一些信息。我可以使用WinDBG中的StackWalk64
,SymGetSymFromAddr64
和SymGetLineFromAddr64
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来获取准确的值?如果我能得到参数的类型和名称会更好。
答案 0 :(得分:1)
它没有API。为什么会有这样的现代操作系统对一些玩这种东西的人不感兴趣。 如前所述,编译器可以自由地进行优化,因此您无法使用任何确定性工具来执行此操作。 但是,有启发式!如果在调用之前解析汇编或在调用之后退出,您可以知道函数中有多少参数,您总是有返回地址,可以检查它是否在CS中。
最重要的是 - 你应该阅读有关术语'堆栈展开'的信息。