Skip to content

Basic experimentation with Windows drivers.

License

Notifications You must be signed in to change notification settings

yottaawesome/basic-windows-drivers

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 

Repository files navigation

Basic Windows Drivers

Introduction

Basic experimentation with Windows drivers based off the MSDN docs, Pavel Yosifovich's Windows Kernel Programming book and Developing Drivers with the Windows Driver Foundation by Penny Orwick and Guy Smith.

Debugging

You'll need to first configure a target machine or VM for deployment and debugging. See here. Note that you need to ensure the target and host can ping each other. You may need to change the VM to use a Bridged connection and allow File and Printer Sharing on both the host and the target. You may then need to set up your Debug Print Filter (important note: filter masks stored in the registry take effect during boot). Once deployed and installed on the target, you'll need to start a WndDbg session through an elevated command prompt e.g. WinDbg -k net:port=<port>,key=<key>. WinDbg is located in your Windows kit, e.g. A:\Windows Kits\10\Debuggers\x64.

Building

You need Visual Studio 2022 and the latest Windows Driver Kit (WDK) and accompanying SDK to build and develop kernel components. If you receive obscure build errors related to inf2cat to dates in the DriverVer field in the *.inf files, ensure that in Project Properties > Configuration Properties > Inf2Cat > General > Use local time is set to Yes (/uselocaltime). See here and here for additional information. You may need to rebuild more than if you receive some errors after doing a full solution clean. There may be some absolute paths (for my machine) referenced in the project files that you may need to adjust or remove for your local environment.

Deploying

Provisioned VMs require binaries to be signed, or they'll be blocked by Microsoft Defender. As part of the VM provisioning process, development certificates for signing drivers will be generated, but you may still need to generate self-signed test certificates yourself. The SignTool comes with the Windows Kit (e.g. under C:\Program Files (x86)\Windows Kits\10\App Certification Kit\) and can be used like so to sign a binary: SignTool.exe Sign /a /v /fd SHA256 <binary_path> (note that older versions did not require the fd argument).

WinDbg

  • To add a breakpoint through WnDbg, use bm <module>!<symbol>, e.g. bm KmdfHelloWorld!DriverEntry
  • To list all breakpoints, use bl;
  • To list all running modules, use lm;
  • To list all symbols in a module, use x <module>!<symbol-search-string> e.g. x KmdfHelloWorld!Driver*
  • bc - clears a breakpoint from the list. Use bc * to clear all breakpoints.
  • bd - disables a breakpoint. Use bd * to disable all breakpoints.
  • be - enables a breakpoint. Use be * to enable all breakpoints.

See the step-by-step lab for further information.

Other notes and common problems

  • If devcon.exe fails, a log is generated at c:\windows\inf\setupapi.dev.log.
  • If you get an error about No file digest algorithm specified. Please specify the digest algorithm with the /fd flag. Using /fd SHA256 is recommended and more secure than SHA1. Calling signtool with /fd sha1 is equivalent to the previous behavior. In order to select the hash algorithm used in the signing certificate's signature, use the /fd certHash option., right click the project > Configuration Properties > Driver Signing > General > File Digest Algorithm > SHA256.
  • Newer versions of the WDK do not accept Sample as a class name in the INF file, and you'll also need to generate a new GUID.
  • Don't try to use C++ modules in kernel projects -- VS seemingly bugs out and locks the IFC files, causing compilation failures. This is apparently a WDK issue. This happens regardless of setting the standard to C++20, and the only way to solve the issue is to manually kill the language server processes in Task Manager, which is a pain.
  • For the Windows kernel, C++ is a fully-viable and effective language option for drivers. However, you don't have access to the STL and the C++ runtime is unavailable, which means no exception support, by default. That being said, you can find a kernel-ready implementation of the STL via Johnny Shaw's stlkrn and you can enable C++ exceptions using Martin Vejnár's vcrtl. I've not used them personally, so I can't vouch for them.
  • In the Windows registry, installed drivers are located under the HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services key.
  • When drivers are installed, Windows will copy the driver's INF file and referenced files to the driver store, which appears to be the %SYSTEMROOT%\System32\DriverStore directory. This behaviour was introduced in Windows Vista.
  • If you stop a driver and then restart it (e.g. via the net stop and net start commands) and you get a "file not found" error, check to see that your driver cleans up all resources before exiting. Certain resources, such as callouts, not being cleaned up can cause this issue.
  • When invoking any native Microsoft functions in the kernel, it's worthwhile checking the MSDN docs to ensure that you are running at the required IRQL to invoke those functions. This is because certain functions require the driver to be running at, above, or below a certain IRQL. Failure to do so will cause the function to fail or possibly bugcheck the system.

Additional resources