Platform that enables Windows driver development in Rust. Developed by Surface.

Overview

windows-drivers-rs

This repo is a collection of Rust crates that enable developers to develop Windows Drivers in Rust. It is the intention to support both WDM and WDF driver development models. This repo contains the following crates:

  • wdk-build: A library to configure a Cargo build script for binding generation and downstream linking of the WDK (Windows Developer Kit). While this crate is written to be flexible with different WDK releases and different WDF version, it is currently only tested for NI eWDK, KMDF 1.33, UMDF 2.33, and WDM Drivers. There may be missing linker options for older DDKs.
  • wdk-sys: Direct FFI bindings to APIs available in the Windows Development Kit (WDK). This includes both autogenerated ffi bindings from bindgen, and also manual re-implementations of macros that bindgen fails to generate.
  • wdk: Safe idiomatic bindings to APIs available in the Windows Development Kit (WDK)
  • wdk-panic: Default panic handler implementations for programs built with WDK
  • wdk-alloc: alloc support for binaries compiled with the Windows Development Kit (WDK)
  • wdk-macros: A collection of macros that help make it easier to interact with wdk-sys's direct bindings. This crate is re-exported via wdk-sys and crates should typically never need to directly depend on wdk-macros

To see an example of this repo used to create drivers, see Windows-rust-driver-samples.

Note: This project is still in early stages of development and is not yet recommended for commercial use. We encourage community experimentation, suggestions and discussions! We will be using our GitHub Discussions forum as the main form of engagement with the community!

Supported Configurations

This project was built with support of WDM, KMDF, and UMDF drivers in mind, as well as Win32 Services. This includes support for all versions of WDF included in WDK 22H2 and newer. Currently, the crates available on crates.io only support KMDF v1.33, but bindings can be generated for everything else by cloning windows-drivers-rs and modifying the config specified in build.rs of wdk-sys. Crates.io support for other WDK configurations is planned in the near future.

Getting Started

Build Requirements

  • Binding generation via bindgen requires libclang. The easiest way to acquire this is via winget

    • winget install LLVM.LLVM
  • To execute post-build tasks (ie. inf2cat, infverif, etc.), cargo make is used

    • cargo install --locked cargo-make --no-default-features --features tls-native
  • Building programs with the WDK also requires being in a valid WDK environment. The recommended way to do this is to enter an eWDK developer prompt

Adding windows-drivers-rs to Your Driver Package

The crates in this repository are available from crates.io, but take into account the current limitations outlined in Supported Configurations. If you need to support a different config, try cloning this repo and using path dependencies

  1. Create a new Cargo package with a lib crate:

    cargo new <driver_name> --lib --config
  2. Add dependencies on windows-drivers-rs crates:

    cd <driver_name>
    cargo add --build wdk-build
    cargo add wdk wdk-sys wdk-alloc wdk-panic
  3. Set the crate type to cdylib by adding the following snippet to Cargo.toml:

    [lib]
    crate-type = ["cdylib"]
  4. Set crate panic strategy to abort in Cargo.toml:

    [profile.dev]
    panic = "abort"
    lto = true # optional setting to enable Link Time Optimizations
    
    [profile.release]
    panic = "abort"
    lto = true # optional setting to enable Link Time Optimizations
  5. Create a build.rs and add the following snippet:

    fn main() -> Result<(), wdk_build::ConfigError> {
       wdk_build::Config::from_env_auto()?.configure_binary_build();
       Ok(())
    }
  6. Mark your driver as no_std in lib.rs:

    #![no_std]
  7. Add a panic handler in lib.rs:

    #[cfg(not(test))]
    extern crate wdk_panic;
  8. Add a global allocator in lib.rs:

    #[cfg(not(test))]
    use wdk_alloc::WDKAllocator;
    
    #[cfg(not(test))]
    #[global_allocator]
    static GLOBAL_ALLOCATOR: WDKAllocator = WDKAllocator;
  9. Add a DriverEntry in lib.rs:

    use wdk_sys::{
       DRIVER_OBJECT,
       NTSTATUS,
       PCUNICODE_STRING,
    };
    
    #[export_name = "DriverEntry"] // WDF expects a symbol with the name DriverEntry
    pub unsafe extern "system" fn driver_entry(
       driver: &mut DRIVER_OBJECT,
       registry_path: PCUNICODE_STRING,
    ) -> NTSTATUS {
       0
    }
  10. Add a Makefile.toml:

