KanoHypervisor is a Windows x64 kernel driver for Intel VT-x research and bring-up. It is intended for an isolated test installation with a kernel debugger. Current status: research and bring-up; it is not a production hypervisor.
The primary validation profile is an isolated reference target:
- Windows 11 25H2, x64
- Intel Core i7-14700KF
- a recovery snapshot and an attached kernel debugger
- no production, safety-critical, or personal-data workloads
Host-only contract tests can run on other supported Windows x64 systems. VMX, service, and signature results must be collected on the isolated target. The compile host is not a runtime validation target; building an artifact there does not establish driver, HyperDbg, nested-VMX, passthrough, or performance compatibility.
- Intel VT-x late launch and VM-exit state handling
- fail-closed capability checks
- orderly multi-processor teardown with bounded retries
- quarantine when VMX ownership cannot be proven to be released
- versioned provider and session ABI for a future BootL0 interposer
- pure software VMCS12/nested-VMX, VMCS shadow, EPT policy, and TSC/QPC contract models
- a versioned VMX control-capability and per-processor consistency model for target-side validation
- an isolated
KNHV-NestedTest.syscontract-test driver - a read-only Windows Hypervisor Platform capability broker
- no physical BootL0 handoff, EPT/VMCS02 acceleration, device passthrough, or production support
| Path | Responsibility |
|---|---|
src/core |
Driver entry, lifecycle facade, and shared runtime state |
src/vmx |
Feature gates, VMCS setup, launch, exits, diagnostics, stop paths, and CPU capability model |
src/include |
Public, private, and logging contracts |
src/asm |
VMX entry, instruction wrappers, launch, and restore routines |
src/nested |
VMCS12, VMCS shadow, VMX instruction, address, and exit models |
src/ept |
Pure EPTP, nested mapping, generation, and debug-lease policy model |
src/time |
Fixed-point TSC transform, calibration, and drift contract model |
src/iommu |
Device, DMA-domain, and quarantine contract model |
src/exit |
Fail-closed VM-exit policy and routing model |
src/interrupt |
Bounded injection and posted-interrupt contract model |
src/whp |
WHP partition, mapping, vCPU, and exit lifecycle model |
src/broker |
Read-only WHP capability probe executable |
src/provider |
Capability-gated provider selection |
src/validation |
Versioned target evidence, wire codec, and release-gate model |
src/control |
Shared secure WDM control-device implementation |
src/test_driver |
Independent nested contract-test driver entry point |
drivers |
Separate INF packages for the two control services |
tests |
Source, ABI, artifact, and opt-in runtime checks |
tools |
Build, signing, certificate, and TESTSIGNING helpers |
The C++ and MASM frame layouts share src/asm/vmx_asm.inc and are guarded by
static assertions and contract tests. Change both sides together when editing
an offset or calling convention.
- Windows 11 25H2 x64 for the primary validation profile
- Visual Studio x64 C++ tools and MASM
- a Windows SDK and a matching Windows Driver Kit (WDK)
- CMake 3.23 or newer and Ninja
ntifs.h is provided by the WDK, not by the Windows SDK alone. Open the
repository from a Visual Studio Developer PowerShell. If more than one WDK is
installed, pass its root with -WdkRoot or -DWDK_CONTENT_ROOT.
To record the target before a hardware test, use these read-only commands:
Get-CimInstance Win32_OperatingSystem |
Select-Object Caption, Version, BuildNumber
Get-CimInstance Win32_Processor |
Select-Object -First 1 Name, NumberOfCores, NumberOfLogicalProcessorsRun these commands from the repository root in a Developer PowerShell:
$env:VSLANG = "1033"
cmake --preset vscode-debug
cmake --build --preset vscode-debug --parallel 4For an optimized image:
$env:VSLANG = "1033"
cmake --preset vscode-release
cmake --build --preset vscode-release --parallel 4VSLANG=1033 requests the MSVC message language where that resource is
installed; CMake also detects the compiler's /showIncludes prefix. It does
not change the language of the driver or the test binaries.
The output directory is build/vscode/<Configuration>/. Generated runtime
images are classified by kind, while linker PDB files stay in the
configuration root:
bin/KNHV_ContractTests.exebin/KNHV_NestedProbe.exebin/KNHV_NativeVmxProbe.exebin/KNHV_NativeLikeBench.exebin/KNHV_VmxExitBench.exebin/KNHV_TscQpcBench.exebin/KNHV_EptHookBench.exebin/KNHV_DeviceIoBench.exebin/KNHV_Preflight.exebin/KNHV_CpuMatrix.exebin/KNHV_WHPBroker.exebin/KNHV_EvidenceTool.exesys/KNHV.syssys/KNHV-Control.syssys/KNHV-NestedTest.sysKNHV*.pdb
CMakeFiles/ and Testing/ remain CMake's internal build directories. The
native self-test source is HV_PROBE_TESTER/native_vmx_probe.cpp.
The two auxiliary SYS files expose only the versioned control contract. They do
not execute physical VMXON; the current KNHV.sys remains the native,
late-launch research baseline. A physical top-level KNHV L0 requires a
separately validated boot-time handoff and is outside the current release
profile.
KNHV-NestedTest.sys advertises a deliberately marked
kFlagSyntheticSnapshot so the host-only nested model can be exercised. That
flag is laboratory-only: it is not evidence of a BootL0 handoff, VMCS02/EPT
hardware, WHP integration, or transparent passthrough. The current control
contract keeps VirtualizationReady=false for that synthetic path while still
allowing the model IOCTLs to run. It also uses a bounded session table, a
generation key, and the creating file-object binding. It still does not verify
a production image manifest/signature or provide a production broker identity.
Do not deploy these auxiliary images as a production hypervisor or as a
security boundary.
The control device also exposes an additive ABI v2 capability and lease
contract. IOCTL_KNHV_QUERY_CAPS_V2 is read-only; the acquire and release
lease calls require a versioned session key, a matching generation, and known
feature and policy bits. A hardware lease is returned only for a verified KNHV
Boot L0 owner. The nested test image can return a lease marked
kLeaseFlagSynthetic; that lease is a laboratory model and never authorizes
physical VMX, EPT, IOMMU, or DMA work. Unknown versions, truncated buffers,
stale generations, and unknown flags are rejected.
The CMake Tools integration exports compile_commands.json with the project
headers and WDK km include directory. After changing the WDK or toolchain,
run CMake: Delete Cache and Reconfigure. If IntelliSense still reports a
missing ntifs.h, reset the C/C++ IntelliSense database and reopen the source
file under src/vmx.
The default suite is host-only. It does not execute VMX instructions, load a driver, change TESTSIGNING, or start a service:
.\build\vscode\Debug\bin\KNHV_ContractTests.exe --root .
ctest --test-dir build\vscode\Debug --output-on-failureThe host-only suite includes provider-selection, BootL0 ownership-state, VMCS12/nested-instruction, EPT mapping/generation, debug-lease, and fixed-point TSC/QPC model tests. It does not load either auxiliary driver, change TESTSIGNING, or execute VMX instructions.
After the signed KNHV-NestedTest.sys test driver is running on an isolated
x64 Windows target, the dedicated probe can validate its public synthetic
nested-model device contract:
.\build\vscode\Release\bin\KNHV_NestedProbe.exe --caps-only
.\build\vscode\Release\bin\KNHV_NestedProbe.exeThe full probe opens \\.\KNHVNestedTest, registers the known laboratory
provider, and exercises VMXON, VMCS12 setup, VMLAUNCH, reflected L2 exits,
VMRESUME, VMXOFF, and session release. It does not execute physical VMX
instructions or verify a physical BootL0/VMCS02/EPT02 implementation.
On an isolated target where KNHV.sys is already running, the native VMX
self-test is available as:
.\build\vscode\Release\bin\KNHV_NativeVmxProbe.exeThe native probe must not be used as a nested or coexistence test. It checks only the existing KNHV VM-exit path and is intentionally separate from the synthetic nested-model probe.
The benchmark executables are host-only diagnostic tools. They use the common
knhv-bench-1 JSON schema; a .csv output contains sample columns only. The
five tools cover native-like CPU and memory work, TSC/QPC clock sampling,
synthetic VM-exit accounting, synthetic EPT-hook accounting, and a virtual
device-I/O queue. They do not execute physical VMX instructions, access PCI
devices, or enable DMA.
For a local baseline, write results to a directory owned by the caller:
.\build\vscode\Release\bin\KNHV_NativeLikeBench.exe `
--mode baseline --workload cpu,mem --duration-ms 1000 --repeat 3 `
--out results\native_like.jsontools/Run-Benchmarks.ps1 runs the host-only suite and records commands,
provenance, hashes, and result files in the output directory supplied by the
caller. The native-l0 and nested-l1 modes are capability-gated and fail
closed when a verified provider, owner, or nested capability is unavailable.
The device-I/O tool accepts only its explicit virtual profile; it never
detaches, resets, or transfers data to a physical device. Comparison mode
requires matching workload, scope, configuration, and host provenance before
reporting a result.
KNHV_Preflight.exe is the read-only gate for a future Native L0 target. It
reports CPUID, topology, firmware-table, Secure Boot, DeviceGuard, WHP, service,
and provider observations in knhv-preflight-1 JSON. Unknown privileged state
is retained as unknown and blocks a native-l0 profile; the tool never changes
boot policy, loads a driver, or executes VMX instructions.
The owner_observation and owner_gate fields record the selected action, reason, owner, and generation. Only a complete, active KNHV Boot L0 handoff can produce acquire-native; unknown or conflicting evidence remains blocked.
KNHV_CpuMatrix.exe is a separate read-only target-machine probe. It temporarily
binds one user-mode thread to each active logical processor, records the
observable CPUID feature set, restores the original affinity, and emits a
knhv-cpu-matrix-1 JSON file. A pass requires a complete uniform matrix with
VMX and Invariant TSC; a blocked result is expected when a hypervisor owns VMX,
affinity cannot be restored, or processors expose different features. VMX
control MSRs, EPT/VPID, and IOMMU are reported as unknown because they need
privileged target-side validation.
KNHV_EvidenceTool.exe is a host-only encoder and gate reader for the target
evidence contract. --emit-synthetic creates a clearly marked laboratory
package, --validate checks its fixed wire header and SHA-256 envelope digest,
and --gate evaluates profile, stage, generation, and required flags. The
tool never turns a synthetic package into hardware evidence. --verify-signature
uses Windows WinVerifyTrust with revocation checks disabled and cache-only URL
retrieval. It reports trusted, not-signed, untrusted, or
private-test-root without changing the certificate store or setting
SignatureVerified in a manifest. A private test root is accepted only with
the explicit --allow-test-root option and remains unsuitable as a production
signing result.
Example offline flow:
.\build\vscode\Release\bin\KNHV_EvidenceTool.exe `
--emit-synthetic evidence.bin --out evidence-emit.json
.\build\vscode\Release\bin\KNHV_EvidenceTool.exe `
--validate evidence.bin --out evidence-validate.json
.\build\vscode\Release\bin\KNHV_EvidenceTool.exe `
--gate evidence.bin --profile synthetic-lab --stage release
.\build\vscode\Release\bin\KNHV_EvidenceTool.exe `
--verify-signature .\build\vscode\Release\sys\KNHV.sys `
--out driver-signature.jsonThe pure knhv_vmx_capability contract is the next validation boundary for a
privileged target collector. It normalizes VMX control MSR masks, checks the
primary/secondary/tertiary dependency rules, and rejects a mixed per-CPU EPT,
VPID, or feature-control profile. The model contains no MSR or VMX instruction;
the target collector must provide the raw snapshots and retain the per-CPU
evidence.
The knhv_owner_observation contract provides an owner observation gate and
applies the same fail-closed rule to
ownership evidence. It combines CPUID hypervisor state, Windows hypervisor and
VBS/HVCI observations, provider state, boot-handoff evidence, and a generation
counter. Only an active KNHV Boot L0 with complete handoff evidence can return
acquire-native; an external owner, WHP owner, synthetic owner, or unknown
state receives an explicit action and reason. The model does not claim that
HyperDbg or another hypervisor can share physical VMX ownership, and it never
executes VMX or MSR instructions.
The knhv_target_evidence contract defines a versioned target evidence manifest
for future hardware collection and release gates. It binds the chosen profile,
stage, owner state, CPU coverage, artifact and PDB hashes, generation, signature
state, time/telemetry status, recovery readiness, and device or performance proof.
A gate accepts a manifest only when its requested profile, stage, generation,
verdict, and required evidence flags all match. The current model validates
supplied evidence only; it does not collect privileged state or claim that a
Native L0 hardware validation has completed.
The manifest writer is the host-only boundary that turns an already collected snapshot into the fixed manifest. It checks the snapshot's version, profile, stage, owner generation, source-clean observation, and signature result before writing it. Synthetic snapshots require an explicit laboratory flag and cannot carry hardware evidence. Native Intel capability and release profiles require target hardware evidence and a trusted signature; the writer never reads VMX, VT-d, DMA, device, or certificate-store state itself.
The target snapshot adapter is the boundary before the writer. It accepts a versioned snapshot plus raw per-processor CPU and VMX samples, recomputes both matrices, checks owner and generation consistency, and forwards only a valid candidate to the writer. The adapter is host-only; privileged collection and hardware execution remain explicit target-side operations.
The collector binding contract is the provenance boundary after package
verification. A target-side collector supplies its identity, capture id,
generation, timestamp window, sample counts, package digest, artifact hash, and
signature result. The host validator compares those fields with the decoded
snapshot and fails closed on stale, mixed, or incomplete evidence. It does not
make an unsigned record trusted and does not collect privileged state itself.
GetTargetEvidenceSnapshotPackageDigest exposes the digest only after the wire
header and stored SHA-256 have both been verified, so callers do not need to
reimplement package offsets.
For offline transport, KNHV_EvidenceTool.exe can encode the approved snapshot
and its raw samples into a bounded, SHA-256 protected package, then decode and
re-run the same validation before materializing a manifest:
.\build\vscode\Release\bin\KNHV_EvidenceTool.exe `
--emit-synthetic-snapshot snapshot.bin --out snapshot-emit.json
.\build\vscode\Release\bin\KNHV_EvidenceTool.exe `
--validate-snapshot snapshot.bin --out snapshot-validate.jsonAfter validation, the same executable can apply the profile, stage, and generation gate to the decoded snapshot in one operation:
.\build\vscode\Release\bin\KNHV_EvidenceTool.exe `
--gate-snapshot snapshot.bin --profile synthetic-lab --stage release `
--expected-generation 1 --out snapshot-gate.jsonA blocked or malformed package returns a nonzero exit code and never becomes a release manifest. This command evaluates supplied evidence only; it does not acquire VMX ownership, start a driver, or touch devices.
The synthetic command is a laboratory fixture only. A target collector must provide the real per-processor samples and a matching generation; malformed, truncated, or tampered packages are rejected before a manifest is written.
Run it once on the isolated validation target after copying the matching build:
.\build\vscode\Release\bin\KNHV_CpuMatrix.exe `
--out results\cpu_matrix.jsonKNHV_WHPBroker.exe dynamically loads the system WinHvPlatform.dll and
queries WHvGetCapability to emit a knhv-whp-probe-1 JSON snapshot. It does
not create a partition, map guest memory, create a vCPU, or execute a vCPU.
--run is intentionally blocked until a separately validated runner exists:
.\build\vscode\Release\bin\KNHV_WHPBroker.exe --caps-only `
--out results\whp_capabilities.jsonTo validate a built SYS and its matching PDB:
.\build\vscode\Debug\bin\KNHV_ContractTests.exe `
--root . `
--driver .\build\vscode\Debug\sys\KNHV.sysThe following checks are explicit opt-ins and belong only on the isolated Windows 11 25H2 / i7-14700KF target:
.\build\vscode\Debug\bin\KNHV_ContractTests.exe --root . --hardware
.\build\vscode\Debug\bin\KNHV_ContractTests.exe `
--root . `
--driver .\build\vscode\Debug\sys\KNHV.sys `
--signature `
--allow-test-root
.\build\vscode\Debug\bin\KNHV_ContractTests.exe `
--root . `
--driver .\build\vscode\Debug\sys\KNHV.sys `
--runtime --start --stop--signature expects a test-signed image. --runtime requires a prepared
service, a kernel debugger, and a recovery path. The test only stops a service
that it started itself.
Fault injection is disabled in normal builds. Use a separate build directory to validate a launch-rollback configuration:
$env:VSLANG = "1033"
cmake -S . -B build\vscode\FaultDebug -G Ninja `
-DCMAKE_BUILD_TYPE=Debug `
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON `
-DWDK_WINVER=0x0A00 `
-DKNHV_BUILD_TESTS=ON `
-DKNHV_FAULT_INJECTION=ON `
-DKNHV_TEST_FAIL_CPU=0 `
-DKNHV_TEST_FAIL_STAGE=8 `
-DKNHV_ARTIFACT_ROOT=build\vscode\FaultDebug
cmake --build build\vscode\FaultDebug --parallel 4
.\build\vscode\FaultDebug\bin\KNHV_ContractTests.exe `
--root . `
--driver .\build\vscode\FaultDebug\sys\KNHV.sysThis command validates the fault-injection build and its artifact contract; it does not load the driver or trigger a VMX launch.
KNHV_TEST_FAIL_CPU selects the logical processor and
KNHV_TEST_FAIL_STAGE selects a bounded stage. These hooks request a
controlled rollback; they do not emulate arbitrary hardware failures. To
exercise one, sign and register this separate SYS only on the isolated target,
attach KD, and retain the rollback log. The normal --runtime --start --stop
check expects a successful launch, so it is not the expected-result check for
an intentionally injected launch failure.
All scripts are intended to be run from the repository root. They use the installed Visual Studio and WDK rather than hard-coded compiler paths.
| Script | Purpose | State changes |
|---|---|---|
tools/Build-Driver.ps1 |
Discover VS/WDK, configure, and build unsigned SYS/EXE/PDB artifacts | Writes only the selected build directory using sys/, bin/, and the root for linker PDBs |
tools/Build-And-Sign-Driver.ps1 |
Build, create or reuse a local test certificate, then sign the SYS | Writes certs/, may install test certificates, and changes the SYS |
tools/Generate-Test-Certificate.ps1 |
Create a private Root CA and kernel-code-signing leaf certificate | Writes certs/ and may update certificate stores |
tools/Sign-Driver.ps1 |
Sign an existing SYS and verify Authenticode plus kernel policy | Changes the specified SYS; requires signtool.exe and a certificate |
tools/Set-TestSigning.ps1 |
Read or change Windows TESTSIGNING state | -Status is read-only; -Enable and -Disable change BCD and require a reboot |
tools/Run-Benchmarks.ps1 |
Run the host-only benchmark suite and write a reproducibility manifest | Writes only the caller-selected output directory |
.\tools\Build-Driver.ps1 -Configuration Debug
.\tools\Build-Driver.ps1 -Configuration Release
.\tools\Build-Driver.ps1 -Configuration Debug -ConfigureOnlyUse -WdkRoot 'C:\Program Files (x86)\Windows Kits\10' when automatic WDK
selection is not appropriate.
The legacy standalone probe entry point remains available from an x64 Native Tools Command Prompt:
cd HV_PROBE_TESTER
build_msvc.batIt writes build\standalone\bin\KNHV_NativeVmxProbe.exe and its PDB instead
of placing a binary beside the source file.
Signing is never enabled by the CMake presets. For an isolated test target:
.\tools\Build-And-Sign-Driver.ps1 -Configuration DebugThe generated private key and password stay under the ignored certs/
directory. Do not commit them. -Recreate on
Generate-Test-Certificate.ps1 replaces the local test chain and should only
be used when the existing chain is intentionally being retired.
For an existing certificate and SYS, the lower-level command is:
.\tools\Sign-Driver.ps1 `
-DriverPath .\build\vscode\Debug\sys\KNHV.sys `
-Certificate .\certs\KNHV_test.pfx `
-Password '<test-password>' `
-AllowUntrustedTestCertificateDo not put a real password in source control or shell history. A production release needs the platform's approved kernel-code-signing process; a private test root is not production trust.
.\tools\Set-TestSigning.ps1 -StatusOnly on the isolated test installation, from an elevated PowerShell:
.\tools\Set-TestSigning.ps1 -Enable
# reboot before loading a test-signed driver
.\tools\Set-TestSigning.ps1 -Disable
# reboot again after disabling test modeSecure Boot, enterprise policy, or firmware settings may reject TESTSIGNING. Do not change it on a production machine.
The implementation was informed by the Intel Software Developer's Manual and public research projects such as HyperDbg.
MIT License. See LICENSE.