Baby Steps in Windows Device Driver Development: Part 5, Monitoring Processes

July 2, 2011

no comments

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 )

VOID DriverProcessNotifyRoutine(
    IN HANDLE ParentId,
    IN HANDLE ProcessId,
    IN BOOLEAN Create)
{
    if (Create)
    {
        DbgPrint("Process %d created process %d\n",
                 ParentId, ProcessId);
    }
    else
    {
        DbgPrint("Process %d has ended\n",
                 ProcessId);
    }
}

/* in DriverDispatch */
case IOCTL_HOOK:
    PsSetCreateProcessNotifyRoutine(
         DriverProcessNotifyRoutine, FALSE);
    break;
case IOCTL_UNHOOK:
    PsSetCreateProcessNotifyRoutine(
         DriverProcessNotifyRoutine, TRUE);
    break;

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.

Add comment
facebook linkedin twitter email

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*