How to debug and find out who signaled my event in kernel

Hi ,

There is an event created in the user mode and passed through IOCTL to kernel and from kernel it will be signaled.
In the user it waiting on the event to be signaled then do some job.

My problem is i am not able to find who is signalling this event in kernel like in which function in the driver . Is there a way to debug in windbg to break when this event is signalled ?

Regards
Umer

ba is a very powerful tool for the “who touched my data?” sort of question. Start by reading through this: https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/ba--break-on-access-

Once you know about ba, you’ll discover that the tricky bit is knowing what parameters to pass to it: You need to know exactly which address is modified, and you need to know what size the access is.

If you dump out the contents of a KEVENT, you’ll notice that there’s a bunch of stuff, but (you might have to take my word for it) the most interesting field here is the SignalState member:

typedef struct _DISPATCHER_HEADER {
    . . . a bunch of stuff . . .
    LONG SignalState;
    LIST_ENTRY WaitListHead;
} DISPATCHER_HEADER;

That’s what we want, although there’s so much stuff in there that it’s almost impossible to manually find the offset of SignalState. Fortunately, we don’t have to: just ask windbg to do it for us:

kd> dt -v KEVENT .
   +0x000 Header           : 
      . . . a bunch of stuff . . .
      +0x004 SignalState      : Int4B
      +0x008 WaitListHead     : struct _LIST_ENTRY, 2 elements, 0x10 bytes

Now we know that SignalState is at offset 0x000+0x004 from the start of the structure, and we know it’s a 4Byte integer. That gives us the address and size of the access. So if your KEVENT is at address 0xffffd688899592e0, just use the breakpoint ba w4 (0xffffd688899592e0+4) . The w4 is because it’s a 4-byte integer, and the +4 is because SignalState is 4 bytes into the KEVENT structure.

If everything goes right, you should get a breakpoint immediately after this instruction in nt!KeSetEvent at the callstack where someone signals your event:

kd> ub @rip L1
nt!KeSetEvent+0x72:
fffff806`3fad3e12 c7430401000000  mov     dword ptr [rbx+4],1

It will also break in any other time someone changes the event state, e.g., KeClearEvent or even KeWaitForSingleObject if it’s an auto-reset event. If you don’t like that, you can add an extra bit of logic to skip the breakpoint if the event is being cleared. If rbx+4 was just set to 0, then the event is cleared, so we can modify the breakpoint thusly:

kd> ba w4 (0xffffd688899592e0+4) ".if (dwo(@rbx+4) == 0) { gc }"

which, after breaking in, checks if the dword (aka 4 byte integer) at rbx+4 is equal to zero. If it is, resume execution.

3 Likes

Sigh!

@umer_haris-2 You’re posting in the ADMIN forum.

I’ll move it… but please, be a bit more careful.

Peter

1 Like

@Jeffrey_Tippet thank you for inormation .

@Peter_Viscarola , sorry for that , will take care from next time.