Environment Setup

Configure windows 10 vms for driver development and testing; Basics of kernel driver interactions.

Dev Environment Config

The best methodology for building and testing a driver is using a two-machine setup - one to act as the dev machine (where you will write and build the code) and the other as the test machine (where you will load, run and debug your driver). Because I use Windows as my physical host OS, I typically dev on my host and use a VM for testing. You can use a VM as your dev machine if that is your preference, or if you run another host OS such as Linux or macOS.

Development Machine

The primary tools that you'll need on your dev machine are Visual Studio 2022, the Windows Driver Kit (WDK), and WinDbg. Visual Studio can be downloaded here. Any version, including the free community edition can be used. During installation, select the Desktop development with C++ workload option.

Under Individual components, ensure the latest Windows 10 SDK version is selected (your versions may differ to those shown here).

Then find and select the latest MSVC x64/x86 Spectre-mitigation libs.

Once installation is complete, download and run the WDK installer. At the end of the installation, ensure checkbox for installing the Visual Studio extension is selected before closing the installer window.

This will launch a further VSIX installer which will add new driver project templates to Visual Studio. If it does not, install it manually by browsing to C:\Program Files (x86)\Windows Kits\10\Vsix\VS2022\10.x and double-clicking on WDK.vsix.

The old, "classic" version of WinDbg should already be installed under C:\Program Files (x86)\Windows Kits\10\Debuggers\x64, but a more modern version is available for download here (it's the full release of the WinDbg Preview version found in the Windows Store).

Test Machine

The two most popular methods of exposing kernel debugging from a VM are via KDCOM and KDNET. The former uses a virtual COM port on the VM and the latter a virtual NIC. Microsoft recommend KDNET for its better performance and compatibility between hypervisors. Begin by downloading the standalone Windows 10 SDK installer from here. During setup, uncheck every option except for Debugging Tools.

This will install kdnet under C:\Program Files (x86)\Windows Kits\10\Debuggers\x64. Launch a Command Prompt as a local admin and enable test signing mode. This will allow the VM to load drivers that have not been signed with a valid code-signing certificate.

Next, open regedit (also in an elevated context) and navigate to HKLM\SYSTEM\CurrentControlSet\Control\Session Manager. Create a new Key called Debug Print Filter and within that, a new DWORD value. Give it the name DEFAULT and a value of 8. This will allow Windows to generate kernel debug messages, which are disabled by default.

Finally, enable kernel debugging with kdnet.exe <ip> <port>. Where <ip> is the IP address of your dev machine and <port> is a random port.

C:\Windows\system32>"C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\kdnet.exe" 192.168.0.154 50000

Enabling network debugging on Network debugging is supported by this Microsoft Hypervisor Virtual Machine.

To debug this vm, run the following command on your debugger host machine.windbg -k net:port=50000,key=1zeaj689h01ba.2p51dbdh81yzl.2ghcs6uei0g73.1mba0f4ju3ykv Then restart this VM by running shutdown -r -t 0 from this command prompt.

Before restarting the test machine, launch WinDbg on the dev machine, go to File > Attach to kernel and enter the key output from kdnet.

Click OK and it will wait for a connection.

Reboot the test VM and it will connect to the debugger during startup.

You can stop the kernel by selecting Break (in the top-left).

You will notice the entire VM freeze, which is why you cannot fully debug a local kernel - the whole machine state is suspended by the debugger. To allow the system to continue, select Go or press F5. After which, the VM will start responding again.

Kernel Debugging

One of the coolest features of WinDbg is the ability to load your source code and debug symbols, and debug a driver in the same way you might experience in an IDE. If you already have WinDbg attached to the VM kernel, click the Break button. Then go to File > Settings > Debugging settings.

Under source path, add the path to the driver source code. For me, that's C:\Users\Daniel\source\repos\DriverDev\Driver.

Under symbol path, add the directory that contains Driver.pdb. For me, that's C:\Users\Daniel\source\repos\DriverDev\x64\Debug.

Click Ok to save the changes.

To set a breakpoint, use the bp command. For example:

kd> bp Driver!DeviceControl

The bl command will list all current breakpoints.

Breakpoints can be removed using the bc command. bc <index> will delete a single breakpoint at the given index and bc * will delete them all. You can also use bd to temporary disable breakpoints without deleting them, and be to enable them again.

Resume the debugger by pressing Go or using the g command, then run the client app. Once it sends the IOCTL, WinDbg will break and automatically displays our source code.

The step out/into/over buttons can then be used to step through execution flow as with any managed debugger. You can also set additional breakpoints by clicking in the little gutter on the left-hand side.

Last updated