It is easy and straightforward to debug a user-mode process by a user-mode Windbg. However, for some reason, we may prefer to debug a user-mode process by the kernel-mode Windbg.
Here I have tow examples by using notepad.exe
The first scenario is that, the notepad.exe is already running, and we want to set a breakpoint on it.
Remember! If we want to set a breakpoint on particular process, the current debugging process context must be the context of the process. So the only thing we need to do is to switch to the right process context.
1. we use the !process to find the process context of notepad.exe
1: kd> !process 0 0 notepad.exe PROCESS b75d67e8 SessionId: 1 Cid: 0a30 Peb: 7ffd5000 ParentCid: 08f4
DirBase: 77fdf660 ObjectTable: aad050f0 HandleCount: 77.
Image: notepad.exe
The bolder part is the process context.
2. Now we know the process context and next step is to use .process /i to switch to it
0: kd> .process /i b75d67e8
You need to continue execution (press 'g' ) for the context
to be switched. When the debugger breaks in again, you will be in
the new process context.
3. the Windbg will automatic break again after press 'g', now windbg is in right process context of notepad.exe. the next step is same as usual to reload symbol and and set a breakpoint.
2: kd> .reload /user
Loading User Symbols
2: kd> bp notepad!LoadFile
2: kd> bl
0 e 00862820 0001 (0001) notepad!LoadFile
we successful set a user-mode breakpoint on notepad.exe. and if we open a file by notepad, the windbg will break the process.
The second scenario is to break at the start up of notepad launched by user.
we know it is explorer.exe to create process, we need find somewhere the process is already created but not run. The kernel mode function nt!EtwpTraceLoadImage is good place to do it. This function will be called very time when process load modules.
Remember, the nt!EtwpTraceLoadImage is a kernel mode function which is called by any process. So when windbg is breaking at the function, we need verify the current process name.
if you have private symbols of nt module, you can just look the local windows of windbg, the first item is ImageName。
if you don't have private symbols, use !peb or .process to get know current process name.
after successful break into nt!EtwpTraceLoadImage on notepad.exe, the windbg is in the right process context we want, however, we may still failed to set breakpoint because current is in process initial time and some module may not be loaded into memory. so we must wait to all modules are loaded into memory.
By executing nt!EtwpTraceLoadImage several times, you may find a similar call stack
just set a break point at the return address of ntdll!LdrpInitializeProcess, at that time, all static modules are loaded into memory and we can reload symbols and set breakpoint now.