确定ZwWaitForMultipleObjects正在等待哪些对象

7

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

> ~2k
ChildEBP RetAddr  
00d2fcc8 7d4e27dc ntdll_7d600000!ZwWaitForMultipleObjects+0x15

或者是同类的SingleObject。

当将对象句柄传递给ZwWaitForMultipleObjects时,我认为可以通过以下方式推断出使用的对象:

!do <address>

有了正确的地址——但我不知道如何构造正确的地址。我假设我需要一些从ChildEBP的偏移量?


2
!do 用于托管对象 (.NET),但 ZwWFMO 很可能在等待本机句柄。使用 ~2kb 获取堆栈上方的良好文档化的 Win32 帧(希望是 WaitForMultipleObjects)及其前三个参数。您将需要取消引用第二个参数以获取句柄。当您获得句柄值时,请使用 !handle <handle> f 获取有关特定句柄的信息。如果您需要帮助挖掘句柄值,请将输出发布到 ~2kb - Marc Sherman
1个回答

14

请尝试以下步骤:

  1. 使用“~2s”命令切换到线程#2的上下文环境(此步骤可以视为多余,但我发现在正确的线程上下文中操作更容易)

  2. 使用“kb”命令显示线程的调用堆栈,包括每个函数的前三个参数。您将获得如下内容:

    ChildEBP RetAddr  Args to Child 
    0dc7fa30 768b0962 00000004 0dc7fa80 00000001 ntdll!ZwWaitForMultipleObjects+0x15
    0dc7facc 73c61339 0dc7fa80 0dc7fb14 00000000 KERNELBASE!WaitForMultipleObjectsEx+0x100
    
  3. 以上面的调用堆栈为例,您可以看到传递给ZwWaitForMultipleObjects的句柄数为4(第一个参数的值)。句柄数组的地址是第二个参数。在上述示例中,地址为0dc7fa80

  4. 使用“dd”命令显示句柄数组的内容。在上面的调用堆栈中,使用“dd 0dc7fa80”会得到如下内容:

    0dc7fa80  000001f0 000001f8 0000020c 000001ec
    0dc7fa90  73a53c1b 00000000 0d462f70 00000001
    0dc7faa0  0cf7afe0 00000003 0dc7fac8 00000004
    

    假设这是一个32位进程,则句柄是前四个DWORD:“1f0”,“1f8”,“20c”和“1ec”。

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

如果您怀疑句柄是从托管代码中传递过来的,那么您需要加载SOS或PSSCOR,并使用!ClrStack命令显示托管调用堆栈的详细信息。

太好了,谢谢Aeham(以及Marc的评论)。这很完美。 - Tim Barrass

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接