This is fairly trivial in hindsight, but I didn't find the help of any use when I was stuck debugging an user mode app through remote kd. BTW, I hope you're familiar with console debuggers because there doesn't seem to be a way to leverage any of windbg's GUI features over a remote kd session.
Once you've got kd running and connected to the target, make sure the usermode app is running. Break into KD to quickly get the process id in hex:
nt!RtlpBreakWithStatusInstruction: 81881760 cc int 3 1: kd> !process 0 0 notepad.exe PROCESS 84b127f8 SessionId: 1 Cid: 0ff0 Peb: 7ffde000 ParentCid: 09a4 DirBase: 6b25c280 ObjectTable: 9b80e530 HandleCount: 170. Image: notepad.exe
Cid is the process id. Next we will break inside the process context of notepad to set a local breakpoint. This can be acomplished fairly easily using the command
1: kd> !bpid 0ff0 Finding wininit.exe (1)... Finding winlogon.exe (1)... Waiting for winlogon.exe to break. This can take a couple of minutes... Break instruction exception - code 80000003 (first chance) Break into process ff0 set. The next break should be in the desired process. Break instruction exception - code 80000003 (first chance) ntdll!DbgBreakPoint: 001b:77b82ea8 cc int 3 0: kd> !process PROCESS 84b127f8 SessionId: 1 Cid: 0ff0 Peb: 7ffde000 ParentCid: 09a4 DirBase: 6b25c280 ObjectTable: 9b80e530 HandleCount: 170. Image: notepad.exe VadRoot 86164120 Vads 121 Clone 0 Private 1029. Modified 2564. Locked 0. DeviceMap 92071bf8 Token 9e30cca0 ElapsedTime 00:15:00.188 UserTime 00:00:00.093 KernelTime 00:00:00.124 QuotaPoolUsage[PagedPool] 144744 QuotaPoolUsage[NonPagedPool] 5808 Working Set Sizes (now,min,max) (3327, 50, 345) (13308KB, 200KB, 1380KB) PeakWorkingSetSize 3704 VirtualSize 77 Mb PeakVirtualSize 106 Mb PageFaultCount 5972 MemoryPriority BACKGROUND BasePriority 8 CommitCharge 1511 THREAD 849ddd78 Cid 0ff0.0f58 Teb: 7ffdf000 Win32Thread: fe577e98 WAIT: (WrUserRequest) UserMode Non-Alertable 84b01350 SynchronizationEvent THREAD 849dfa90 Cid 0ff0.0f88 Teb: 7ffdc000 Win32Thread: 00000000 WAIT: (WrQueue) UserMode Non-Alertable 849e7cf0 QueueObject THREAD 84a41ac0 Cid 0ff0.083c Teb: 7ffdb000 Win32Thread: 00000000 WAIT: (DelayExecution) UserMode Non-Alertable 84a41b48 NotificationTimer THREAD 849957d0 Cid 0ff0.0b10 Teb: 7ffdd000 Win32Thread: 00000000 RUNNING on processor 0
Now after confirming we're in the right process context, we can now proceed to set breakpoints.
Another way to do this is to use
.process /i 84b127f8 to break into notepad's context and then set the breakpoints.