Windows shared services allow us to run system services together in a single service by having multiple DLLs run in a single process called Svchost. This allows Windows to have many services to run with the overhead of a single process. You can find more information about shared services here and here. I like to do a lot of my user mode debugging from a kernel mode debugger. I can just attach to a Hyper-V VM though a virtual serial port and all my tools are available to me without having to set up a user mode debugger on the target, plus if my application calls into kernel mode I’m all set. The Svchost process won’t load the DLL until it’s time to start the service, so it can be tricky to set the correct breakpoint to catch the service starting up. This is complicated by the fact that the dll entry point will usually be <module>!ServiceMain, however this is not necessarily the case. We can leverage the fact that svchost.exe exists in the same shared memory across all the Svchost processes, and a change to this shared memory will affect all of the svchost process. When you set a user mode breakpoint from a kernel mode debugger the debugger changes the user mode code by inserting an int 3 (the debugger changes the code back when it is executed). We can take advantage of this functionality to set one breakpoint that will fire from any svchost process. If we can get past the Svchost process loading the service dll, we can find the host process main function or any other function we want to set a breakpoint on. First, find the process address of any Svchost. I’m just showing the first of a long list of processes: kd> !process 0 0 svchost.exe
PROCESS fffffa80098c5970
SessionId: 0 Cid: 0270 Peb: 7fffffd8000 ParentCid: 0204
DirBase: 35986000 ObjectTable: fffff8a001115b20 HandleCount: 343.
Image: svchost.exe Now let’s get into the context of this Svchost (it doesn’t matter which one) and set a breakpoint. .process –i sets an invasive breakpoint so we can get into the active context of the process. kd> .process -i fffffa80098c5970
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. Then go the debugger to enter the active process. Read more: NTDebugging
PROCESS fffffa80098c5970
SessionId: 0 Cid: 0270 Peb: 7fffffd8000 ParentCid: 0204
DirBase: 35986000 ObjectTable: fffff8a001115b20 HandleCount: 343.
Image: svchost.exe Now let’s get into the context of this Svchost (it doesn’t matter which one) and set a breakpoint. .process –i sets an invasive breakpoint so we can get into the active context of the process. kd> .process -i fffffa80098c5970
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. Then go the debugger to enter the active process. Read more: NTDebugging