Определение того, какие объекты ZwWaitForMultipleObjects ожидает
Глядя на аварийный дамп в windbg, я вижу, что все текущие потоки остановлены на
> ~2k
ChildEBP RetAddr
00d2fcc8 7d4e27dc ntdll_7d600000!ZwWaitForMultipleObjects+0x15
или SingleObject вариации одинаковы.
Поскольку дескриптор объекта для ожидания передается в ZwWaitForMultipleObjects, я предполагал, что смогу определить, какой объект использует вариант
!do <address>
с правильным адресом - но я не знаю, как построить правильный адрес. Я предполагаю, что мне нужно некоторое смещение от ChildEBP?
1 ответ
Попробуйте эти шаги:
Используйте команду "~2s" для переключения контекста в поток № 2 (этот шаг, возможно, избыточен, но мне легче работать в контексте правильного потока)
Используйте команду "kb" для отображения стека вызовов потока, включая первые три аргумента каждой функции. Вы получите что-то вроде:
ChildEBP RetAddr Args to Child 0dc7fa30 768b0962 00000004 0dc7fa80 00000001 ntdll! ZwWaitForMultipleObjects + 0x15 0dc7facc 73c61339 0dc7fa80 0dc7fb14 00000000 KERNELBASE! WaitForMultipleObjectsEx + 0x100
Взяв приведенный выше стек вызовов в качестве примера, вы можете видеть, что число дескрипторов, передаваемых в ZwWaitForMultipleObjects, равно 4 (значение первого аргумента). Адрес массива handle является вторым аргументом. В приведенном выше примере адрес 0dc7fa80
Используйте команду "dd" для отображения содержимого массива handle. В случае вышеупомянутого стека вызовов используйте "dd 0dc7fa80", который даст что-то вроде:
0dc7fa80 000001f0 000001f8 0000020c 000001ec 0dc7fa90 73a53c1b 00000000 0d462f70 00000001 0dc7faa0 0cf7afe0 00000003 0dc7fac8 00000004
Предполагая, что это 32-битный процесс, дескрипторы - это первые четыре отдельных DWORD: "1f0", "1f8", "20c" и "1ec".
Вы можете увидеть детали каждого дескриптора, используя расширение "! Handle" WinDbg, например так:! Handle 1f0 F Флаг F будет отображать более подробную информацию о дескрипторе, включая его количество и имя (если он связан с ним)
Если вы подозреваете, что дескрипторы были переданы из управляемого кода, вам потребуется загрузить SOS или PSSCOR и использовать команду!ClrStack для отображения сведений об управляемом стеке вызовов.