extend = ".cargo-make-loadscripts/rust-driver-makefile.toml"

[env]
CARGO_MAKE_EXTEND_WORKSPACE_MAKEFILE = true

[config]
load_script = """
pwsh.exe -Command "\
if ($env:CARGO_MAKE_CRATE_IS_WORKSPACE) { return };\
$cargoMakeURI = 'https://raw.githubusercontent.com/microsoft/windows-drivers-rs/main/rust-driver-makefile.toml';\
New-Item -ItemType Directory .cargo-make-loadscripts -Force;\
Invoke-RestMethod -Method GET -Uri $CargoMakeURI -OutFile $env:CARGO_MAKE_WORKSPACE_WORKING_DIRECTORY/.cargo-make-loadscripts/rust-driver-makefile.toml\
"
"""
  1. Add an inx file that matches the name of your cdylib crate.

  2. Build the driver:

cargo make

A DriverCertificate.cer file will be generated, and a signed driver package will be available at target/<Cargo profile>/package

Trademark Notice

Trademarks This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow Microsoft’s Trademark & Brand Guidelines. Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party’s policies.

Comments
  • error

    error

    **********************************************************************
    ** Visual Studio 2022 Developer Command Prompt v17.7.4
    ** Copyright (c) 2022 Microsoft Corporation
    **********************************************************************
    [vcvarsall.bat] Environment initialized for: 'x64'
    
    C:\Program Files\Microsoft Visual Studio\2022\Enterprise>cd /d D:\code\rust\code\windows\windows-drivers-rs
    
    D:\code\rust\code\windows\windows-drivers-rs>cargo build
       Compiling wdk-sys v0.1.0 (D:\code\rust\code\windows\windows-drivers-rs\crates\wdk-sys)
    error: failed to run custom build command for `wdk-sys v0.1.0 (D:\code\rust\code\windows\windows-drivers-rs\crates\wdk-sys)`
    
    Caused by:
      process didn't exit successfully: `D:\code\rust\code\windows\windows-drivers-rs\target\debug\build\wdk-sys-bd0a85a523038361\build-script-build` (exit code: 101)
      --- stderr
      thread 'main' panicked at 'WDKContentRoot should be able to be detected. Ensure that the WDK is installed, or that the environment setup scripts in the eWDK have been run.', crates\wdk-build\src\lib.rs:111:64
      note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
    
    D:\code\rust\code\windows\windows-drivers-rs>
    
    opened by kouzhudong 5
  • Choose between windows-rs and this crate

    Choose between windows-rs and this crate

    Hi! Thanks for your awesome work, but I have a question: windows-rs has bindings for WDK based on wdkmetadata, your crate uses bindgen. So... which crate should I use for a long-term project? Which crate is "official" WDK port that Microsoft recommends to use for drivers? And which approach is better (wdkmetadata vs bindgen) in terms of accuracy and completeness?

    opened by HoShiMin 0
  • Fix makefile if target directory is on another drive letter

    Fix makefile if target directory is on another drive letter

    This commit is a simple change to make the build script work if the target directory is on another drive than the project (for example, a RAMdisk or an NVMe).

    opened by unknowntrojan 0
  • RUST_TAG in wdk-alloc

    RUST_TAG in wdk-alloc

    https://github.com/microsoft/windows-drivers-rs/blob/79d09bbc2f42a8cc0f2f1b47f2bb3839e232e3b0/crates/wdk-alloc/src/lib.rs#L25-L33

    Is there a reason this uses lazy_static instead of just a const and a byte string literal (of type &[u8;4])? u32::from_ne_bytes is const stable since 1.44.

    C.f. https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=2be24215859c818308542b6893f36ca2

    opened by Xiphoseer 1
  • Panic Strategy

    Panic Strategy

    "Panic" in the Windows Kernel (or "bugchecking" the system KeBugCheckEx) is a last resort and should be reserved only for cases where the kernel is in a corrupted and unrecoverable state. It is usually never acceptable to bugcheck the system. I find it unlikely that any Rust crate would ever need to bugcheck the kernel.

    Today this library notes a "TODO" on this topic: https://github.com/microsoft/windows-drivers-rs/blob/cd1fd23f000c64ea244b5cbfc33d64acb1104b8b/crates/wdk-panic/src/lib.rs#L29-L33

    Ultimately the kernel should handle errors cleanly and, by all means necessary, prevent itself from getting into a corrupted or unrecoverable state. I worry that the introduction of a panic handler and the interactions between other crates written for the Windows Kernel could degrade the overall reliability of the kernel.

    I'm not certain the best way to approach this problem. My initial reaction is disallow panic handlers when developing against the Windows Kernel and reserve "panics" (bugchecks) for the rare and extreme cases. To achieve this the crates used in the kernel would need to always communicate errors rather than giving up with a panic. Thankfully, Rust has robust and capable error handling patterns with things like match and Result. I'd like to raise this as an open topic to the community to discuss strategies for panic handling for the Windows Kernel.

    opened by jxy-s 4
  • Generic Fail-able, Pool and Tag Aware Allocators

    Generic Fail-able, Pool and Tag Aware Allocators

    Development in the Windows Kernel requires allocations from different pools and the capability to tag allocations is an invaluable tool for debugging/triage.

    Today this repository looks to recommend a global allocator and one that allocates exclusively from non-paged pool with a hard-coded pool tag.

    https://github.com/microsoft/windows-drivers-rs/blob/cd1fd23f000c64ea244b5cbfc33d64acb1104b8b/crates/wdk-alloc/src/lib.rs#L35-L45

    Rust crates for the Windows Kernel probably shouldn't provide a global kernel allocator. Else everyone using these crates may subtly end up allocating memory using identical tags. This will make debugging and triage a nightmare in the long term. Additionally I'll note, the non-paged pools are far more limited resource that the paged pools. I recognize that the safer option when implementing a global allocator is to force it into non-paged memory, since not doing so has the potential to introduce other issues. However resource exhaustion is far more likely when forcing all allocations into non-paged pools.

    For Rust to be a first-class citizen in the Windows Kernel. The language must support generic fail-able allocators. And the crates for the Windows Kernel should expose and support appropriate allocators that are capable of specifying pool types and tags.

    opened by jxy-s 2
