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).
Runtime Componentsfor installation. We'll obtain the development files through a different method.
To obtain the eBPF Development files, we have three options.
x64/Debug/ebpf-for-windows.msi. Instructions for building the project can be found here.
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
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
That’s it. We’ll see what to do with the downloaded files later in this post.
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.