I'm debugging some 32-bit process using windbg kernel debugger. This process calls some syscalls, so I set few breakpoints at kernel functions like nt!NtQuerySystemInformation. So after breakpoint hit, what's the easiest way to trace back from kernel function to place where syscall was called in user-mode process? It's wow64 so call stack doesn't help, this is how it looks like:
[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
I don't want to set breakpoints at usermode modules, have to trace it back from kernel. I've found out that jmp fword ptr [r14]
at the end of wow64cpu!RunSimulatedCode is used to jump back to usermode. However RunSimulatedCode isn't always called, some functions use something else. Moreover, after jumping back to usermode windbg cannot retrieve user mode call stack.