我正在使用 windbg 内核调试器调试一些 32 位进程。这个过程会调用一些系统调用,所以我在内核函数中设置了一些断点,比如 nt!NtQuerySystemInformation。那么在断点命中后,从内核函数回溯到用户模式进程中调用 syscall 的位置的最简单方法是什么?这是 wow64 所以调用堆栈没有帮助,它是这样的:
[0x0] nt!NtQuerySystemInformation
[0x1] nt!KiSystemServiceExitPico + 0x25e
[0x2] ntdll!NtQuerySystemInformation + 0x14
[0x3] wow64!whNT32QuerySystemInformation + 0x34
[0x4] wow64!whNtQuerySystemInformation + 0xb4
[0x5] wow64!Wow64SystemServiceEx + 0x15a
[0x6] wow64cpu!ServiceNoTurbo + 0xb
[0x7] wow64cpu!BTCpuSimulate + 0x9
[0x8] wow64!RunCpuSimulation + 0xd
[0x9] wow64!Wow64LdrpInitialize + 0x12d
[0xa] ntdll!LdrpInitializeProcess + 0x193e
[0xb] ntdll!_LdrpInitialize + 0x4cd95
[0xc] ntdll!LdrpInitialize + 0x3b
[0xd] ntdll!LdrInitializeThunk + 0xe
我不想在用户模式模块上设置断点,必须从内核追溯到它。我发现jmp fword ptr [r14]在 wow64cpu!RunSimulatedCode 的末尾是用来跳回用户模式的。然而 RunSimulatedCode 并不总是被调用,一些函数使用其他东西。而且,在跳回用户模式后,windbg 无法检索用户模式调用堆栈。