从系统调用获取返回地址

逆向工程 视窗 调试 风袋 核心
2021-06-22 02:32:13

我正在使用 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 无法检索用户模式调用堆栈。

1个回答

syscall 指令总是在 long 模式下调用,由 64 位ntdllntdll在 wow64 进程中有两个),因此返回到用户模式应该在那里。jmp fword ptr [r14]指令从 x64跳转回x86代码。

在 WinDbg 中处理混合模式堆栈时, wow64ext 扩展很有用,例如:

!load wow64ext
!wow64exts.info
!wow64exts.k