kb对64位进程有什么作用?

时间:2014-09-09 09:07:21

标签: debugging 64-bit windbg stack-trace

我最近在分析一个callstack时犯了一个错误,因为我没想到应用程序是64位的。我使用WinDbg命令kb来显示传递给方法的callstack和参数。

在64位时,参数不通过堆栈传递,而是通过寄存器(RCX,RDX,R8和R9)传递。似乎WinDbg没有或没有完全实现这一点。部分我想这几乎是不可能的,因为寄存器值可能同时发生了变化。

但是,WinDbg帮助仍将kb列为User-Mode, x64 Processor下的有效命令。因此我的问题是:

对于64位用户模式进程,kb显示什么?何时/如何输出有用?

2 个答案:

答案 0 :(得分:6)

" Args to Child"在WinDbg中以kb和kv显示的输出一直是非常可疑的,即使在x86上,这些列也不一定显示函数的参数。

在x86上," Args to Child"只是[EBP + 0x08],[EBP + 0x0C]和[EBP + 0x10](kv显示四个参数,因此最后一列是[EBP + 0x14])。这些只是函数的参数:

  1. 该功能使用EBP框架
  2. 该函数具有堆栈传递的参数(取决于调用约定)
  3. 优化工具没有重复使用这些位置
  4. 在x64上,正如您所注意到的,该函数的前四个参数通过寄存器传递。但是,作为调用约定的一部分,调用者需要分配" Home" (或" Spill")每个参数的堆栈空间。即使被调用的函数少于四个参数,此空间也始终分配。然后,被调用的函数可以自由选择使用此Home Space,它可以:

    1. 忽略它
    2. 保存非易失性寄存器
    3. "首页"寄存器将参数传递到堆栈
    4. kb和kv输出按顺序显示Home Space(RCX Home,RDX Home,R8 Home,R9 Home)。最常见的是这个空间将用于上面的1或2,因此它实际上与传入的参数没有任何关系。但是,在Debug构建中,编译器会立即对传入的参数进行Homes操作,以便更轻松地进行调试。

      例如,这里是一个函数的序言,其中两个参数编译为Debug。请注意参数的归位作为第一条指令:

      0:000> u DriverEntry
      mov     qword ptr [rsp+10h],rdx
      mov     qword ptr [rsp+8],rcx
      push    rdi
      sub     rsp,0C0h
      

      相同的代码编译Release,使用Home Space进行非易失性寄存器保存:

      0:000> u DriverEntry
      mov     qword ptr [rsp+8],rbx
      mov     qword ptr [rsp+10h],rdi
      push    rbp
      lea     rbp,[rsp-57h]
      sub     rsp,0B0h
      

      这意味着在获取函数的参数方面,Home Space通常是无用的。但是,它仍然可以用作调试辅助来重建函数入口上的非易失性寄存器值(即我可以通过查看Home Space告诉你上面的RBX或RDI的值)

答案 1 :(得分:3)

kb会列出堆栈返回跟踪以及三个参数,但它是参数传递机制(调用约定),它不会使参数显示为可信。您必须阅读更多@ http://www.codemachine.com/article_x64deepdive.html

dv,所有其他变种dv / v等都可能显示垃圾值。只有在__this调用的情况下,我们可以使用rcx作为this指针但是我们必须反汇编并确保指针没有备份到其他地方然后重用。除非我们有归属参数,否则拆卸是要走的路。