Releases(v0.1.0)
  • v0.1.0(Sep 22, 2023)

    What's Changed

    • Added wdk, wdk-sys, wdk-build, wdk-alloc, wdk-panic, wdk-macros in initial commit to Open-Sourced Repository!
    • Fixes to go with 0.1.0 crates.io releases by @wmmc88 in https://github.com/microsoft/windows-drivers-rs/pull/2

    New Contributors

    • @wmmc88 made their first contribution in https://github.com/microsoft/windows-drivers-rs/pull/2

    Full Changelog: https://github.com/microsoft/windows-drivers-rs/commits/v0.1.0

    Source code(tar.gz)
    Source code(zip)
Owner
Microsoft
Open source projects and samples from Microsoft
Microsoft
This tool was developed as part of a course on forensic analysis and cybersecurity. It is intended to be used as a training resource to help students understand the structure and content of job files in Windows environments.

Job File Parser Job File Parser is a Rust-based tool designed for parsing both legacy binary job files and modern XML job files used by the Windows Ta

Mehrnoush 3 Aug 12, 2024
Rust crate for interacting with the Windows Packet Filter driver.

NDISAPI-RS NDISAPI-RS is a Rust crate for interacting with the Windows Packet Filter driver. It provides an easy-to-use, safe, and efficient interface

Vadim Smirnov 6 Jun 15, 2023
A Windows virtual display driver written in Rust (works with VR, etc)

Virtual Display Driver This is a Windows driver made in Rust which creates a virtual desktop. It has many uses, such as: A private virtual desktop for

Cherry 28 Sep 19, 2023
Windows shellcode development in Rust

