如何在Windows中以编程方式从调用堆栈帧中读取函数参数
How to read the function parameters from call stack frames programmatically in Windows?
我试图遍历调用堆栈帧,并从中提取一些信息。我可以使用WinDBG中的StackWalk64
、SymGetSymFromAddr64
和SymGetLineFromAddr64
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中。
最重要的是,你应该阅读术语"堆栈展开"。
相关文章:
- Visual Studio(或任何其他工具)能否将地址解释为调用堆栈(boost上下文)的开头
- 为什么调用堆栈数组会导致内存泄漏
- 是否可以检查悬挂光纤的调用堆栈?
- MSVC __debugbreak() 与 openGL 错误回调一起使用时不会产生调用堆栈
- 以下代码如何工作以每次为唯一调用堆栈唯一实例化模板函数?
- OpenCV 3 Visual Studio 2017 调试,调用堆栈没有.pdb文件
- C/C++中全局调用堆栈的基础
- 是否可以访问代码中的调用堆栈?
- 调用堆栈显示 SIGBUS,这意味着什么
- 打开C++故障转储不会在调用堆栈中显示正确的行
- 将参数推送到调用堆栈 (C++) 的可移植方法
- 是否可以将功能调用堆栈放在堆上
- 未定义对调用堆栈库的引用出现问题
- 我无法获得由 Clang 构建的优化 NDK 应用程序的调用堆栈
- 调用堆栈中的访问冲突
- GDB正在调试一个缺少特定调用堆栈的符号表的核心转储
- C++按引用传递:如何使用调用堆栈
- 从系统调用内部生成调用堆栈
- 使用 .Net 4.0 时出现堆栈不平衡错误,但在使用 .Net 2.0 时不调用堆栈不平衡错误
- 生成所有可能的调用堆栈的树