Search This Blog

Monday, October 8, 2012

WINDBG: Setting breakpoints for user-mode process from kernel mode debugger

When working with kernel debugger, sometimes we may want to set a breakpoint in the user-mode. Can we do it? Yes, we can. :)

So in this post let me show you how to do that using notepad as an example.
First, let us connect to kernel debugger and in my case I use 1394 debugger connection. Once we are connected, look for a process that we want to set a breakpoint for.

0: kd> !process 0 0 notepad.exe
PROCESS fffffa8012256980
    SessionId: 1  Cid: 0990    Peb: 7f72f0bf000  ParentCid: 07ac
    DirBase: 1babb8000  ObjectTable: fffff8a007c7a040  HandleCount:  68.
    Image: notepad.exe


Once we have located the process that we are interested in. Follow these steps.

0: kd> .process /i fffffa8012256980
You need to continue execution (press 'g' <enter>) for the context
to be switched. When the debugger breaks in again, you will be in
the new process context.
0: kd> g
Break instruction exception - code 80000003 (first chance)
nt!DbgBreakPointWithStatus:
fffff802`46e8f930 cc

.process command will set a process context to notepad and '/i' option means that the target process is to be debugged invasively. In other words, once we execute this command, it prompts us to type 'g'. When we type 'g', it will set the target process to be active process and in this context, we can set a user-mode breakpoint.

For instance, let us set a breakpoint at NtCreateFile of ntdll but before we do that, we need to reload the symbols. This will not only reload kernel symbols but it will also reload user-mode symbols which we need to set a breakpoint for.

3: kd> .reload
Connected to Windows 8 9200 x64 target at (Mon Oct  8 18:10:21.107 2012 (UTC - 7:00)), ptr64 TRUE
Loading Kernel Symbols
...............................................................
................................................................
...................
Loading User Symbols
.........................
Loading unloaded module list
......
3: kd> bp /p fffffa8012256980 ntdll!ntcreatefile


Now, let us resume and this time the debugger should be able to break into the user-mode process.

3: kd> g
Breakpoint 3 hit
ntdll!ZwCreateFile:
0033:000007fb`891a30f0 4c8bd1          mov     r10,rcx
1: kd> kcn
 # Call Site
00 ntdll!ZwCreateFile
01 ntdll!LdrpNtCreateFileUnredirected
02 ntdll!LdrpMapResourceFile
03 ntdll!LdrLoadAlternateResourceModuleEx
04 ntdll!LdrpLoadResourceFromAlternativeModule
05 ntdll!LdrpSearchResourceSection_U
06 ntdll!LdrFindResource_U
07 KERNELBASE!FindResourceExW
08 COMDLG32!FindResourceExFallback
09 COMDLG32!FindResourceExMirrorFallback
0a COMDLG32!CFileOpenSave::_GetDialogTemplate
0b COMDLG32!CFileOpenSave::Show
0c notepad!ShowOpenSaveDialog


You can see from the above that the breakpoint was hit and the callstack is actually from the user-mode.
This technique can be used in many different places and one of the place could be when we want to break into certain function of the service process when it was being loaded. I guess that there are probably other places but this will definitely save you from some work of coordinating two different debuggers.

3 comments:

  1. What regarding printing index cards?
    Gary.

    My homepage - Xerox Phaser 8560 Driver

    ReplyDelete
  2. it's very interesting, it works here, thanks, buddy

    ReplyDelete
  3. sometimes I see process context switches automatically. Even after I set process specific BP. Any input would be helpful.

    ReplyDelete