DCSIMG
Baby Steps in Windows Device Driver Development: Part 5, Monitoring Processes - All Your Base Are Belong To Us

All Your Base Are Belong To Us

Mostly .NET internals and other kinds of gory details

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

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.

Comments

No Comments

Leave a Comment

(required) 

(required) 

(optional)

(required) 


Enter the numbers above: