eBPF is (now!) a cross-platform technology with origins in the Linux Kernel that can run sandboxed programs in a privileged context such as the operating system kernel. It is used to safely and efficiently extend the capabilities of the kernel without requiring to change kernel source code or write drivers with the native kernel APIs.

Since May 2021, Microsoft has been hard at work on bringing eBPF to Windows. This post is meant to provide a user’s view of the project circa early 2023. We’ll be looking at setting up a Windows-eBPF build environment, followed by creating a sample project to pass around data between a userspace program and an eBPF program running in the kernel.

Untitled_Artwork (1).png

Table of Contents

Installation

To develop eBPF programs, we need a Windows VM with test-signing enabled or a kernel-debugger attached. eBPF drivers cannot be production-signed at the current state of the project (hardening the security process is still in progress).

To obtain the eBPF Development files, we have three options.

  1. Use the eBPF-for-Windows nuget package.

  2. Build the project in the repository and grab the newly built MSI installer from x64/Debug/ebpf-for-windows.msi. Instructions for building the project can be found here.

  3. Download the 0.6.0 release .msi from the Releases section here.

    <aside> 💡 At the time of writing, the 0.6.0 .msi has a few bugs regarding the directory structure that need to be ironed out. We will be using the nuget package for our development.

    </aside>

To begin, download NuGet Windows x86 Commandline version 6.31 or higher and install it to a location such as C:\\Program Files (x86)\\NuGet. Don't forget to add nuget.exe to your PATH.

Next, navigate to the directory where you want to download the eBPF files and open a command prompt. Run the command nuget install eBPF-for-Windows -Version 0.6.0. This should create a directory called eBPF-for-Windows.0.6.0 in your working directory.

After installing the NuGet package, as a one-time operation, run the export_program_info.exe tool from the command line to complete the installation. You can find this tool in the eBPF-for-Windows.0.6.0\\build\\native\\bin directory.

That’s it. We’ll see what to do with the downloaded files later in this post.

The eBPF Programming Model

eBPF programs are executed by an eBPF runtime driver in the kernel. On Linux systems, this runtime ships with the kernel. On Windows, this runtime ebpfcore.sys ships with the MSI installer. Let’s examine a high level view of how eBPF programs are built and run on Windows.

We start with our source code for the eBPF program written in a restricted set of C. This is the program that will run in the kernel. We compile this program with a compiling toolchain that can emit eBPF bytecode. Currently, this can be done with Clang/LLVM.

Using an application written by you, or the netsh app, the bytecode is fed into the PREVAIL Verifier through a userspace API (EbpfApi.lib/ebpfapi.dll) which exposes functions for userspace manipulation of an eBPF Program. The verifier checks the program for invalid memory accesses, termination, etc. This is why eBPF Programs are written in a restricted subset of C so that another piece of software can verify them.