0

I'm debugging a user-mode process "myprocess.exe" which has a long running operations, constantly doing system calls to kernel mode, how can i break on syscalls, for example: i want to break and examine all ZwCreateEvent calls, that are called from "myprocess.exe" ? If i just do bp nt!ZwCreateEvent i get thousands of breakpoints from across the system, not related to the "myprocess.exe" and it is impbossible to catch ones that are coming from "myprocess.exe"

I know that there are conditional breakpoints, but i don't have a specific parameter to which i can bind myself ( the one with constant known value or string )

Mefdron
  • 1
  • 1
  • `bp /p` to break on a specific process (see [bp](https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/bp--bu--bm--set-breakpoint-) documentation) – Neitsa Apr 24 '23 at 14:22

1 Answers1

2

You can set kernel breakpoints per process using the bp /p command (doc):

/p EProcess (Kernel-mode only) Specifies a process that is associated with this breakpoint. EProcess should be the actual address of the EPROCESS structure, not the PID. The breakpoint is triggered only if it is encountered in the context of this process.

To get the EPROCESS structure (which represents a process object in kernel land), you can issue the !process command:

Example with notepad:

0: kd> !process 0 0 notepad.exe
PROCESS ffffbe8e593d3080
    SessionId: 14  Cid: 74bc    Peb: 2d7c91c000  ParentCid: 8a94
    DirBase: a2faeb002  ObjectTable: ffffa981f4ce3a40  HandleCount: 246.
    Image: notepad.exe

The hexadecimal number right at the top of the output (ffffbe8e593d3080 above) is the address of the EPROCESS structure. If you have more than one process with the same name, you can discriminate between them using the Cid (otherwise known a PID, Process identifier).

Setting a BP:

0: kd> bp /p ffffbe8e593d3080 nt!ZwCreateEvent

Debugging a userland process in kernel mode is sometimes a bit contrived. I'd suggest to debug your process using windbg in user mode and setting a breakpoint at the user / kernel boundary (that is, in ntdll.dll), simply:

0:004> bp ntdll!ZwCreateEvent

Note that in this case (from a user-mode debugger) you're setting a breakpoint in the function that performs the syscall (transitioning to kernel mode):

0:004> u ntdll!ZwCreateEvent
ntdll!NtCreateEvent:
00007ffa`d1d8d950 4c8bd1          mov     r10,rcx
00007ffa`d1d8d953 b848000000      mov     eax,48h
00007ffa`d1d8d958 f604250803fe7f01 test    byte ptr [SharedUserData+0x308 (00000000`7ffe0308)],1
00007ffa`d1d8d960 7503            jne     ntdll!NtCreateEvent+0x15 (00007ffa`d1d8d965)
00007ffa`d1d8d962 0f05            syscall
00007ffa`d1d8d964 c3              ret

Obviously, you won't be able to step in kernel mode from there.

Neitsa
  • 7,693
  • 1
  • 28
  • 45
  • just an aside well most of the times after hitting ntdll!xxxx you can immediately set bp nt!xxxx and do a single step in (t or trace and you will normally be in process context) – blabb Apr 25 '23 at 03:45