Hello.

This is the first part in the series, “Writing Windows Kernel-Mode Drivers for Fun and Profit”.

This series will help you understand and write KMDF drivers, and maybe exploit them in red team engagements or DoS your own/or others’ system/VM if you messed up.

A basic DriverEntry routine definition looks something like this ->

1
2
3
4
5
NTSTATUS DriverEntry (_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath) {
    UNREFERENCED_PARAMETER (DriverObject);
    UNREFERNECED_PARAMETER (RegistryPath);
    return STATUS_SUCCESS;
}

While this may look intimidating at first, brushing up on OS Concepts, Windows Internals, C/C++ knowledge, and some persistence will help you better understand stuff that’s about to come.

We’ll be dealing mostly with Kernel-Mode or KMDF drivers (explained later), so unless explicitly stated, a driver means a KMDF driver.

For further details, I recommend Windows Internals by Pavel Yosifovich, Alex Ionescu, Mark E. Russinovich, David A. Solomon and Windows Kernel Programming by Pavel Yosifovich. This post and the upcoming ones took inspiration from their work.

By the way, DriverEntry is just the main of the driver.

Drivers… Who dis?

Drivers are Structured, High Privilege Deployable Kernel modules operating in Ring 0 processor privilege level (only kernel-mode drivers), same as the kernel. Initially, Ring 1 and Ring 2 were reserved for drivers but nobody uses them anymore.

Drivers provide a way to interact with (in most cases) hardware devices. These are called Hardware Drivers. On the contrary, software components that execute kernel-level privilege tasks such as file creation, are classified under Software Drivers.

To write drivers, you need to follow a set of guidelines, conventions, and structures, all these together combine to form a Driver Framework. Two of these exist -> Windows Driver Model (WDM) and Windows Driver Foundation (WDF).

WDM vs WDF

  • Simply put, WDM is an older, more complex-to-work-with framework to write drivers. Ideal for writing File Systems or File System Filter drivers, WDM provides greater control over kernel objects and is hard to write, debug, and maintain.

    WDM objects are system-wide objects accessible to drivers and are referenced by pointers. A driver that corrupts a WDM object corrupts the entire system. WDM drivers are trusted kernel components, hence OS does fewer checks to validate data.

    From a security perspective, leveraging a framework that provides higher control than WDF, would enable more stealth during offensive engagements.

  • WDF is a new, easier-to-work-with framework that abstracts a lot of details of WDM. It supports a coherent object model in which objects are invisible to drivers.

    Corrupting a WDF Driver is not only more difficult - as the framework evaluates data being supplied - but also causes system-wide problems less often.

    Apart from these, there are many more subtle differences such as how both handle I/O requests. For eg. In a WDM driver, I/O dispatch routines map to particular IRP codes whereas, in a WDF driver, the framework registers its own dispatch routines, follows some identical steps to WDM, and then invokes the driver’s event callback functions.

    Event callback functions do a more specific task than the general I/O dispatch routines of WDM.

Regardless of details, the bottom line is, WDM is complex and much harder to work with while WDF is easier to understand, the tradeoff being the abstraction.

Requirements

There are some tools and methodologies that are recommended while working with drivers.

To build and deploy drivers you require the Windows Software Development Kit (SDK), Windows Driver Kit (WDK), and Visual Studio 2022 (the latest as of this writing). You can find them here and Visual Studio here.

Make sure SDK and WDK versions match, this is important.

Additionally, you’d require a Visual Studio extension, “Windows Driver Kit”. That should be automatically installed if WDK is configured correctly.

To test drivers, you’ll need a Windows Virtual Machine, with Windows SDK and WDK installed.

SysInternals Tools is a must.

Final Thoughts

Driver Development is not something you do regularly unless you have to.

The purpose is to understand Windows internals and drivers to build anything from Anti-Virus Filter Drivers to Rootkits. Knowing Driver Development also develops Kernel Debugging skills which are great if you are interested in Windows vulnerability research.

In Part 2, you’ll learn the Advanced Windows Internals concepts required to get started with drivers.

Stay Tuned.

Tx0actical. Out.