调试器如何跟踪堆栈?

时间:2021-07-20 15:39:16

标签: windows stack reverse-engineering trace

我试图使用堆栈指针来实现堆栈跟踪器; RSP 和 RBP,但我认为调试器使用完全不同的方式来获取返回地址,或者我可能遗漏了一些东西。我可以获取最后一个堆栈帧的返回地址,但我无法获取其他堆栈帧的返回地址,因为我不知道其他堆栈帧的大小,所以我不知道应该从堆栈帧返回多少字节, 获取退货地址。有没有人知道调试器使用哪种方式跟踪堆栈?

1 个答案:

答案 0 :(得分:0)

当代码使用帧指针时,可以跟踪堆栈。在这种情况下,ebp/rbp 用作帧指针,函数以序言开头并以结尾结尾。 一个典型的序言看起来像这样:

push    rbp       ; save previous frame pointer
mov     rbp, rsp  ; initialize this functions frame pointer

典型的结语如下所示:

mov     rsp, rbp  ; restore the value of rsp
pop     rbp       ; restore previous frame pointer value from stack
retn

因此在函数中的每个位置 rbp 都指向保存前一帧指针的堆栈位置,而 rbp+8 包含保存的返回地址。 要获得被调用的函数,调试器应该读取 [rbp+8] 值并找到该地址所属的函数。这可以通过在调试符号中搜索来完成。 接下来它应该读取 [rbp] 值以获取调用者函数的帧指针。继续这个过程,直到找到一个顶级函数。这通常是启动线程的系统库函数。