# Copyright (c) Microsoft Corporation # SPDX-License-Identifier: MIT <# .SYNOPSIS Generate a native driver from a BPF program. .DESCRIPTION This script generates a native driver (.sys file) from a BPF program. The native program can be used to load BPF programs into the kernel when Hypervisor-protected Code Integrity (HVCI) is enabled. .PARAMETER FileName Specifies the name of the ELF file containing the BPF program. .PARAMETER Type Specifies the type of the BPF program. Valid values include "xdp", "bind", "sockops", and other BPF program types. .PARAMETER IncludeDir Specifies the directory containing the bpf2c include files. .PARAMETER BinDir Specifies the directory containing the bpf2c binaries. .PARAMETER OutDir Specifies the directory where the generated driver will be placed. .PARAMETER Platform Specifies the target platform. Valid values include "x64". .PARAMETER Configuration Specifies the build configuration. Valid values include "Release", "FuzzerDebug", and "Debug". .PARAMETER SkipVerification Specifies whether to skip verification of the generated driver. This parameter is only supported for Debug builds. .PARAMETER KernelMode Specifies whether to generate a kernel-mode driver. If this parameter is false, a user DLL will be generated. .PARAMETER ResourceFile Specifies the path to a resource file to embed in the generated driver. .EXAMPLE .\Convert-BpfToNative.ps1 -FileName bindmonitor This example generates a native driver from the BPF program bindmonitor.o. .EXAMPLE .\Convert-BpfToNative.ps1 -FileName bindmonitor -Type bind This example generates a native driver from the BPF program bindmonitor.o. The program type is set to "bind". .EXAMPLE .\Convert-BpfToNative.ps1 -FileName bindmonitor -Type bind -Configuration Debug This example generates a native driver from the BPF program bindmonitor.o. The program type is set to "bind". The driver is built in Debug configuration. .EXAMPLE .\Convert-BpfToNative.ps1 -FileName bindmonitor -Type bind -Configuration Debug -KernelMode $false This example generates a user-mode DLL from the BPF program bindmonitor.o. The program type is set to "bind". The driver is built in Debug configuration. .NOTES Author: Microsoft Corporation Website: https://github.com/microsoft/ebpf-for-windows #> param([parameter(Mandatory = $true)] [string] $FileName, [parameter(Mandatory = $false)] [string] $Type, [parameter(Mandatory = $false)] [string] $IncludeDir = "$PSScriptRoot\..\include", [parameter(Mandatory = $false)] [string] $BinDir = "$PSScriptRoot", [parameter(Mandatory = $false)] [string] $OutDir = "$PWD", [parameter(Mandatory = $false)] [string] $Platform = "x64", [ValidateSet("Release", "NativeOnlyRelease", "FuzzerDebug", "Debug", "NativeOnlyDebug")][parameter(Mandatory = $false)] [string] $Configuration = "Release", [parameter(Mandatory = $false)] [bool] $SkipVerification = $false, [parameter(Mandatory = $false)] [bool] $KernelMode = $true, [parameter(Mandatory = $false)] [string] $ResourceFile = "") Push-Location $OutDir $KernelModeProject = '___KERNEL_MODE_VCXPROJ___' $UserModeProject = '___USER_MODE_VCXPROJ___' # If program name ends with .o, remove the suffix if ($FileName.EndsWith(".o")) { $FileName = $FileName.Substring(0, $FileName.Length - 2) } # SkipVerification is only supported for Debug builds. if ($Configuration -eq "Release" -and $SkipVerification) { throw "Invalid parameter. SkipVerification is only supported for Debug builds" } if ($null -eq (Get-Command 'msbuild.exe' -ErrorAction SilentlyContinue)) { throw "Unable to locate msbuild.exe. This command needs to run within a 'Developer Command Prompt'" } $fileExists = Test-Path -Path ("$FileName.o") if (!$fileExists) { $errorString = "Can't find program file: " + "$FileName.o" throw $errorString } $TempDir = "$OutDir\$FileName" if ($KernelMode) { $TempDir += "_km" } else { $TempDir += "_um" } mkdir -Force $TempDir Copy-Item -Path "$FileName.o" -Destination "$TempDir\" cd $TempDir if ($KernelMode) { $ProjectFile = "$FileName.vcxproj" Set-Content -Path $ProjectFile -Value $KernelModeProject } else { $ProjectFile = "$FileName_um.vcxproj" Set-Content -Path $ProjectFile -Value $UserModeProject } $AdditionalOptions = If ($SkipVerification) {"--no-verify"} Else {""} if ($PSBoundParameters.ContainsKey("Type")) { $AdditionalOptions += " --type $Type" } msbuild /p:BinDir="$BinDir\" /p:OutDir="$OutDir\" /p:IncludeDir="$IncludeDir" /p:Configuration="$Configuration" /p:Platform="$Platform" /p:FileName="$FileName" /p:AdditionalOptions="$AdditionalOptions" /p:ResourceFile="$ResourceFile" $ProjectFile if ($LASTEXITCODE -ne 0) { throw "Build failed for $FileName.o" } Pop-Location