A forum for reverse engineering, OS internals and malware analysis 

Ask your beginner questions here.
 #31964  by WhoPMi
 Sat Aug 11, 2018 9:22 pm
Hello, i'm trying to understand a little thing about sending data from kernel mode to user using IOCTL,
basically i want to use a do while to find some datas and while i'm finding them basically i just need to send them at runtime.

This is what i mean:

do{
//find pid of process...
// send this pid to the user mode application using the irp sysbuffer

//search the next pid
}while(//some instructions);

Basically i can't understand how could i do it, i tried to write something but i just obtain a bsod.
If you could explain me the logic behind i'll be rly glad.
Thank you.
 #31969  by Vrtule
 Sun Aug 12, 2018 9:40 am
Hello,

you may find inspiration in keyboard and mouse class drivers (kbdclass.sys, mouclass.sys). You may find their source code in some old WDKs/DDKs (IIRC, DDK 2003 is the right edition).

These drivers store keyborad/mouse events received from the hardware drivers in their buffers. Wne an IRP comes, they fill its output buffer with information from their buffers. If there is nothing to report, the IRP is marked as pending and the driver holds it until a keyboard/mouse event occurrs and is propagated to it.

This means, you need to solve some edge cases:
* there is no IRP ready to receive data,
* there are no data to satisfy the incomming IRP,
* it may be desirable to allow IRP cancellation.

Since the IRP magic may be quite complicated, I personally prefer a simpler solution. I use a semaphore shared between the driver and the application that counts number of messages waiting for the application. The application creates the semaphore and passes it to the driver when a connection between them is being established.

When a new message for the application arrives, the semaphore counter is incremented (which triggers the application into action) and the application sends an IRP (or fast I/O, the means of communication do not matter) to retrieve the message. Because of the semaphore, the application sends IRPs only in case the driver has something for it.

Of course, the driver also handles the case when an IRP comes and there are no messages to be reported. In that case, the IRP is completed with an error status, such as STATUS_NO_MORE_ENTRIES. No advanced IRP magic is required, just a bit of synchronization primitives.