如何显示当前内核模式上下文的用户模式堆栈?
How to display user-mode stack of current kernel-mode context?
假设我在系统调用或从用户模式启动的 IOCTL 期间进入了内核调试器。我想看看完整的堆栈——从用户模式开始,然后切换到内核模式。
我知道一些作品:
- 我可以列出
!process 0 0
的所有进程,并查看其中的线程。或者,使用 !dml_proc
. 打瞌睡
- 如果我知道当前的用户模式线程,我可以切换到它并查看整个开始:
!thread <usermode_thread> 15
.
但是我该如何将它们联系在一起呢?具体来说:
- 我怎么知道当前的用户模式线程?
- 我可以通过编程方式检索它,这样我就可以得到一行
!thread <some_magic> 15
吗?
WinDbg 在伪寄存器 @$thread
中跟踪用户模式和内核模式中的当前线程,并在伪寄存器 @$proc
.
中跟踪当前进程
查看当前线程堆栈:!thread @$thread 0x1f
。
这是完整的堆栈,从 _RtlUserThreadStart
到最后一个 api 如果线程放弃执行,通常是 SwapContext()
。
查看当前进程及其所有线程的堆栈:!process @$proc 0x1f
这是两个命令输出的完整当前线程堆栈
!proc @$proc 1f 以及 !thread @$thread 1f
第一个将打印特定进程的所有线程的调用堆栈
第二个将打印特定当前 运行 线程的调用堆栈
您可以在 Threads 输出的第一行看到 运行 的等待状态
:\>head -2 sample.txt
kd> !process @$proc 0x17
PROCESS 84efc748 SessionId: 0 Cid: 0470 Peb: 7ffdc000 ParentCid: 01e8
:\>wc -l sample.txt
517 sample.txt
:\>grep THREAD sample.txt
THREAD 84efcb60 Cid 0470.0474 Teb: 7ffdf000 Win32Thread: ff9f1c00 WAIT: (UserRequest) UserMode Non-Alertable
THREAD 84f166b8 Cid 0470.0478 Teb: 7ffde000 Win32Thread: 00000000 WAIT: (UserRequest) UserMode Alertable
THREAD 85303820 Cid 0470.0490 Teb: 7ffd9000 Win32Thread: 00000000 WAIT: (UserRequest) UserMode Non-Alertable
THREAD 85307bb0 Cid 0470.0494 Teb: 7ffd8000 Win32Thread: 00000000 WAIT: (UserRequest) UserMode Non-Alertable
THREAD 853064e8 Cid 0470.0498 Teb: 7ffd7000 Win32Thread: 00000000 WAIT: (UserRequest) UserMode Non-Alertable
THREAD 84e71d48 Cid 0470.049c Teb: 7ffd6000 Win32Thread: 00000000 WAIT: (UserRequest) UserMode Non-Alertable
THREAD 8530eb80 Cid 0470.04a8 Teb: 7ffda000 Win32Thread: 00000000 WAIT: (UserRequest) UserMode Non-Alertable
THREAD 85371030 Cid 0470.0538 Teb: 7ffd4000 Win32Thread: 00000000 WAIT: (WrQueue) UserMode Alertable
THREAD 8538ea08 Cid 0470.0588 Teb: 7ffad000 Win32Thread: 00000000 WAIT: (UserRequest) UserMode Non-Alertable
THREAD 853d6310 Cid 0470.05a4 Teb: 7ffaa000 Win32Thread: 00000000 WAIT: (WrQueue) UserMode Alertable
THREAD 8540fa78 Cid 0470.06bc Teb: 7ffaf000 Win32Thread: 00000000 WAIT: (UserRequest) UserMode Non-Alertable
THREAD 84173030 Cid 0470.0740 Teb: 7ffa6000 Win32Thread: 00000000 WAIT: (WrQueue) UserMode Non-Alertable
THREAD 84f77990 Cid 0470.0174 Teb: 7ffdd000 Win32Thread: 00000000 RUNNING on processor 0
THREAD 84f77990 Cid 0470.0174 Teb: 7ffdd000 Win32Thread: 00000000 RUNNING on processor 0
:\>grep !thread sample.txt
kd> !thread @$thread 1f
:\>grep -A 2 !thread sample.txt
kd> !thread @$thread 1f
THREAD 84f77990 Cid 0470.0174 Teb: 7ffdd000 Win32Thread: 00000000 RUNNING on processor 0
Not impersonating
:\>
在 NtDeviceIoControlFile
上中断的当前 运行 线程的完整调用堆栈
kd> !thread @$thread 1f
THREAD 84f77990 Cid 0470.0174 Teb: 7ffdd000 Win32Thread: 00000000 RUNNING on processor 0
Not impersonating
DeviceMap 919b0008
Owning Process 84efc748 Image: svchost.exe
Attached Process N/A Image: N/A
Wait Start TickCount 49461 Ticks: 1 (0:00:00:00.010)
Context Switch Count 659 IdealProcessor: 0
UserTime 00:00:00.040
KernelTime 00:00:03.314
Win32 Start Address ntdll!TppWorkerThread (0x770403e7)
Stack Init 8c0e3fd0 Current 8c0e3bf8 Base 8c0e4000 Limit 8c0e1000 Call 00000000
Priority 8 BasePriority 8 PriorityDecrement 0 IoPriority 2 PagePriority 5
ChildEBP RetAddr
8c0e3d04 8283787a nt!NtDeviceIoControlFile
8c0e3d04 770570b4 nt!KiFastCallEntry+0x12a (FPO: [0,3] TrapFrame @ 8c0e3d34)
0292f518 77055864 ntdll!KiFastSystemCallRet (FPO: [0,0,0])
0292f51c 76dd14c9 ntdll!ZwDeviceIoControlFile+0xc (FPO: [10,0,0])
0292f560 76dd15f9 NSI!NsiIoctl+0x5d (FPO: [Non-Fpo])
0292f584 76dd15c7 NSI!NsiEnumerateObjectsAllParametersEx+0x23 (FPO: [Non-Fpo])
0292f5d0 718718e2 NSI!NsiEnumerateObjectsAllParameters+0x79 (FPO: [Non-Fpo])
0292f620 71871858 ncsi!CNcsiNsiTable::AllocateAndGetTable+0x51 (FPO: [Non-Fpo])
0292f644 718717c6 ncsi!UpdateInterfaceStatsByFamily+0xb0 (FPO: [Non-Fpo])
0292f664 71871e49 ncsi!UpdateInterfaceStats+0x26 (FPO: [Non-Fpo])
0292f694 71871d4e ncsi!PassiveProbe+0x6f (FPO: [Non-Fpo])
0292f6f4 718715d5 ncsi!NcsiUpdateConnectivityStatusList+0x4a1 (FPO: [Non-Fpo])
0292f6f8 7704112c ncsi!NcsiUpdateConnectivityStatusListTimer+0x5 (FPO: [3,0,0])
0292f71c 77040842 ntdll!TppTimerpExecuteCallback+0x10f (FPO: [Non-Fpo])
0292f87c 756f3c45 ntdll!TppWorkerThread+0x572 (FPO: [Non-Fpo])
0292f888 770737f5 kernel32!BaseThreadInitThunk+0xe (FPO: [Non-Fpo])
0292f8c8 770737c8 ntdll!__RtlUserThreadStart+0x70 (FPO: [Non-Fpo])
0292f8e0 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])
假设我在系统调用或从用户模式启动的 IOCTL 期间进入了内核调试器。我想看看完整的堆栈——从用户模式开始,然后切换到内核模式。
我知道一些作品:
- 我可以列出
!process 0 0
的所有进程,并查看其中的线程。或者,使用!dml_proc
. 打瞌睡
- 如果我知道当前的用户模式线程,我可以切换到它并查看整个开始:
!thread <usermode_thread> 15
.
但是我该如何将它们联系在一起呢?具体来说:
- 我怎么知道当前的用户模式线程?
- 我可以通过编程方式检索它,这样我就可以得到一行
!thread <some_magic> 15
吗?
WinDbg 在伪寄存器 @$thread
中跟踪用户模式和内核模式中的当前线程,并在伪寄存器 @$proc
.
查看当前线程堆栈:!thread @$thread 0x1f
。
这是完整的堆栈,从 _RtlUserThreadStart
到最后一个 api 如果线程放弃执行,通常是 SwapContext()
。
查看当前进程及其所有线程的堆栈:!process @$proc 0x1f
这是两个命令输出的完整当前线程堆栈
!proc @$proc 1f 以及 !thread @$thread 1f
第一个将打印特定进程的所有线程的调用堆栈
第二个将打印特定当前 运行 线程的调用堆栈
您可以在 Threads 输出的第一行看到 运行 的等待状态
:\>head -2 sample.txt
kd> !process @$proc 0x17
PROCESS 84efc748 SessionId: 0 Cid: 0470 Peb: 7ffdc000 ParentCid: 01e8
:\>wc -l sample.txt
517 sample.txt
:\>grep THREAD sample.txt
THREAD 84efcb60 Cid 0470.0474 Teb: 7ffdf000 Win32Thread: ff9f1c00 WAIT: (UserRequest) UserMode Non-Alertable
THREAD 84f166b8 Cid 0470.0478 Teb: 7ffde000 Win32Thread: 00000000 WAIT: (UserRequest) UserMode Alertable
THREAD 85303820 Cid 0470.0490 Teb: 7ffd9000 Win32Thread: 00000000 WAIT: (UserRequest) UserMode Non-Alertable
THREAD 85307bb0 Cid 0470.0494 Teb: 7ffd8000 Win32Thread: 00000000 WAIT: (UserRequest) UserMode Non-Alertable
THREAD 853064e8 Cid 0470.0498 Teb: 7ffd7000 Win32Thread: 00000000 WAIT: (UserRequest) UserMode Non-Alertable
THREAD 84e71d48 Cid 0470.049c Teb: 7ffd6000 Win32Thread: 00000000 WAIT: (UserRequest) UserMode Non-Alertable
THREAD 8530eb80 Cid 0470.04a8 Teb: 7ffda000 Win32Thread: 00000000 WAIT: (UserRequest) UserMode Non-Alertable
THREAD 85371030 Cid 0470.0538 Teb: 7ffd4000 Win32Thread: 00000000 WAIT: (WrQueue) UserMode Alertable
THREAD 8538ea08 Cid 0470.0588 Teb: 7ffad000 Win32Thread: 00000000 WAIT: (UserRequest) UserMode Non-Alertable
THREAD 853d6310 Cid 0470.05a4 Teb: 7ffaa000 Win32Thread: 00000000 WAIT: (WrQueue) UserMode Alertable
THREAD 8540fa78 Cid 0470.06bc Teb: 7ffaf000 Win32Thread: 00000000 WAIT: (UserRequest) UserMode Non-Alertable
THREAD 84173030 Cid 0470.0740 Teb: 7ffa6000 Win32Thread: 00000000 WAIT: (WrQueue) UserMode Non-Alertable
THREAD 84f77990 Cid 0470.0174 Teb: 7ffdd000 Win32Thread: 00000000 RUNNING on processor 0
THREAD 84f77990 Cid 0470.0174 Teb: 7ffdd000 Win32Thread: 00000000 RUNNING on processor 0
:\>grep !thread sample.txt
kd> !thread @$thread 1f
:\>grep -A 2 !thread sample.txt
kd> !thread @$thread 1f
THREAD 84f77990 Cid 0470.0174 Teb: 7ffdd000 Win32Thread: 00000000 RUNNING on processor 0
Not impersonating
:\>
在 NtDeviceIoControlFile
上中断的当前 运行 线程的完整调用堆栈kd> !thread @$thread 1f
THREAD 84f77990 Cid 0470.0174 Teb: 7ffdd000 Win32Thread: 00000000 RUNNING on processor 0
Not impersonating
DeviceMap 919b0008
Owning Process 84efc748 Image: svchost.exe
Attached Process N/A Image: N/A
Wait Start TickCount 49461 Ticks: 1 (0:00:00:00.010)
Context Switch Count 659 IdealProcessor: 0
UserTime 00:00:00.040
KernelTime 00:00:03.314
Win32 Start Address ntdll!TppWorkerThread (0x770403e7)
Stack Init 8c0e3fd0 Current 8c0e3bf8 Base 8c0e4000 Limit 8c0e1000 Call 00000000
Priority 8 BasePriority 8 PriorityDecrement 0 IoPriority 2 PagePriority 5
ChildEBP RetAddr
8c0e3d04 8283787a nt!NtDeviceIoControlFile
8c0e3d04 770570b4 nt!KiFastCallEntry+0x12a (FPO: [0,3] TrapFrame @ 8c0e3d34)
0292f518 77055864 ntdll!KiFastSystemCallRet (FPO: [0,0,0])
0292f51c 76dd14c9 ntdll!ZwDeviceIoControlFile+0xc (FPO: [10,0,0])
0292f560 76dd15f9 NSI!NsiIoctl+0x5d (FPO: [Non-Fpo])
0292f584 76dd15c7 NSI!NsiEnumerateObjectsAllParametersEx+0x23 (FPO: [Non-Fpo])
0292f5d0 718718e2 NSI!NsiEnumerateObjectsAllParameters+0x79 (FPO: [Non-Fpo])
0292f620 71871858 ncsi!CNcsiNsiTable::AllocateAndGetTable+0x51 (FPO: [Non-Fpo])
0292f644 718717c6 ncsi!UpdateInterfaceStatsByFamily+0xb0 (FPO: [Non-Fpo])
0292f664 71871e49 ncsi!UpdateInterfaceStats+0x26 (FPO: [Non-Fpo])
0292f694 71871d4e ncsi!PassiveProbe+0x6f (FPO: [Non-Fpo])
0292f6f4 718715d5 ncsi!NcsiUpdateConnectivityStatusList+0x4a1 (FPO: [Non-Fpo])
0292f6f8 7704112c ncsi!NcsiUpdateConnectivityStatusListTimer+0x5 (FPO: [3,0,0])
0292f71c 77040842 ntdll!TppTimerpExecuteCallback+0x10f (FPO: [Non-Fpo])
0292f87c 756f3c45 ntdll!TppWorkerThread+0x572 (FPO: [Non-Fpo])
0292f888 770737f5 kernel32!BaseThreadInitThunk+0xe (FPO: [Non-Fpo])
0292f8c8 770737c8 ntdll!__RtlUserThreadStart+0x70 (FPO: [Non-Fpo])
0292f8e0 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])