I have simple KMD that monitors process creation, now when process is started my driver receives notification and I want to forward this notify to the ring3 app. I was thinking that the best solution for me would be to somehow register callback procedure from my ring3 app into driver and when ring0 event happens just call that procedure. Is this possible and if so how can I do it. If not, is it then possible to create thread from the driver into ring3 app?
(I dont have much experience with ring0 programming.)
Posted on 2004-11-01 04:16:59 by Mikky
to switch from ring0 to ring3 can only be done with RETF of IRET, because the cpu needs not only CS:EIP, but also a valid ring3 stack. Switching back from ring3 to ring0, on the other hand, can only be done by call gates, interrupts or exceptions.

So this is surely nothing to consider to be used on NT platforms.

But you may take a look at the WMI services, which should provide the means you are looking for.
Posted on 2004-11-01 05:44:18 by japheth
What exactly do you mean by WMI services, any API or other hint?
Also is it possible to send window message from the KMD to ring3 app, such as PostMessage() or something like that?
Posted on 2004-11-01 15:37:38 by Mikky
Hi Mikky,

There are a way to call ring-3 functions in NT drivers without having
to swap contexts. But is a bit complex and error prone.
I know that osronline.com has an article about this, but I don't find where.
The currect way is to use shared events and the DeviceIoControl interface to make communication with your process, or even shared
memory.

Maybe this code help you a bit:
http://66.98.132.48/forum/attachment.php?attachmentid=904

Regards,
Opcode
Posted on 2004-11-01 16:17:54 by Opcode
Hi

There are several ways you could pass info back to user mode, generally through the DeviceIoControl interface as Opcode mentions. Using the METHOD_BUFFERED transfer method and passing whatever info back via Irp.AssociatedIrp.SystemBuffer is probably the most common.

If you need to pass large (but not unlimited) amounts of data, which you probably don't in your case, you can use a shared MDL. This is described in the OSR article, which is in the example I used in the attachment Opcode sneakily dug up ;-) You can also find this article archived by doing a Google search for
"Sharing Memory Between Drivers and Applications"
This should also give you a hit to the MS site and elsewhere giving further info on transfer methods. If you don't like my example, Four-F also uses a shared MDL in his KMD tut #9.

As an aside/warning about shared MDL's, I say that you can pass large amounts of data back to user mode, but there is a limit. I've used this type of shared MDL several times to successfully create a contiguous buffer of up to several pages (say roughly 8000h bytes). But I've also seen what appears to be a buffer overflow of some sort with larger allocations, where the .data section of my user app has been overwritten with garbage. It may have something to do with fragmentation of the shared pool over time, so take note.


If all you need is a signal, a more direct approach might be to use a shared Event between user and kernel mode, I posted a bit of code using IoCreateNotificationEvent that might help, somewhere in this post. I can give a more complete example if necessary.
http://www.asmcommunity.net/board/viewtopic.php?t=15479&highlight=notificationevent&sid=183ddac91fad5fe1dd28fdf5b2204ce0


Finally, as you first mentioned about registering a callback procedure, this is what the article at Codeproject does by using PsSetCreateProcessNotifyRoutine. However you might not be using this method.
Detecting Windows NT/2K process execution
http://codeproject.com/threads/procmon.asp?df=100&forumid=3523&exp=0&select=801985


EDIT: I just remembered this article on how to notify user-mode applications asynchronously from kernel mode:
http://www.microsoft.com/msj/0799/nerd/nerd0799.aspx

Cheers,
Kayaker
Posted on 2004-11-01 21:43:28 by Kayaker