Windbg 确定ZwWaitForMultipleObjects正在等待哪些对象

Windbg 确定ZwWaitForMultipleObjects正在等待哪些对象,windbg,Windbg,查看windbg中的崩溃转储,我可以看到当前所有线程都在 > ~2k ChildEBP RetAddr 00d2fcc8 7d4e27dc ntdll_7d600000!ZwWaitForMultipleObjects+0x15 或相同的单一对象变体 当要等待的对象的句柄传递给ZwWaitForMultipleObjects时,我假设我可以计算出它使用的变量是哪个对象 !do <address> !做 用正确的地址——但我不知道如何构造正确的地址。我假设我需要一些与C

查看windbg中的崩溃转储,我可以看到当前所有线程都在

> ~2k
ChildEBP RetAddr  
00d2fcc8 7d4e27dc ntdll_7d600000!ZwWaitForMultipleObjects+0x15
或相同的单一对象变体

当要等待的对象的句柄传递给ZwWaitForMultipleObjects时,我假设我可以计算出它使用的变量是哪个对象

!do <address>
!做
用正确的地址——但我不知道如何构造正确的地址。我假设我需要一些与ChildEBP的偏移量?

尝试以下步骤:

  • 使用“~2s”命令将上下文切换到线程#2(这个步骤可以说是多余的,但我发现在正确的线程上下文中更容易操作)

  • 使用“kb”命令显示线程的调用堆栈,包括每个函数的前三个参数。您将得到如下结果:

    ChildEBP RetAddr Args to Child 0dc7fa30 768b0962 00000004 0dc7fa80 00000001 ntdll!ZwWaitForMultipleObjects+0x15 0dc7facc 73c61339 0dc7fa80 0dc7fb14 00000000 KERNELBASE!WaitForMultipleObjectsEx+0x100 0dc7fa80 000001f0 000001f8 0000020c 000001ec 0dc7fa90 73a53c1b 00000000 0d462f70 00000001 0dc7faa0 0cf7afe0 00000003 0dc7fac8 00000004 ChildEBP将参数重新寻址到Child 0dc7fa30 768b0962 0000000 4 0dc7fa80 0000000 1 ntdll!ZwWaitForMultipleObjects+0x15 0dc7facc 73c61339 0dc7fa80 0dc7fb14 00000000内核库!WaitForMultipleObjectsEx+0x100
  • 以上面的调用堆栈为例,可以看到传递给ZwWaitForMultipleObjects的句柄数是4(第一个参数的值)。句柄数组的地址是第二个参数。在上面的示例中,地址是0dc7fa80

  • 使用“dd”命令显示句柄数组的内容。在上述调用堆栈的情况下,使用“dd 0dc7fa80”,它将给出如下内容:

    ChildEBP RetAddr Args to Child 0dc7fa30 768b0962 00000004 0dc7fa80 00000001 ntdll!ZwWaitForMultipleObjects+0x15 0dc7facc 73c61339 0dc7fa80 0dc7fb14 00000000 KERNELBASE!WaitForMultipleObjectsEx+0x100 0dc7fa80 000001f0 000001f8 0000020c 000001ec 0dc7fa90 73a53c1b 00000000 0d462f70 00000001 0dc7faa0 0cf7afe0 00000003 0dc7fac8 00000004 0dc7fa80 000001F0000001F80000020C 000001C 0dc7fa90 73a53c1b 00000000 0d462f70 00000001 0dc7faa0 0CF7AFE00000000 3 0dc7fac8 0000000 4 假设这是一个32位进程,句柄是前四个单独的DWORD:“1f0”、“1f8”、“20c”和“1ec”

  • 您可以使用“!handle”WinDbg扩展查看每个句柄的详细信息,如下所示: !手柄1f0 F F标志将显示有关句柄的更多详细信息,包括其计数和名称(如果有关联)


  • 如果怀疑句柄是从托管代码传入的,则需要加载SOS或PSSCOR并使用!ClrStack命令以显示托管调用堆栈的详细信息。

    !do
    用于托管对象(.NET),但ZwWFMO很可能正在等待本机句柄。使用
    ~2kb
    可以在堆栈的更高层(希望是WaitForMultipleObjects)及其前三个参数中获得一个有良好文档记录的Win32框架。您必须取消第二个参数的引用才能获得句柄。获取句柄值时,请使用
    !句柄f
    获取有关特定句柄的信息。如果您需要有关挖掘句柄值的帮助,请将输出发布到
    ~2kb
    。非常好,谢谢Aeham(和Marc的评论)。太好了。