The first remotely useful thing we are going to do with our newly acquired knowledge about device driver development is to register a callback for whenever a process is created, and output the information on the parent and child processes. (Frankly, this can be accomplished quite as easily using the WMI Win32_ProcessStartTrace event class, but bear with me here.)
The PsSetCreateProcessNotifyRoutine function is a service provided by the process manager in the executive, which allows us to register a callback for when processes are created. This can be useful in the context of a security product, auditing software, or malicious code. (Note that this is a prime example of an API that is not accessible from user mode.)
So here’s what we’re going to do—we will add two new IOCTLs (IOCTL_HOOK and IOCTL_UNHOOK) to our driver’s interface. The “hook” IOCTL will register the callback and the “unhook” IOCTL will unregister it so that the driver can be unloaded safely. Consider the unfortunate case when a driver is unloaded but the process manager attempts to call a function in it!
Without further ado, here’s the code for the new IOCTLs and the DriverProcessNotifyRoutine:
#define IOCTL_HOOK (ULONG) CTL_CODE( FILE_DEVICE_HELLOWORLD, 0x01, METHOD_BUFFERED, FILE_ANY_ACCESS )
#define IOCTL_UNHOOK (ULONG) CTL_CODE( FILE_DEVICE_HELLOWORLD, 0x02, METHOD_BUFFERED, FILE_ANY_ACCESS )
IN HANDLE ParentId,
IN HANDLE ProcessId,
IN BOOLEAN Create)
DbgPrint("Process %d created process %d\n",
DbgPrint("Process %d has ended\n",
/* in DriverDispatch */
As always, compile, deploy and register the driver on the target system, and then create and kill a few processes while watching the DebugView output.
In the next episode: using Direct Kernel Object Manipulation (DKOM) to hide a process from tools like Task Manager.