# Environment Setup

## 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](https://visualstudio.microsoft.com/).  Any version, including the free community edition can be used.  During installation, select the *Desktop development with C++* workload option.

![](https://files.cdn.thinkific.com/file_uploads/584845/images/8a6/f6e/983/cpp-workload.png)

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

![](https://files.cdn.thinkific.com/file_uploads/584845/images/91f/014/692/sdk.png)

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

![](https://files.cdn.thinkific.com/file_uploads/584845/images/e93/3da/6ce/spectre.png)

Once installation is complete, download and run the [WDK installer](https://go.microsoft.com/fwlink/?linkid=2196230).  At the end of the installation, ensure checkbox for installing the Visual Studio extension is selected before closing the installer window.

![](https://driverdev-assets.s3.eu-west-2.amazonaws.com/101/vsix.png)

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](https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/) (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](https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/attaching-to-a-virtual-machine--kernel-mode-) and [KDNET](https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/setting-up-network-debugging-of-a-virtual-machine-host).  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](https://developer.microsoft.com/en-us/windows/downloads/windows-sdk/).  During setup, uncheck every option except for *Debugging Tools*.

![](https://files.cdn.thinkific.com/file_uploads/584845/images/b4f/a8f/374/dbg-tools.png)

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.

```
C:\Windows\system32>bcdedit /set testsigning on
The operation completed successfully.
```

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.

![](https://files.cdn.thinkific.com/file_uploads/584845/images/16b/1d9/dc6/start-debugging.png)

Click *OK* and it will wait for a connection.

```
Microsoft (R) Windows Debugger Version 10.0.25877.1004 AMD64
Copyright (c) Microsoft Corporation. All rights reserved.

Using NET for debugging
Opened WinSock 2.0
Waiting to reconnect...
```

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

```
Windows 10 Kernel Version 19041 MP (1 procs) Free x64
Edition build lab: 19041.1.amd64fre.vb_release.191206-1406
Kernel base = 0xfffff801`4d000000 PsLoadedModuleList = 0xfffff801`4dc2a2d0
System Uptime: 0 days 0:00:00.378
```

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

```
Break instruction exception - code 80000003 (first chance)
*******************************************************************************
*                                                                             *
*   You are seeing this message because you pressed either                    *
*       CTRL+C (if you run console kernel debugger) or,                       *
*       CTRL+BREAK (if you run GUI kernel debugger),                          *
*   on your debugger machine's keyboard.                                      *
*                                                                             *
*                   THIS IS NOT A BUG OR A SYSTEM CRASH                       *
*                                                                             *
* If you did not intend to break into the debugger, press the "g" key, then   *
* press the "Enter" key now.  This message might immediately reappear.  If it *
* does, press "g" and "Enter" again.                                          *
*                                                                             *
*******************************************************************************
nt!DbgBreakPointWithStatus:
fffff801`4d405660 cc              int     3
```

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`.

![](https://files.cdn.thinkific.com/file_uploads/584845/images/fa7/8cf/56d/debugging-paths.png)

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.

```
kd> bl
     0 e Disable Clear  fffff806`6d291090  [C:\Users\Daniel\source\repos\DriverDev\Driver\main.cpp @ 61]     0001 (0001) Driver!DeviceControl
```

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.

![](https://files.cdn.thinkific.com/file_uploads/584845/images/2b9/42e/c02/bp.png)

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.
