在od1.x中 主窗口中有五个子窗口, 其中一个是堆栈窗口.
除了这个堆栈窗口外, 还有一个 调用堆栈窗口(Alt+K).
这两个窗口没有什么本质的区别,反正都是显示堆栈信息. 唯一不同的是 调用堆栈窗口的数据给人更直观的感觉. 能快速的查看所有调用层次顺序. 如下图:
堆栈和调用堆栈
调用堆栈可以通过 StackWalk64 这个函数来获取.
[C++] 纯文本查看 复制代码 BOOL IMAGEAPI StackWalk64(
[in] DWORD MachineType,
[in] HANDLE hProcess,
[in] HANDLE hThread,
[in, out] LPSTACKFRAME64 StackFrame,
[in, out] PVOID ContextRecord,
[in, optional] PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine,
[in, optional] PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine,
[in, optional] PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine,
[in, optional] PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress
);
其中第一个参数是指定被调试目标程序架构模式. 比如32位程序选择 IMAGE_FILE_MACHINE_I386 , 64位程序选择 IMAGE_FILE_MACHINE_AMD64.
这里需要注意的是第5个参数, 32位和64位程序,需要填入相应的线程context.
我在调试od1.x的时候, 给 StackWalk64 下断点, 然后 按F12 ,再按 alt+k , 并没有中断下来.
我没细看, 估计有可能是用别的方法实现的, 也有可能是自己实现的调用堆栈.
我打算先用 StackWalk64 实现, 先试一下效果, 效果如果不理想的话, 就再自己实现.
下面是 OllyDbg 1.x, x32Dbg, YzDbg 调用栈对比图:
几个调试器的调用堆栈
让人感觉奇怪的是 od2.x 和 ollydbg x64 都没有 alt+k(调用堆栈) 窗口了. 不知道是不是自己没有找到. 还是真的给阉割掉了, 我感觉这个功能还是挺不错的.
od1.x的 F12中断, 实现应该还是有点问题的. 他中断后, 你按F7 或者 F8, 程序直接就运行起来了.
---------------------------
2022.11.13 更新
刚刚用 StackWalk64 实现了堆栈调用的效果. 如下图:
32位调试器_堆栈调用
猛一看, 效果好像和 od1.x 差不多, 如果你仔细看,就会发现有不少问题.
其中 [返回到] 和 [调用来自] 都是错的. StackWalk64 第四个参数是 STACKFRAME
[C++] 纯文本查看 复制代码 typedef struct _tagSTACKFRAME {
ADDRESS AddrPC;
ADDRESS AddrReturn;
ADDRESS AddrFrame;
ADDRESS AddrStack;
PVOID FuncTableEntry;
DWORD Params[4];
BOOL Far;
BOOL Virtual;
DWORD Reserved[3];
KDHELP KdHelp;
ADDRESS AddrBStore;
} STACKFRAME, *LPSTACKFRAME;
其中 AddrReturn 就是 对应的 [返回到] , 实际测试的时候发现, AddrReturn 和 堆栈窗口中的 Value不对应. 对应的数据都是错位的, 相差4字节.
另外 [调用来自] 这个数据在 STACKFRAME 结构体中并没有发现. 这个 [调用来自] 是 od1.x 中的 called from.
还有一个问题就是 编译64位的调试器,分析32位的程序, 调用 StackWalk64 [函数名/参数] 就显示为空. 我将所有的参数全部改成32位的,也一样是获取不到.
只有编译32位的调试器,分析32位的程序,才能正常显示 [函数名/参数].
既然如此, 这个 调用堆栈 还是只能自己实现了...
---------------------------
2022.11.14 更新
刚发现调用堆栈窗口, od1.x 中的 [调用来自] 和 x32dbg 的 [返回自] 数据是不一样的. 如下例子:
[Asm] 纯文本查看 复制代码
00401011 E8 08000000 CALL CrackM.0040101E
00401016 68 80000000 PUSH 80
0040101B 90 NOP
0040101C 90 NOP
0040101D 90 NOP
0040101E 8D85 78FFFFFF LEA EAX,DWORD PTR SS:[EBP-88]
od1.x 的 [调用来自], 此时的值是: 0x0040101E
x32dbg 的 [返回自], 此时的值是: 0x00401011
这两个看着功能差不多, 我最终还是选择了od1.x的 [调用来自] . 等后续,也有可能会把 [返回自] 加上.
---------------------------
to be continued...
|