Write Windows Shellcode in Rust Project overview Windows shellcode project is located in shellcode/, it can build into a PE file with only .text secti

red 171 Dec 26, 2022
Windows-rs - Rust for Windows

Rust for Windows The windows crate lets you call any Windows API past, present, and future using code generated on the fly directly from the metadata

Microsoft 7.7k Dec 30, 2022
Use Thunk to build your Rust program that runs on old Windows platforms, support Windows XP and more!

Use Thunk to build your Rust program that runs on old platforms. Thunk uses VC-LTL5 and YY-Thunks to build programs that support old platforms. So, ho

null 6 May 21, 2023
This will be developed in Rust on a Teensy 4.1 with an ARM Cortex-M7

Advent of Code 2021 This will be developed in Rust on a Teensy 4.1 with an ARM Cortex-M7. Solutions are stored in src/bin. Setup It is really recommen

Liz 3 Aug 9, 2022
Synthia is a lightweight and beginner-friendly interpreted programming language developed in Rust

Synthia is a lightweight and beginner-friendly interpreted programming language developed in Rust. With a simple, intuitive syntax and a focus on ease of use, Synthia is perfect for both newcomers to programming and experienced developers looking for a flexible scripting language

Shiva 3 Oct 5, 2023
Nonsible is an alternative to Ansible. It is open source and developed in Rust.

Nonsible is an alternative to Ansible. It is open source and developed in Rust. The idea is not to depend on factors like Python, as it commits us to having Python installed on all of our machines, among other requirements.

Nedd Chairi Muñoz 4 Oct 17, 2023
List public items (public API) of library crates. Enables diffing public API between releases.

cargo-public-items List public items (the public API) of a Rust library crate by analyzing the rustdoc JSON of the crate. Automatically builds the rus

Martin Nordholts 203 Dec 31, 2022
zkPoEX enables white hat hackers to report live vulnerabilities in smart contracts while maintaining the confidentiality of the exploit

zkPoEX enables white hat hackers to report live vulnerabilities in smart contracts while maintaining the confidentiality of the exploit, facilitating efficient communication and collaboration between hackers and project owners for a more secure DeFi ecosystem.

zkoranges 135 Apr 16, 2023
Switch windows of same app with alt + ` on windows pc.

Windows Switcher Switch windows of same app with alt + ` on windows pc. 250k single file executable downloaded from Github Release. No installation re

null 172 Dec 10, 2022
Check if the process is running inside Windows Subsystem for Linux (Bash on Windows)

is-wsl Check if the process is running inside Windows Subsystem for Linux (Bash on Windows) Inspired by sindresorhus/is-wsl and made for Rust lang. Ca

Sean Larkin 6 Jan 31, 2023
Windows Capture Simple Screen Capture for Windows 🔥

Windows Capture   Windows Capture is a highly efficient Rust library that enables you to effortlessly capture the screen using the Graphics Capture AP

null 3 Sep 24, 2023
A collection of COSMIC projects developed by the community.

COSMIC Project Collection A collection of COSMIC projects developed by the community. Applications Name Description Image tasks A simple task manageme

Eduardo Flores 94 Jul 25, 2024
Rust-based language and runtime for cross-platform app development

Pax Pax is a cross-platform rendering engine & Rust framework for interactive graphics, animations, and GUIs. Pax extends the Rust programming languag

Pax 75 Dec 19, 2022
Cross-platform CLI Rimworld Mod manager. Still under development

rwm Inspired by Spoons rmm. This is a cross-platform Mod Manager for RimWorld intended to work with macOS, linux and Windows Up to now, you must have

Alejandro O 7 Sep 5, 2022
That program use on platform windows. And if you write any text on uncorrect keyboard layout, that program for that.

?? This program is designed to translate text into the correct layout when typing is incorrect. ?? Example ghbdtn -> привет Just (by default) pressing

Gest Se 5 Jan 26, 2023
Cross-platform casting SDK, support Android, Windows, Linux

mirror Cross-platform casting SDK, support Android, Windows, Linux Low-latency transport protocols use [SRT](https://github.com/Haivision/srt) Video:

Lazy Panda 10 Feb 29, 2024