mirror of
https://github.com/safing/portmaster
synced 2026-04-28 03:20:31 +00:00
feat(tests): add documentation and build script for Windows kernel driver testing
This commit is contained in:
parent
9e8acb2d25
commit
def9d3407e
3 changed files with 373 additions and 0 deletions
215
windows_kext/test/BUILD_DEBUG.md
Normal file
215
windows_kext/test/BUILD_DEBUG.md
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
# Building and Running Driver with Debug Logging
|
||||
|
||||
## Driver Signing Requirement
|
||||
|
||||
Windows requires **all kernel drivers to be signed**. Test signing provides a free alternative to expensive production code signing certificates for development and testing purposes.
|
||||
|
||||
## Important: Debug Builds Are Disabled
|
||||
|
||||
⚠️ **The driver cannot be compiled in debug mode.** The code contains a compile-time check (`compile_error!`) that prevents debug builds due to potential optimization-related issues and inconsistent compiler behavior between debug and release modes.
|
||||
|
||||
However, you can still enable verbose logging in release builds by changing the log level.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Already documented in [main README](../README.md), but quick recap:
|
||||
|
||||
1. **Visual Studio 2022** with C++ and Windows SDK
|
||||
2. **Windows Driver Kit (WDK)** installed
|
||||
3. **Rust toolchain** installed
|
||||
4. **Test signing enabled** (see below)
|
||||
|
||||
## Step 1: Enable Test Signing (One-time Setup)
|
||||
|
||||
⚠️ **SECURITY WARNING**: Test signing reduces system security by allowing any locally-generated test certificate to load kernel drivers. **Strongly recommended to use a VM or dedicated test machine**. See "Disabling Test Signing" section below to restore security when done testing.
|
||||
|
||||
### Create Test Certificate
|
||||
|
||||
Open **PowerShell as Administrator**:
|
||||
|
||||
```powershell
|
||||
# Create a self-signed certificate for driver testing
|
||||
MakeCert -r -pe -ss PrivateCertStore -n "CN=DriverTestCert" DriverTestCert.cer
|
||||
|
||||
# Install the certificate to Trusted Root
|
||||
CertMgr /add DriverTestCert.cer /s /r localMachine root
|
||||
|
||||
# Install to Trusted Publishers (needed for driver installation)
|
||||
CertMgr /add DriverTestCert.cer /s /r localMachine trustedpublisher
|
||||
```
|
||||
|
||||
### Enable Test Signing Mode
|
||||
|
||||
```powershell
|
||||
# Enable test signing
|
||||
Bcdedit.exe -set TESTSIGNING ON
|
||||
|
||||
# Restart required!
|
||||
Restart-Computer
|
||||
```
|
||||
|
||||
After restart, you should see **"Test Mode"** watermark in the corner of your screen.
|
||||
|
||||
### Verify Test Signing is Enabled
|
||||
|
||||
```powershell
|
||||
bcdedit /enum | Select-String testsigning
|
||||
# Should show: testsigning Yes
|
||||
```
|
||||
|
||||
## Step 2: Enable Debug Logging in Driver
|
||||
|
||||
To see verbose logs from the driver, edit the log level before building.
|
||||
|
||||
**Edit `driver/src/logger.rs`:**
|
||||
|
||||
```rust
|
||||
// Change line 8 from:
|
||||
pub const LOG_LEVEL: u8 = Severity::Warning as u8;
|
||||
|
||||
// To one of:
|
||||
pub const LOG_LEVEL: u8 = Severity::Debug as u8; // Recommended for testing
|
||||
// pub const LOG_LEVEL: u8 = Severity::Info as u8; // Less verbose
|
||||
// pub const LOG_LEVEL: u8 = Severity::Trace as u8; // Most verbose
|
||||
```
|
||||
|
||||
For testing, `Debug` level is recommended.
|
||||
|
||||
## Step 3: Build Driver in Release Mode
|
||||
|
||||
Navigate to the driver directory:
|
||||
|
||||
```powershell
|
||||
cd D:\Projects\Portmaster\portmaster\windows_kext\driver
|
||||
|
||||
# Build in release mode (only mode supported)
|
||||
cargo build --release --target x86_64-pc-windows-msvc
|
||||
|
||||
# Output: driver/target/x86_64-pc-windows-msvc/release/driver.lib
|
||||
```
|
||||
|
||||
**Note:** Debug builds (`cargo build` without `--release`) will fail with a compile error by design.
|
||||
|
||||
## Step 4: Link the Driver
|
||||
|
||||
Copy the `.lib` file to the root directory:
|
||||
|
||||
```powershell
|
||||
cd D:\Projects\Portmaster\portmaster\windows_kext
|
||||
|
||||
Copy-Item driver/target/x86_64-pc-windows-msvc/release/driver.lib . -Force
|
||||
```
|
||||
|
||||
Run the linker script:
|
||||
|
||||
```powershell
|
||||
.\link-dev.ps1
|
||||
```
|
||||
|
||||
This creates `driver.sys` in the current directory.
|
||||
|
||||
## Step 5: Sign the Driver
|
||||
|
||||
## Step 5: Sign the Driver
|
||||
|
||||
```powershell
|
||||
cd D:\Projects\Portmaster\portmaster\windows_kext
|
||||
|
||||
# Sign the driver
|
||||
SignTool sign /v /s PrivateCertStore /n DriverTestCert driver.sys
|
||||
```
|
||||
|
||||
Verify signature:
|
||||
|
||||
```powershell
|
||||
SignTool verify /v /pa driver.sys
|
||||
```
|
||||
|
||||
You should see: **"Successfully verified: driver.sys"**
|
||||
|
||||
## Step 6: View Driver Logs
|
||||
|
||||
### Ring Buffer Logs (Recommended)
|
||||
|
||||
These logs come through the `GetLogs` command.
|
||||
|
||||
### Kernel Debugger Output (Not Available in Release)
|
||||
|
||||
The `wdk::dbg!()`, `wdk::info!()`, and `wdk::err!()` macros only work in debug builds, which are disabled for this driver. These would output to tools like DebugView via `DbgPrint`, but since debug builds are not allowed, this logging path is not available.
|
||||
|
||||
**Use the ring buffer logs** (captured by `dbg!`, `info!`, `warn!`, `err!` macros) for all debugging.
|
||||
|
||||
## Common Issues
|
||||
|
||||
### "The hash for the file is not present in the specified catalog file"
|
||||
|
||||
**Solution**: Your driver isn't signed or the certificate isn't trusted.
|
||||
```powershell
|
||||
# Re-sign the driver
|
||||
SignTool sign /v /s PrivateCertStore /n DriverTestCert driver.sys
|
||||
```
|
||||
|
||||
### "Windows cannot verify the digital signature"
|
||||
|
||||
**Solution**: Test signing not enabled or certificate not in Trusted Root.
|
||||
```powershell
|
||||
# Check test signing
|
||||
bcdedit /enum | Select-String testsigning
|
||||
|
||||
# Reinstall certificate if needed
|
||||
CertMgr /add DriverTestCert.cer /s /r localMachine root
|
||||
```
|
||||
|
||||
### "Service marked for deletion"
|
||||
|
||||
**Solution**: Manually clean up:
|
||||
```powershell
|
||||
sc stop PortmasterKext
|
||||
sc delete PortmasterKext
|
||||
# Wait a few seconds
|
||||
# Then try starting again
|
||||
```
|
||||
|
||||
### "Access is denied" when creating service
|
||||
|
||||
**Solution**: Run as Administrator.
|
||||
|
||||
### No debug output (`GetLogs` command)
|
||||
|
||||
**Solution**:
|
||||
1. Make sure you edited `driver/src/logger.rs` to set `LOG_LEVEL = Severity::Debug`
|
||||
2. Rebuild the driver in **release mode** (`cargo build --release`)
|
||||
3. The driver must be actively running and processing connections to generate logs
|
||||
4. Default log level (`Warning`) only shows errors, not normal operations
|
||||
|
||||
## Quick Build & Test Cycle
|
||||
|
||||
```powershell
|
||||
# 1. (Optional) Enable debug logging - edit driver/src/logger.rs first
|
||||
|
||||
# 2. Build driver in release mode
|
||||
cd D:\Projects\Portmaster\portmaster\windows_kext\driver
|
||||
cargo build --release
|
||||
|
||||
# 3. Link and sign
|
||||
cd ..
|
||||
Copy-Item driver/target/x86_64-pc-windows-msvc/release/driver.lib . -Force
|
||||
.\link-dev.ps1
|
||||
SignTool sign /v /s PrivateCertStore /n DriverTestCert driver.sys
|
||||
|
||||
# 4. Test (in playground, as Administrator)
|
||||
```
|
||||
|
||||
## Disabling Test Signing (When Done Testing)
|
||||
|
||||
⚠️ **IMPORTANT**: When finished testing, disable test signing to restore system security.
|
||||
|
||||
```powershell
|
||||
# Run as Administrator
|
||||
Bcdedit.exe -set TESTSIGNING OFF
|
||||
|
||||
# Restart required for changes to take effect
|
||||
Restart-Computer
|
||||
```
|
||||
|
||||
After restart, the "Test Mode" watermark will disappear and the system will no longer accept test-signed drivers. This restores normal kernel driver security enforcement.Production vs Test Signing
|
||||
13
windows_kext/test/README.md
Normal file
13
windows_kext/test/README.md
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
# Test Directory
|
||||
|
||||
> ⚠️ **Notice**: This folder and its contents were primarily generated with the assistance of AI and may contain errors or inaccuracies. They are intended solely for local testing and development and must not be used in production.
|
||||
|
||||
## Contents
|
||||
|
||||
- `build_test.ps1` - Script to build the test-signed driver
|
||||
- `_out/` - Output directory for built test driver
|
||||
- `_testcert/` - Test certificates for driver signing
|
||||
|
||||
## Purpose
|
||||
|
||||
This directory contains tools and utilities for testing the Portmaster Windows kernel driver during development. These are developer tools only and are not part of the production build or release process.
|
||||
145
windows_kext/test/build_test.ps1
Normal file
145
windows_kext/test/build_test.ps1
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
# Build and Sign Test Driver Script
|
||||
# Must be run from Developer PowerShell for Visual Studio
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
# Get script directory and set paths
|
||||
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
$rootDir = Split-Path -Parent $scriptDir
|
||||
$driverDir = Join-Path $rootDir "driver"
|
||||
$certPath = Join-Path $rootDir "test\_testcert\DriverTestCert.cer"
|
||||
$outDir = Join-Path $scriptDir "_out"
|
||||
|
||||
# Create output directory if it doesn't exist
|
||||
if (-not (Test-Path $outDir)) {
|
||||
New-Item -ItemType Directory -Path $outDir -Force | Out-Null
|
||||
}
|
||||
|
||||
Write-Host "=================================================" -ForegroundColor Cyan
|
||||
Write-Host " Building and Signing Test Driver" -ForegroundColor Cyan
|
||||
Write-Host "=================================================" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
|
||||
# Verify we are in the correct directory
|
||||
if (-not (Test-Path $driverDir)) {
|
||||
Write-Host "ERROR: Driver directory not found at: $driverDir" -ForegroundColor Red
|
||||
Write-Host "Please run this script from the windows_kext root directory or ensure paths are correct." -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Verify certificate exists
|
||||
if (-not (Test-Path $certPath)) {
|
||||
Write-Host "ERROR: Certificate not found at: $certPath" -ForegroundColor Red
|
||||
Write-Host "Please create the test certificate first." -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
#
|
||||
# Step 1: Build Driver in Release Mode
|
||||
#
|
||||
Write-Host "[1/3] Building driver in release mode..." -ForegroundColor Yellow
|
||||
Push-Location $driverDir
|
||||
try {
|
||||
cargo build --release --target x86_64-pc-windows-msvc
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host "ERROR: Cargo build failed with exit code $LASTEXITCODE" -ForegroundColor Red
|
||||
exit $LASTEXITCODE
|
||||
}
|
||||
|
||||
Write-Host " Driver built successfully" -ForegroundColor Green
|
||||
} finally {
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
#
|
||||
# Step 2: Link the Driver
|
||||
#
|
||||
Write-Host "[2/3] Linking driver..." -ForegroundColor Yellow
|
||||
Push-Location $outDir
|
||||
try {
|
||||
# Copy the .lib file to output directory
|
||||
$libSource = Join-Path $driverDir "target\x86_64-pc-windows-msvc\release\driver.lib"
|
||||
$libDest = Join-Path $outDir "driver.lib"
|
||||
|
||||
if (-not (Test-Path $libSource)) {
|
||||
Write-Host "ERROR: Built driver.lib not found at: $libSource" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
Copy-Item $libSource $libDest -Force
|
||||
Write-Host " Copied driver.lib" -ForegroundColor Green
|
||||
|
||||
# Run linker script (from output directory so files are created here)
|
||||
$linkScript = Join-Path $rootDir "link-dev.ps1"
|
||||
if (-not (Test-Path $linkScript)) {
|
||||
Write-Host "ERROR: link-dev.ps1 not found at: $linkScript" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
& $linkScript
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host "ERROR: Linking failed with exit code $LASTEXITCODE" -ForegroundColor Red
|
||||
exit $LASTEXITCODE
|
||||
}
|
||||
|
||||
# Rename driver.sys to test name
|
||||
$sysFile = Join-Path $outDir "driver.sys"
|
||||
if (-not (Test-Path $sysFile)) {
|
||||
Write-Host "ERROR: driver.sys was not created" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
$testSysFile = Join-Path $outDir "PortmasterKext_test.sys"
|
||||
Move-Item $sysFile $testSysFile -Force
|
||||
|
||||
Write-Host " Driver linked successfully (PortmasterKext_test.sys)" -ForegroundColor Green
|
||||
} finally {
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
#
|
||||
# Step 3: Sign the Driver
|
||||
#
|
||||
Write-Host "[3/3] Signing driver..." -ForegroundColor Yellow
|
||||
Push-Location $outDir
|
||||
try {
|
||||
$sysFile = Join-Path $outDir "PortmasterKext_test.sys"
|
||||
|
||||
# Sign the driver
|
||||
SignTool sign /v /fd SHA256 /s PrivateCertStore /n DriverTestCert $sysFile
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host "ERROR: Signing failed with exit code $LASTEXITCODE" -ForegroundColor Red
|
||||
Write-Host "Make sure the certificate is installed in PrivateCertStore" -ForegroundColor Yellow
|
||||
exit $LASTEXITCODE
|
||||
}
|
||||
|
||||
Write-Host " Driver signed successfully" -ForegroundColor Green
|
||||
|
||||
# Verify signature
|
||||
Write-Host ""
|
||||
Write-Host "Verifying signature..." -ForegroundColor Yellow
|
||||
SignTool verify /v /pa $sysFile
|
||||
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
Write-Host "WARNING: Signature verification failed" -ForegroundColor Yellow
|
||||
} else {
|
||||
Write-Host " Signature verified" -ForegroundColor Green
|
||||
}
|
||||
} finally {
|
||||
Pop-Location
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "=================================================" -ForegroundColor Cyan
|
||||
Write-Host " Build Complete!" -ForegroundColor Green
|
||||
Write-Host "=================================================" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
Write-Host "Output directory: $outDir" -ForegroundColor White
|
||||
Write-Host "Driver file: PortmasterKext_test.sys" -ForegroundColor White
|
||||
Write-Host ""
|
||||
Write-Host "Next steps:" -ForegroundColor Yellow
|
||||
Write-Host " 1. Run playground as Administrator" -ForegroundColor White
|
||||
Write-Host " 2. Use start command to load the driver" -ForegroundColor White
|
||||
Write-Host ""
|
||||
Loading…
Add table
Add a link
Reference in a new issue