<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Parag Mali - tag: project-zero</title><description>Posts tagged project-zero.</description><link>https://paragmali.com/</link><language>en-US</language><lastBuildDate>Sun, 07 Jun 2026 04:13:09 GMT</lastBuildDate><atom:link href="https://paragmali.com/tags/project-zero/rss.xml" rel="self" type="application/rss+xml"/><item><title>The Registry Adventure: How One Researcher Read 100,000 Lines of Windows Kernel C and Found 50 Bugs</title><link>https://paragmali.com/blog/the-registry-adventure-how-one-researcher-read-100000-lines-/</link><guid isPermaLink="true">https://paragmali.com/blog/the-registry-adventure-how-one-researcher-read-100000-lines-/</guid><description>Between May 2022 and December 2023, Mateusz Jurczyk audited the Windows registry parser and produced 50 CVEs. The methodology is the story.</description><pubDate>Sun, 24 May 2026 00:00:00 GMT</pubDate><content:encoded>
Between May 2022 and December 2023, Mateusz Jurczyk of Google Project Zero manually audited the Windows kernel registry parser and filed 39 bug reports under Project Zero&apos;s 90-day disclosure deadline plus 20 low-severity reports without deadline, which Microsoft serviced as 50 CVEs total (44 from the 90-day cohort and 6 more in a March 2024 bulletin). The bugs share a root cause: a thirty-year-old hybrid on-disk-and-in-memory format with a deterministic, unrandomized cell allocator that Microsoft cannot redesign without breaking backward compatibility to Windows NT 4.0. The methodology pivot is the story. Jurczyk started with a coverage-guided fuzzer, found one bug, then put the fuzzer down and read 100,000 lines of kernel C for twenty months. What the audit implies for the rest of the Windows kernel is the open question the article ends on.
&lt;h2&gt;1. I Loaded a Registry Hive From a Network Share and the Kernel Crashed&lt;/h2&gt;
&lt;p&gt;In May 2022, Mateusz Jurczyk pointed a coverage-guided fuzzer at the Windows registry. Within days the fuzzer crashed the kernel and produced CVE-2022-35768. Twenty months later, when he stopped, Jurczyk had filed thirty-nine bug reports against the same subsystem, Microsoft had assigned fifty CVEs to his name, and the fuzzer was sitting unused. Somewhere in those first few days, Jurczyk had realised that the bugs he actually wanted were ones a fuzzer could not see [@pz1-registry-adventure-1].&lt;/p&gt;
&lt;p&gt;The threat model is almost too small to fit on a slide. An unprivileged process running at Medium Integrity Level calls &lt;code&gt;RegLoadAppKey&lt;/code&gt; with the path of a file the attacker controls. The kernel opens the file, runs its in-house binary parser on the bytes, and exposes the resulting tree of keys back to the caller through a private handle. Microsoft&apos;s own documentation describes the surface this way: the hive becomes a private namespace reachable only through that handle, but &quot;the registry will prevent an application from accessing keys in this hive using an absolute path&quot; [@ms-regloadappkey]. The handle is sandboxed. The parser, which is the interesting part, is not. It runs in the kernel with attacker-supplied input, and it has been doing so since Windows Vista.&lt;/p&gt;

A file-and-in-memory tree of registry keys and values, encoded in Microsoft&apos;s regf binary format and operated on by the Windows kernel&apos;s Configuration Manager. Hives live on disk as `*.dat` files (plus `.log` and `.alt` companions) and are loaded into the kernel&apos;s address space when an application or the operating system opens them [@ms-registry-hives].

Medium Integrity Level: the integrity label an ordinary logged-in Windows user runs at. Crossing from Medium IL to SYSTEM is what a kernel local privilege escalation does. The class of bug this article is about reliably accomplishes that crossing from an attacker-supplied file.
&lt;p&gt;The fifty CVEs that Jurczyk&apos;s audit produced are not a uniform pile. Most of them are kernel local privilege escalations (LPEs); a handful are information disclosures; one is a denial of service [@pz1-registry-adventure-1]. The seventeen that matter for this article are the cohort Jurczyk later catalogued in his Project Zero post on practical exploitation: a tight set of memory-corruption bugs that share a single root cause and a single exploitation primitive, which he named &lt;strong&gt;hive-based memory corruption&lt;/strong&gt; [@pz8-registry-adventure-8].&lt;/p&gt;

flowchart TD
    A[&quot;Medium-IL user process&quot;] --&amp;gt; B[&quot;RegLoadAppKey API&quot;]
    B --&amp;gt; C[&quot;NtLoadKeyEx system call&quot;]
    C --&amp;gt; D[&quot;Configuration Manager dispatch&quot;]
    D --&amp;gt; E[&quot;Hv* hive parser&quot;]
    E --&amp;gt; F[&quot;Cell allocator and KCB tree&quot;]
    F --&amp;gt; G[&quot;Mapped section pages -- kernel address space&quot;]
&lt;p&gt;Two questions are doing all the work in this article. Why is a thirty-year-old binary parser running in the Windows kernel willing to accept arbitrary input from unprivileged users? And why did it take a single researcher twenty months to map the consequences? The first question is about Microsoft and design. The second is about Jurczyk and method. To take either one seriously, we have to start at the very beginning -- with Windows 3.1.&lt;/p&gt;
&lt;h2&gt;2. Why There Is a Hive Parser in the Kernel&lt;/h2&gt;
&lt;p&gt;In 1992 the registry was 64 kilobytes. Windows 3.1 shipped with a single file at &lt;code&gt;C:\WINDOWS\REG.DAT&lt;/code&gt;, encoded in a small custom format whose magic bytes spelled &lt;code&gt;SHCC3.10&lt;/code&gt;. It held one top-level key, no named values, and existed solely to register OLE objects and shell file-type associations [@pz2-registry-adventure-2]. The first &lt;code&gt;regedit.exe&lt;/code&gt; shipped alongside it. There was no security descriptor, no recovery story, and no kernel involvement. You could fit the whole thing in the L2 cache of a 2026 laptop.&lt;/p&gt;
&lt;p&gt;Windows NT 3.1, released in July 1993, swept that design away and introduced something different. The new format was called &lt;strong&gt;regf&lt;/strong&gt;, and the design decision that has determined the next thirty-three years of Windows kernel security was made here: &lt;em&gt;the on-disk format and the in-memory format are the same format&lt;/em&gt;. Jurczyk&apos;s blog post on the regf file format states this plainly: &quot;the regf format aims to bypass the reparsing step -- likely to optimize the memory/disk synchronization process -- and reconcile the two types of data encodings into a single one... This unique approach comes with its own set of challenges, and has been a contributing factor in a number of historical vulnerabilities&quot; [@pz5-registry-adventure-5].&lt;/p&gt;

Microsoft&apos;s binary registry file format, introduced in Windows NT 3.1 (1993) and stabilized at v1.3 in NT 4.0 (1996). Later versions (v1.4 Whistler beta, v1.5 XP, v1.6 Win10 AU) layer features on top but all remain cross-compatible with the v1.3 baseline. The same format encodes a hive on disk and in kernel memory; there is no separate &quot;loaded&quot; representation [@pz5-registry-adventure-5]. Microsoft has never published an official regf specification [@pz5-registry-adventure-5].
&lt;p&gt;The motivation was reasonable. NT was a multi-user, securable, network-capable operating system targeting servers; its configuration store needed access control, transactional recovery, and the ability to grow well past 64 KiB. Reusing the same byte layout for disk and memory meant a hive could be loaded by mapping or copying its file image, modified in place, and flushed back without a serialization step.&lt;/p&gt;
&lt;p&gt;Pre-release builds used regf v1.0; the first shipping NT used v1.1; NT 3.5 and 3.51 used v1.2 [@pz2-registry-adventure-2]. The Win9x consumer line went a different direction entirely, with an incompatible format called CREG that never made it into the NT lineage and quietly died with Windows Me.Windows 95, 98, and Me used a completely incompatible CREG format that did not survive into NT. The modern registry inherits nothing from the Win9x line; every memory corruption bug Jurczyk found descends from the NT 3.1 decision.&lt;/p&gt;
&lt;p&gt;The next stabilization happened on July 29, 1996. Windows NT 4.0 (whose pre-RTM development builds had introduced v1.3 in 1995) froze the &lt;em&gt;backward-compatibility baseline&lt;/em&gt; at regf v1.3, added a &quot;fast leaves&quot; optimization for subkey lookups, and locked in the binary layout that the modern Windows kernel still reads thirty years later. Later versions layered features on top -- v1.4 (Whistler beta, big values), v1.5 (Windows XP, 2001, hash leaves), and v1.6 (Windows 10 Anniversary Update, 2016, layered keys) -- but every one of them remains cross-compatible with v1.3-aware parsers, and v1.3 itself still encodes a number of Windows 11 hives [@pz5-registry-adventure-5].&lt;/p&gt;
&lt;p&gt;Microsoft&apos;s own documentation for &lt;code&gt;RegSaveKeyExA&lt;/code&gt; describes &lt;code&gt;REG_STANDARD_FORMAT&lt;/code&gt; as &quot;the only format supported by Windows 2000,&quot; meaning that hives written by Windows 2000 and later, in the default format, are interchangeable with hives produced by Windows NT 4.0 [@ms-regsavekeyex]. A hive file authored on NT 4.0 in 1996 will still mount on Windows 11 in 2026. That backward compatibility is not an accident; it is a load-bearing requirement of system-image management, forensics, and third-party installers.&lt;/p&gt;

gantt
    title Registry format evolution
    dateFormat YYYY
    axisFormat %Y
    section Win 3.x
    reg.dat (SHCC3.10) :1992, 1993
    section NT 3.x
    regf v1.0 to v1.2  :1992, 1996
    section NT 4.0+
    regf v1.3 (standard) :1996, 2026
    section XP
    regf v1.5 (hash leaves) :2001, 2026
    section Vista
    RegLoadAppKey + KTM  :2006, 2026
    section Win 8.1
    LOG1 and LOG2 logging :2013, 2026
    section Win 10 RS4
    Section-backed hives  :2018, 2026
    section Win 10 AU
    regf v1.6 (layered keys) :2016, 2026
&lt;p&gt;Ten years later, in November 2006, Windows Vista added the second design decision that completes the threat model. &lt;code&gt;RegLoadAppKey&lt;/code&gt; shipped as a public Win32 API, allowing an unprivileged application to load an arbitrary hive file as a private &quot;application hive&quot; reachable only through the returned handle [@ms-regloadappkey]. The motivation was legitimate; per-application configuration sidecars are a reasonable feature.&lt;/p&gt;
&lt;p&gt;The consequence was that the kernel-mode regf parser, frozen at v1.3 a decade earlier and unchanged in any of its load-bearing routines, was now reachable from Medium IL with no special privileges. Jurczyk&apos;s introduction to the series says it plainly: &quot;arbitrary registry hives can be loaded from disk without any special privileges via the &lt;code&gt;RegLoadAppKey&lt;/code&gt; API (since Windows Vista)&quot; [@pz1-registry-adventure-1].&lt;/p&gt;

A Win32 API introduced in Windows Vista (2006) that lets an unprivileged process load an arbitrary hive file as a private &quot;app hive,&quot; running the full kernel-mode regf parser on attacker-supplied bytes. Microsoft documents the API as one that &quot;loads the specified registry hive as an application hive&quot; reachable only through a private handle; the parser itself is not sandboxed [@ms-regloadappkey].
&lt;p&gt;With the parser reachable from low privilege and the format frozen for thirty years, the only question left was who would notice.&lt;/p&gt;
&lt;h2&gt;3. Prior Attempts: The &quot;Fuzzed Precisely Once&quot; Misconception&lt;/h2&gt;
&lt;p&gt;Before we go further, a fact you may have heard in a conference Q&amp;amp;A: the Windows registry is &quot;the most-fuzzed subsystem in Windows,&quot; &quot;fuzzed precisely once,&quot; by one person. It is not true. The registry has been poked at, in one form or another, since 1996. None of those efforts found the bug class that Jurczyk would eventually name -- but that is a different statement, and the difference is the point of this section.&lt;/p&gt;
&lt;p&gt;The first instrument to touch the registry from outside Microsoft was Mark Russinovich and Bryce Cogswell&apos;s &lt;strong&gt;RegMon&lt;/strong&gt;, released in 1996 as a Sysinternals utility. RegMon was a kernel driver that intercepted every registry call and surfaced the path, type, process identifier, and result to a user-mode console. It was operational tooling, not a bug-finding tool. Microsoft&apos;s own page on the modern successor, Process Monitor, attributes the lineage to Russinovich and notes that Procmon &quot;combines the features of two legacy Sysinternals utilities, Filemon and Regmon&quot; [@ms-procmon]. RegMon made the registry observable from outside the kernel. It could not see corruption inside a hive.&lt;/p&gt;
&lt;p&gt;The next wave came from forensics. Microsoft never published a regf specification, so the digital-forensics community reverse-engineered one. Timothy D. Morgan&apos;s regfi paper appeared at DFRWS in 2009. Joachim Metz&apos;s libregf project published its first format-spec document in July 2009 and has been updated continuously through 2026 [@libregf-spec]. Maxim Suhanov&apos;s regf specification covers, among other things, the old single-&lt;code&gt;.log&lt;/code&gt; dirty-vector recovery format and the new two-file LOG1/LOG2 layout introduced in Windows 8.1 [@msuhanov-spec]. These were user-space parsers built to mount hive files for evidence extraction. They exercised the format from the outside. They never touched the kernel parser.&lt;/p&gt;
&lt;p&gt;A separate research line, in parallel, pursued the layer &lt;em&gt;above&lt;/em&gt; the parser. James Forshaw of Project Zero spent years hunting capability and access-control bugs in the registry&apos;s name-resolution and permission logic -- registry symbolic links, virtualization quirks, sandbox-escape paths that ride on registry redirection. Jurczyk&apos;s PZ #4 covers some of this surface in passing, noting that the registry has at least four distinct ways in which &quot;access to a registry key can be transparently redirected to another path&quot; [@pz4-registry-adventure-4]. These were logic bugs, not memory-corruption bugs. The parser was not the target.&lt;/p&gt;
&lt;p&gt;Then, in 2016, Jurczyk and Forshaw collaborated on a black-box bitflipping fuzzing pass against &lt;code&gt;RegLoadKey&lt;/code&gt; and &lt;code&gt;RegLoadAppKey&lt;/code&gt;. Jurczyk acknowledges the collaboration directly in his retrospective: &quot;I was also somewhat familiar with basic harnessing of the registry, having fuzzed it in 2016 together with James Forshaw&quot; [@pz1-registry-adventure-1]. The cohort produced a handful of registry bug reports filed as Project Zero issues #873, #874, #876, and #993.&lt;/p&gt;
&lt;p&gt;It did not find the hive-memory-corruption class. The reason is the same one that would defeat the 2022 fuzzer: random byte flips on a hive file produce a malformed-but-rejected hive far more often than they produce one that passes base-block validation, enters the parser proper, and exercises an interesting bug.Per-issue contents of the 2016 cohort are not anonymously fetchable; the Project Zero tracker now lives at &lt;code&gt;project-zero.issues.chromium.org&lt;/code&gt; and redirects unauthenticated requests to a Google sign-in page [@pz-tracker-root]. The cohort&apos;s existence is primary-source-confirmed by Jurczyk&apos;s reference in PZ #1.&lt;/p&gt;

The hive binary format is not very well suited for trivial bitflipping-style fuzzing, because it is structurally simple, and random mutations are much more likely to render (parts of) the hive unusable than to trigger any interesting memory safety violations. -- Mateusz Jurczyk, *The Windows Registry Adventure #1* [@pz1-registry-adventure-1]
&lt;p&gt;In early 2022, Jurczyk made a more serious attempt. He built a &lt;strong&gt;coverage-guided Bochs-based kernel fuzzer&lt;/strong&gt;, the same lineage as his earlier Bochspwn work, and pointed it at the kernel&apos;s hive-loading path. Within days the harness produced its first registry kernel bug, filed as Project Zero issue #2299 and assigned CVE-2022-35768 by Microsoft. The fuzzer worked. It just did not scale to the bug class Jurczyk actually wanted, which is the part of the story that matters.&lt;/p&gt;
&lt;p&gt;A frequent third-party confusion is worth naming and dispatching here. &lt;strong&gt;Bochspwn Reloaded is not the registry-research tool.&lt;/strong&gt; The repository&apos;s own README describes the goal as detecting &quot;the disclosure of uninitialized kernel stack/heap memory,&quot; not memory corruption, and reports &quot;over 70 bugs in the Windows kernel&quot; found by the tool in 2017 and early 2018 [@bochspwn-reloaded-repo]. The 2018 white paper makes the same scope clear; the project&apos;s technical content is about shadow-memory representation and tainting stack frames and pool allocations to catch infoleaks [@bochspwn-reloaded-paper]. The 2022 Bochs-based registry harness is a separate, unreleased instrument sharing the lineage but not the codebase.&lt;/p&gt;

A 2018 Bochs-based Project Zero tool by Mateusz Jurczyk for detecting uninitialized kernel memory disclosures via taint tracking [@bochspwn-reloaded-repo]. *Not* the registry-audit instrument. The 2022 coverage-guided Bochs registry harness is a separate, unreleased tool that shares Bochspwn&apos;s general design but is not the public Bochspwn Reloaded repository.

flowchart LR
    A[&quot;RegMon (1996)&lt;br /&gt;Operational visibility&quot;] --&amp;gt; B[&quot;Forensic parsers&lt;br /&gt;regfi, libregf, msuhanov&lt;br /&gt;2008 to present&quot;]
    B --&amp;gt; C[&quot;Forshaw logic bugs&lt;br /&gt;Sym-links, virtualization&lt;br /&gt;2014 to present&quot;]
    C --&amp;gt; D[&quot;Jurczyk-Forshaw fuzz&lt;br /&gt;Bitflipping RegLoadKey&lt;br /&gt;2016&quot;]
    D --&amp;gt; E[&quot;Bochs coverage fuzz&lt;br /&gt;One good bug&lt;br /&gt;2022&quot;]
    E --&amp;gt; F[&quot;Jurczyk manual audit&lt;br /&gt;50 CVEs&lt;br /&gt;2022 to 2023&quot;]
&lt;p&gt;Every prior attempt had hit the same ceiling. The bug class lived in the code, not in the file. And the code had not yet been read.&lt;/p&gt;
&lt;h2&gt;4. Six Generations of Hardening Without Redesign&lt;/h2&gt;
&lt;p&gt;Between 1992 and 2018, Microsoft shipped six generations of registry changes. Not one of them redesigned the parser. Every generation added a feature, hardened a recovery path, lifted a scale limit, or shifted a memory model. Each of those changes also created new surface for the next decade&apos;s attackers. The cell allocator at the heart of the format has been substantively the same routine for twenty-five years.&lt;/p&gt;
&lt;p&gt;The table below collapses Stage 2&apos;s defensive arc into one view. Each row is a generation; the &quot;Surface effect&quot; column captures the bug class that became reachable as a side effect of the improvement.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Gen&lt;/th&gt;
&lt;th&gt;Year&lt;/th&gt;
&lt;th&gt;What was added&lt;/th&gt;
&lt;th&gt;Surface effect&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;A-1&lt;/td&gt;
&lt;td&gt;1992&lt;/td&gt;
&lt;td&gt;&lt;code&gt;reg.dat&lt;/code&gt; / SHCC3.10, 64 KiB OLE database&lt;/td&gt;
&lt;td&gt;None in the kernel; user-mode only [@pz2-registry-adventure-2]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A-2&lt;/td&gt;
&lt;td&gt;1993&lt;/td&gt;
&lt;td&gt;regf v1.0/v1.1, hybrid on-disk and in-memory&lt;/td&gt;
&lt;td&gt;Every memory-corruption bug class to follow [@pz5-registry-adventure-5]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A-3&lt;/td&gt;
&lt;td&gt;1996&lt;/td&gt;
&lt;td&gt;regf v1.3 lock-in, fast-leaves optimization&lt;/td&gt;
&lt;td&gt;30-year backward compatibility freezes the parser [@ms-regsavekeyex]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A-3b&lt;/td&gt;
&lt;td&gt;2001 / 2016&lt;/td&gt;
&lt;td&gt;regf v1.5 (XP, hash leaves), v1.6 (Win10 AU, layered keys)&lt;/td&gt;
&lt;td&gt;New features, same v1.3-cross-compatible parser core [@pz5-registry-adventure-5]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A-4&lt;/td&gt;
&lt;td&gt;2006&lt;/td&gt;
&lt;td&gt;&lt;code&gt;RegLoadAppKey&lt;/code&gt;, KTM transactions&lt;/td&gt;
&lt;td&gt;Parser becomes reachable from Medium IL with no privileges [@ms-regloadappkey]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A-5&lt;/td&gt;
&lt;td&gt;2013&lt;/td&gt;
&lt;td&gt;LOG1/LOG2 incremental write-ahead logging&lt;/td&gt;
&lt;td&gt;New log-replay path becomes attacker-influenceable [@pz5-registry-adventure-5]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A-6&lt;/td&gt;
&lt;td&gt;2018&lt;/td&gt;
&lt;td&gt;Section-backed hive mapping&lt;/td&gt;
&lt;td&gt;Pages become pageable; double-fetch class enabled [@pz5-registry-adventure-5]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Each row deserves a sentence. &lt;strong&gt;A-1&lt;/strong&gt; is the registry&apos;s prehistory; nothing here lives in the kernel, but the hierarchical key/value mental model is established. &lt;strong&gt;A-2&lt;/strong&gt; is the load-bearing decision: hybrid on-disk and in-memory format, modified in place [@pz5-registry-adventure-5]. &lt;strong&gt;A-3&lt;/strong&gt; is the moment Microsoft signed a thirty-year contract; the format defined by &lt;code&gt;REG_STANDARD_FORMAT&lt;/code&gt; is binary-compatible with NT 4.0 [@ms-regsavekeyex].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A-3b&lt;/strong&gt; is the format-level feature layering done since: v1.5 (Windows XP, 2001) added hash leaves to speed up large subkey lookups, and v1.6 (Windows 10 Anniversary Update, 2016) added layered keys for differencing hives; both stay cross-compatible with v1.3-aware parsers, and v1.3 still encodes a number of Windows 11 hives [@pz5-registry-adventure-5]. &lt;strong&gt;A-4&lt;/strong&gt; is the entry-point change: &lt;code&gt;RegLoadAppKey&lt;/code&gt; and the Kernel Transaction Manager arrive together in Vista, and both are now attacker-reachable [@ms-regloadappkey].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A-5&lt;/strong&gt; introduces the new log format; PZ #5 describes &quot;incremental logging added in Windows 8.1&quot; as one of the two big runtime-recovery overhauls of the modern era [@pz5-registry-adventure-5]. &lt;strong&gt;A-6&lt;/strong&gt; is the section-backed mapping shipped in Windows 10 RS4 (April 2018), and is the change that makes a hive on an SMB share into a moving target -- hive pages become pageable, and a page that was validated on load can be evicted and re-read with different contents [@pz5-registry-adventure-5].Some Windows 11 system hives, such as &lt;code&gt;UsrClass.dat&lt;/code&gt; under &lt;code&gt;HKU\&amp;lt;SID&amp;gt;_Classes&lt;/code&gt;, are still written in regf v1.3 -- a format frozen in 1996. The backward-compatibility freeze is not a hypothetical concern [@pz5-registry-adventure-5].&lt;/p&gt;

The unit of allocation inside a hive. A length-prefixed chunk of bytes; positive prefix means the cell is free, negative prefix means it is allocated, and the absolute value of the prefix is the size in bytes (multiples of eight). Cells are the building blocks of keys, values, security descriptors, and index nodes [@msuhanov-spec].

Key Control Block: the in-memory kernel object that represents an open registry key. It holds the cell index of the on-disk key node, a parent pointer, a refcount, and a per-key synchronization primitive [@pz6-registry-adventure-6]. The KCB tree is the live representation of every currently-open registry key.
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Each generation added new mitigation, new performance, or new functionality. None redesigned the cell allocator, the cell-index-to-virtual-address translation, or the hybrid on-disk-and-in-memory layout. Six generations of mitigation; one unmoved load-bearing routine.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Mapping the result is helpful before we get to the audit. Here is what a hive looks like in the 2025-era kernel from the bytes on disk up to the kernel-object tree that user-mode code touches.&lt;/p&gt;

flowchart TD
    A[&quot;Hive file on disk&lt;br /&gt;REGF base block + HBINs&quot;] --&amp;gt; B[&quot;Memory-mapped section&lt;br /&gt;pageable pages&quot;]
    B --&amp;gt; C[&quot;_HHIVE structure&lt;br /&gt;0x600 bytes, hive descriptor&quot;]
    C --&amp;gt; D[&quot;_CMHIVE structure&lt;br /&gt;0x12F8 bytes, kernel state&quot;]
    D --&amp;gt; E[&quot;Cell map&lt;br /&gt;cell-index translation&quot;]
    E --&amp;gt; F[&quot;Hv* allocator&lt;br /&gt;HvAllocateCell, HvFreeCell&quot;]
    F --&amp;gt; G[&quot;KCB tree&lt;br /&gt;open keys in kernel memory&quot;]
    G --&amp;gt; H[&quot;User-mode handles via NtCreateKey&quot;]
&lt;p&gt;The diagram is not a model; it is the structure. PZ #6 documents the exact sizes: &lt;code&gt;_CMHIVE&lt;/code&gt; is 0x12F8 bytes and contains an embedded &lt;code&gt;_HHIVE&lt;/code&gt; of 0x600 bytes at offset zero [@pz6-registry-adventure-6]. None of these objects existed in NT 3.1; what existed was the bottom three layers and a simpler kernel-side wrapper. The architecture grew. The cell allocator did not.&lt;/p&gt;
&lt;p&gt;By 2018 the parser had been substantively unchanged for twenty-five years, and nobody had read all of it.&lt;/p&gt;
&lt;h2&gt;5. The Pivot: Audit, Not Fuzz&lt;/h2&gt;
&lt;p&gt;Return to May 2022, but now with the full context loaded. Six generations of hardening have created a thirty-year-old attack surface. Forty years of forensic and security research have not penetrated the parser. Jurczyk is sitting at his desk with a working coverage-guided Bochs harness and one good registry bug, and instead of letting the fuzzer run for another six months, he stops.&lt;/p&gt;
&lt;p&gt;The detective work that produced the stop is documented in the introduction to the series. Jurczyk noticed two facts that together amount to a methodology critique.&lt;/p&gt;
&lt;p&gt;First, the regf format is &quot;structurally simple&quot; in the sense that bitflipping a random byte usually produces an invalid base-block checksum, an out-of-range cell offset, or some other condition that the kernel rejects long before it reaches anything interesting [@pz1-registry-adventure-1]. The base-block validator is doing a lot of work.&lt;/p&gt;
&lt;p&gt;Second, the bug class he was chasing -- one that produces kernel memory corruption from an attacker-controlled hive -- requires &lt;em&gt;legal-on-disk&lt;/em&gt; hives that exercise particular &lt;em&gt;combinations&lt;/em&gt; of features. The interesting bugs live in interactions: transactions plus virtualization plus predefined keys plus log replay, all in the same legal hive image. No byte-level mutator is going to synthesize that.&lt;/p&gt;
&lt;p&gt;So Jurczyk did something almost retro. He pulled &lt;code&gt;ntoskrnl.exe&lt;/code&gt; with public PDB symbols into the kind of static-and-dynamic analysis toolchain PZ #3 enumerates -- IDA Pro for cross-referencing, WinDbg attached to a kernel target, Ghidra alongside [@pz3-registry-adventure-3] -- and started reading the Configuration Manager. He cross-referenced every entry point against &lt;code&gt;libregf&lt;/code&gt;, against Suhanov&apos;s spec, and against &lt;em&gt;Windows Internals, Part 2, 7th edition&lt;/em&gt; by Allievi, Russinovich, Ionescu, and Solomon [@winint7-part2; @libregf-spec; @msuhanov-spec]. Every attacker-reachable function got traced to every cell read, write, free, and allocation on every path. PZ #3 lists the bibliography he assembled along the way and marks the Russinovich book with the equivalent of a gold star [@pz3-registry-adventure-3]. The methodology is twentieth-century. The yield is not.&lt;/p&gt;
&lt;p&gt;The numbers came in twenty months later. Per PZ #1, the audit produced 39 bug reports, which Microsoft serviced as 44 CVEs in the 90-day cohort plus 6 more in a March 2024 low-severity batch, for 50 CVEs total; the average time from report to fix was 81 days [@pz1-registry-adventure-1]. By December 2024, with more Microsoft CVE assignments rolling in, PZ #5 was reporting 52 CVEs [@pz5-registry-adventure-5]. By May 2025, PZ #7 was at 53 [@pz7-registry-adventure-7]. The growth across the publication arc reflects CVE assignment, not new discoveries. &quot;50+&quot; is the safe headline figure.&lt;/p&gt;
&lt;p&gt;Inside those 50 CVEs, a tight subset of 17 share a single root cause and a single exploitation primitive [@pz8-registry-adventure-8]. Jurczyk&apos;s PZ #8 gives them a name -- &lt;strong&gt;hive-based memory corruption&lt;/strong&gt; -- and divides them into two subclasses. &lt;em&gt;Spatial&lt;/em&gt; violations are cell-boundary overflows: writes that cross the boundary of a legitimately-allocated cell into an adjacent cell whose type, owner, or pointer the attacker now controls. &lt;em&gt;Temporal&lt;/em&gt; violations are cell-reuse use-after-frees: writes through a cell-index reference whose backing storage has been freed and reallocated to attacker-influenced content. Spatial and temporal together; everything else is detail.&lt;/p&gt;

Mateusz Jurczyk&apos;s coinage for the bug class that corrupts the in-memory representation of an active hive via the deterministic cell allocator [@pz8-registry-adventure-8]. The spatial subclass is cell-boundary overflows. The temporal subclass is cell-reuse use-after-frees. The class is named in PZ #8 and demonstrated on Windows 11 with all modern kernel mitigations enabled.
&lt;p&gt;The exploitation primitive is the deliberate engineering of the cell allocator, and PZ #8 is unsentimental about it.&lt;/p&gt;

The registry cell allocator... completely lacks any safeguards against memory corruption, and... has no element of randomness, making its behavior entirely predictable. -- Mateusz Jurczyk, *The Windows Registry Adventure #8* [@pz8-registry-adventure-8]
&lt;p&gt;A deterministic, unrandomized allocator with no integrity checks on its cell metadata is what you would design if you wanted recovery from a torn write to produce the same byte image every time. It is also, identically, what you would design if you wanted an exploit primitive that places a controlled object at a predictable cell index. The property that makes the parser correct under crash recovery and the property that makes it exploitable are the same property.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The bug class was semantic. The fuzzer was syntactic. That mismatch is the audit&apos;s entire reason for existing.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;How does an attacker-controlled hive actually become a corruption primitive? The sequence is shorter than you might expect.&lt;/p&gt;

sequenceDiagram
    participant U as Medium-IL process
    participant K as Configuration Manager
    participant V as Base-block validator
    participant P as Bin and cell parser
    participant A as Cell allocator
    U-&amp;gt;&amp;gt;K: RegLoadAppKey(hive_path)
    K-&amp;gt;&amp;gt;V: Validate REGF header
    V-&amp;gt;&amp;gt;P: Walk HBINs, accept legal cells
    P-&amp;gt;&amp;gt;A: Reserve cell indices for keys, values, security
    A-&amp;gt;&amp;gt;P: Hand back deterministic indices
    P-&amp;gt;&amp;gt;K: Build cell map, expose KCB
    Note over A,P: Attacker-shaped cells now live at predictable kernel addresses
    K-&amp;gt;&amp;gt;U: Return private handle
    U-&amp;gt;&amp;gt;K: Trigger second-stage operation (e.g., transaction abort)
    K-&amp;gt;&amp;gt;A: Spatial or temporal violation fires
&lt;p&gt;The diagram makes the loss of generality clear. The base-block validator does its job; the bin and cell parser accept a &lt;em&gt;legal&lt;/em&gt; hive; the cell allocator places attacker-shaped cells at &lt;em&gt;deterministic&lt;/em&gt; indices; and then a second-stage operation -- a transaction abort, a log replay, a predefined-key dereference -- reuses a cell index whose backing storage no longer means what the kernel assumes. There is no point in the lifecycle where a fuzzer&apos;s mutator could have engineered the legal-on-disk-but-semantically-explosive hive that the audit&apos;s reader engineered by hand.&lt;/p&gt;
&lt;p&gt;Coverage-guided fuzzing and manual audit are not equivalent tools on this target. The empirical numbers from the same researcher, on the same target, are instructive.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Researcher-months&lt;/th&gt;
&lt;th&gt;Good registry kernel bugs&lt;/th&gt;
&lt;th&gt;Empirical rate&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Bitflipping fuzz of &lt;code&gt;RegLoadKey&lt;/code&gt; / &lt;code&gt;RegLoadAppKey&lt;/code&gt; (2016)&lt;/td&gt;
&lt;td&gt;~few [@pz1-registry-adventure-1]&lt;/td&gt;
&lt;td&gt;4 (PZ #873, #874, #876, #993)&lt;/td&gt;
&lt;td&gt;~1 per month or worse&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bochs coverage-guided harness (early 2022)&lt;/td&gt;
&lt;td&gt;~1 to 2&lt;/td&gt;
&lt;td&gt;1 (CVE-2022-35768)&lt;/td&gt;
&lt;td&gt;~0.5 to 1 per month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Manual audit (May 2022 -- December 2023)&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;td&gt;50 CVEs across 39 reports [@pz1-registry-adventure-1]&lt;/td&gt;
&lt;td&gt;~2.5 CVEs per month&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;To understand why hive-based memory corruption works as a primitive, we have to look at what the parser actually is.&lt;/p&gt;
&lt;h2&gt;6. Anatomy of the Configuration Manager&lt;/h2&gt;
&lt;p&gt;If you want to find bugs in the registry, you have to know exactly what a hive is. Here is what one looks like on disk and in memory.&lt;/p&gt;
&lt;p&gt;A hive begins with a &lt;strong&gt;base block&lt;/strong&gt;: a 4 KiB header that contains the magic string &lt;code&gt;regf&lt;/code&gt;, the format version (v1.3 in modern hives), a sequence-number pair for crash recovery, a checksum, the root cell index, the hive length, the boot type and recovery information [@pz5-registry-adventure-5; @libregf-spec]. The validator that runs at hive load time vets this block first. If the checksum does not match, if the version is unrecognized, if the lengths do not add up, the parser refuses the file and no further code runs. This is the line of defense that ate 99% of the bitflipping fuzzer&apos;s effort in 2016 and again in 2022.&lt;/p&gt;
&lt;p&gt;After the base block come one or more &lt;strong&gt;HBIN&lt;/strong&gt; blocks. Each HBIN is a 4-KiB-multiple chunk of the hive carved into cells. Microsoft&apos;s documentation on registry hives describes the on-disk supporting files alongside the main hive: an &lt;code&gt;.alt&lt;/code&gt; backup of the critical &lt;code&gt;HKLM\System&lt;/code&gt; hive, a &lt;code&gt;.log&lt;/code&gt; transaction log, and a &lt;code&gt;.sav&lt;/code&gt; backup [@ms-registry-hives]. The HBIN is the layer the cells live in.&lt;/p&gt;
&lt;p&gt;A &lt;strong&gt;cell&lt;/strong&gt; is a length-prefixed chunk of bytes whose first 32-bit field is a signed integer. Positive means free, negative means allocated, and the absolute value is the cell size in bytes (cells are 8-byte aligned). The Suhanov spec documents the convention plainly, alongside the cell types we are about to walk through [@msuhanov-spec]. The signed-size convention is not just a curiosity; it is the load-bearing invariant that the cell allocator must protect, and it is the convention an attacker exploits when they convince the kernel to walk one allocated cell into the next.&lt;/p&gt;
&lt;p&gt;{`
// Demonstrates the regf signed-size cell convention from Suhanov&apos;s spec.
// A cell whose first 32-bit field is positive is FREE.
// A cell whose first 32-bit field is negative is ALLOCATED; |size| is bytes.&lt;/p&gt;
&lt;p&gt;function readCellHeader(buf, offset) {
  const raw = new DataView(buf).getInt32(offset, true); // little-endian
  const allocated = raw &amp;lt; 0;
  const sizeBytes = Math.abs(raw);
  return { allocated, sizeBytes, raw };
}&lt;/p&gt;
&lt;p&gt;// Build a 16-byte buffer: cell #1 allocated, 16 bytes, then a sentinel.
const buf = new ArrayBuffer(20);
new DataView(buf).setInt32(0, -16, true); // header: -16 -&amp;gt; allocated, 16 B
new DataView(buf).setInt32(16, 1234, true); // sentinel &quot;next cell&quot; prefix&lt;/p&gt;
&lt;p&gt;console.log(&quot;Cell 1:&quot;, readCellHeader(buf, 0));
console.log(&quot;Cell 2 sentinel:&quot;, readCellHeader(buf, 16));&lt;/p&gt;
&lt;p&gt;// A trivial validator that only checks &quot;is the size positive after abs()&quot;
// will accept a maliciously flipped header that overlaps into the next cell.
const tampered = buf.slice();
new DataView(tampered).setInt32(0, -24, true); // size now spans into cell 2
console.log(&quot;Tampered cell 1:&quot;, readCellHeader(tampered, 0));
`}&lt;/p&gt;
&lt;p&gt;A hive holds a small number of cell types. The five that matter for security analysis are catalogued below. Each describes a different on-disk concept, and each can be malformed in ways the parser must catch.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Cell type&lt;/th&gt;
&lt;th&gt;Signature&lt;/th&gt;
&lt;th&gt;What it stores&lt;/th&gt;
&lt;th&gt;Failure mode&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Key node&lt;/td&gt;
&lt;td&gt;&lt;code&gt;nk&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A registry key: name, parent index, child-list index, value-list index, security index, timestamp [@libregf-spec]&lt;/td&gt;
&lt;td&gt;Dangling indices; malformed name length; recursive parenting&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Value&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vk&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A registry value: name, type tag, length, inline data or data-block index [@libregf-spec]&lt;/td&gt;
&lt;td&gt;Length-versus-buffer mismatch; type-tag confusion&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Security descriptor&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sk&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A security descriptor for one or more keys; reference-counted [@libregf-spec]&lt;/td&gt;
&lt;td&gt;Refcount underflow on shared SDs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Index node&lt;/td&gt;
&lt;td&gt;&lt;code&gt;lf&lt;/code&gt; / &lt;code&gt;lh&lt;/code&gt; / &lt;code&gt;li&lt;/code&gt; / &lt;code&gt;ri&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A subkey list: leaves with hash hints, intermediate ri lists [@msuhanov-spec]&lt;/td&gt;
&lt;td&gt;Out-of-order entries; phantom subkeys&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Big-data block&lt;/td&gt;
&lt;td&gt;&lt;code&gt;db&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;A continuation cell for values larger than 16,344 bytes (just under 16 KiB) [@libregf-spec]&lt;/td&gt;
&lt;td&gt;Length math overflow; truncated continuation&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Between the cells and the parser sits a layer most people do not know about: the &lt;strong&gt;cell map&lt;/strong&gt;. Bins are not guaranteed to be contiguously mapped in kernel virtual address space, so the Configuration Manager maintains a page-table-like indirection that translates a 32-bit cell index into a virtual address. PZ #6 documents this in detail in its discussion of &lt;code&gt;_HHIVE&lt;/code&gt; and &lt;code&gt;_CMHIVE&lt;/code&gt;, with the latter spanning 0x12F8 bytes and the former 0x600 bytes at offset zero [@pz6-registry-adventure-6].Per PZ #6: &lt;code&gt;_CMHIVE&lt;/code&gt; is 0x12F8 bytes and contains an embedded &lt;code&gt;_HHIVE&lt;/code&gt; of 0x600 bytes at offset 0. The depth of Jurczyk&apos;s reverse-engineering is reflected in these exact offsets, which are not in any Microsoft-published documentation.&lt;/p&gt;

A page-table-like indirection layer that translates a 32-bit cell index into a kernel virtual address [@pz6-registry-adventure-6]. The cell map exists because the bins making up a hive are not guaranteed to be contiguously mapped. Most cell-boundary exploitation primitives walk through the cell map.

flowchart LR
    A[&quot;32-bit cell index&quot;] --&amp;gt; B[&quot;Directory index&quot;]
    A --&amp;gt; C[&quot;Table index&quot;]
    A --&amp;gt; D[&quot;Cell offset within bin&quot;]
    B --&amp;gt; E[&quot;Cell map directory&quot;]
    E --&amp;gt; F[&quot;Cell map table&quot;]
    C --&amp;gt; F
    F --&amp;gt; G[&quot;Bin base address&quot;]
    D --&amp;gt; G
    G --&amp;gt; H[&quot;Kernel virtual address of cell&quot;]
&lt;p&gt;The cell allocator itself -- &lt;code&gt;HvAllocateCell&lt;/code&gt;, &lt;code&gt;HvReallocateCell&lt;/code&gt;, &lt;code&gt;HvFreeCell&lt;/code&gt; [@pz8-registry-adventure-8] -- is small, deterministic, and unrandomized. There is no allocator metadata integrity check; freed cells are eagerly reused; cell placement is a function of the bins&apos; free lists, which the attacker can influence by shaping the input hive. Combined with the cell map, the result is that the attacker can place a chosen byte pattern at a chosen cell index with reasonable predictability, and -- because the same allocator services both attacker-influenced and kernel-managed cells -- the attacker can place that pattern &lt;em&gt;adjacent&lt;/em&gt; to a kernel-managed object whose corruption hands them an elevation primitive [@pz8-registry-adventure-8].&lt;/p&gt;
&lt;p&gt;Since Windows 10 RS4, hive pages are not copied into the paged kernel pool; they are backed by &lt;strong&gt;memory-mapped sections&lt;/strong&gt; that can be paged in from the underlying file [@pz5-registry-adventure-5]. The performance and footprint benefits are real. The security side effect is a new bug class: the kernel can read a hive byte at validation time, then read the same byte again at use time, and the underlying page can have been re-fetched in between. This is the &lt;strong&gt;double-fetch&lt;/strong&gt; pattern, and CVE-2024-43452 -- a double-fetch while loading hives from remote network shares -- is the canonical example Jurczyk cites in PZ #5 [@pz5-registry-adventure-5].&lt;/p&gt;

A vulnerability pattern where the kernel reads the same attacker-influenced memory location twice and treats both reads as authoritative. The section-backed registry (Windows 10 RS4) made hive pages pageable, which enables this on hive files served from remote SMB shares: between the kernel&apos;s two reads, the attacker swaps the byte under the kernel&apos;s feet. CVE-2024-43452 is the canonical example [@pz5-registry-adventure-5].
&lt;p&gt;A small but stubborn misconception about the registry deserves a callout before we move on. The registry is not lock-free. The Configuration Manager uses &lt;strong&gt;pushlocks&lt;/strong&gt; -- a Windows kernel synchronization primitive supporting shared and exclusive modes -- on a per-Key-Control-Block basis, plus a hive-wide pushlock for operations that touch the hive globally [@pz6-registry-adventure-6]. PZ #6&apos;s discussion of &lt;code&gt;_CMHIVE&lt;/code&gt; and &lt;code&gt;_HHIVE&lt;/code&gt; documents the pushlock placements directly. The design is fine-grained pushlock synchronization, not lock-free concurrency, and the difference matters because temporal hive-memory-corruption bugs frequently exploit the &lt;em&gt;gap between unlocking a parent and re-locking it&lt;/em&gt;, which exists in pushlock designs and would not exist in a true lock-free one.&lt;/p&gt;

A Windows kernel synchronization primitive supporting shared and exclusive modes [@pz6-registry-adventure-6]. The registry uses per-KCB pushlocks and a hive-wide pushlock. The implementation is *not* lock-free; that is a third-party misconception, and several of Jurczyk&apos;s temporal hive-memory-corruption bugs exploit the moment a pushlock is released and re-acquired.
&lt;p&gt;Two other runtime subsystems sit on top of the parser. The Kernel Transaction Manager (KTM) lets registry writes be grouped into atomic, rollbackable transactions; KTM rides on the Common Log File System (CLFS).KTM&apos;s CLFS backing is interesting in its own right: CLFS has had its own significant CVE history, and a transactional registry write whose KTM log can be tampered with reaches a separate kernel subsystem with its own attack surface. The transactional layer is one of the &quot;semantic combinators&quot; Jurczyk explicitly lists as outside the syntactic-fuzzer reach.&lt;/p&gt;
&lt;p&gt;Incremental write-ahead logging via LOG1 and LOG2 provides crash-recoverable durability for individual writes that have not yet been flushed to the main hive [@pz5-registry-adventure-5]. Both layers add features. Both layers add cell-lifetime states the parser must reason about. Both layers contributed bugs to the audit.&lt;/p&gt;
&lt;p&gt;The PZ #1 summary breakdown of the 50-CVE cohort is the clearest single statistic in the entire series.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Count&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Elevation of privilege&lt;/td&gt;
&lt;td&gt;39 [@pz1-registry-adventure-1]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Information disclosure&lt;/td&gt;
&lt;td&gt;9 [@pz1-registry-adventure-1]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Memory information disclosure&lt;/td&gt;
&lt;td&gt;1 [@pz1-registry-adventure-1]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Denial of service&lt;/td&gt;
&lt;td&gt;1 [@pz1-registry-adventure-1]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;50&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Of those 50, the subset PZ #8 picks out as exploitable via the hive-memory-corruption primitive numbers seventeen: CVE-2022-34707, CVE-2022-34708, CVE-2022-37956, CVE-2022-37988, CVE-2022-38037, CVE-2023-21675, CVE-2023-21748, CVE-2023-23420, CVE-2023-23421, CVE-2023-23422, CVE-2023-23423, CVE-2023-28248, CVE-2023-35382, CVE-2023-38139, CVE-2024-26182, CVE-2024-43641, and CVE-2024-49114 [@pz8-registry-adventure-8]. Seventeen kernel LPEs from one researcher, one subsystem, one bug class, one exploitation primitive.&lt;/p&gt;
&lt;p&gt;Microsoft has known about every one of these issues since the day they were reported. Why has the parser not been rewritten?&lt;/p&gt;
&lt;h2&gt;7. Why Doesn&apos;t Microsoft Just Rewrite It?&lt;/h2&gt;
&lt;p&gt;The first thing anyone asks after seeing the architecture is the obvious question. Why doesn&apos;t Microsoft rewrite this thing? The answer is, roughly, &quot;because they cannot.&quot;&lt;/p&gt;
&lt;p&gt;Backward compatibility is the dominant constraint. A hive file from NT 4.0 in 1996 still mounts on Windows 11 in 2026; that is the published behaviour of &lt;code&gt;REG_STANDARD_FORMAT&lt;/code&gt; in &lt;code&gt;RegSaveKeyExA&lt;/code&gt; [@ms-regsavekeyex]. Three decades of system images, third-party installers, forensic tooling, configuration-management products, and group-policy templates depend on the regf v1.3 format being readable. A new on-disk format with a hardened in-memory representation would not be a parser change; it would be the kind of compatibility break Microsoft has not made since the move from Win9x to NT.&lt;/p&gt;
&lt;p&gt;There are databases inside Windows that look like reasonable alternatives at a glance. None of them is a drop-in replacement, for reasons that have less to do with their internals than with what the registry is asked to do.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;System&lt;/th&gt;
&lt;th&gt;Implementation&lt;/th&gt;
&lt;th&gt;Used for&lt;/th&gt;
&lt;th&gt;Why it is not a drop-in&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Registry&lt;/td&gt;
&lt;td&gt;regf, kernel parser&lt;/td&gt;
&lt;td&gt;All Windows configuration, COM, security, policy [@ms-structure-registry]&lt;/td&gt;
&lt;td&gt;The thing we are auditing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ESE&lt;/td&gt;
&lt;td&gt;&lt;code&gt;esent.dll&lt;/code&gt;, full ACID DB&lt;/td&gt;
&lt;td&gt;Active Directory, Windows Search, Mail, Exchange [@winint7-part2]&lt;/td&gt;
&lt;td&gt;Different access model; userland; not designed for boot-path config&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LSA Secrets / &lt;code&gt;SECURITY&lt;/code&gt; hive&lt;/td&gt;
&lt;td&gt;regf substrate, restricted access&lt;/td&gt;
&lt;td&gt;Cached credentials, Kerberos keys [@winint7-part2]&lt;/td&gt;
&lt;td&gt;Same parser, same bug class -- moving the lock does not move the bug&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href=&quot;https://paragmali.com/blog/the-object-manager-namespace/&quot; rel=&quot;noopener&quot;&gt;Object Manager Namespace&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Kernel object directory&lt;/td&gt;
&lt;td&gt;Named kernel objects (events, mutexes, sections)&lt;/td&gt;
&lt;td&gt;Different threat model; not a config store&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MSIX / AppX state&lt;/td&gt;
&lt;td&gt;Per-package JSON/XML in app container&lt;/td&gt;
&lt;td&gt;UWP/Store-app configuration&lt;/td&gt;
&lt;td&gt;New apps only; cannot host legacy registry consumers&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;ESE&lt;/strong&gt; -- the Extensible Storage Engine -- is the closest existing internal candidate. It is a full ACID embedded database, used by Active Directory and Windows Search, and it is much better-engineered as a storage layer than regf is. It is also userland, designed for very different consumers, and not on the kernel boot path. Reusing it would require porting every kernel-mode registry caller across the kernel-user boundary, which has performance implications that nobody has signed off on publicly.&lt;/p&gt;

Microsoft&apos;s Extensible Storage Engine, an embedded ACID database implemented in `esent.dll`. Active Directory, Windows Search, Exchange, and Windows Mail all use it as their internal data store [@winint7-part2]. It is a much more modern design than the registry&apos;s regf, but it is userland, not boot-path, and its access model is different enough that it is not a drop-in replacement for the kernel-mode configuration store.
&lt;p&gt;The &lt;strong&gt;LSA Secrets&lt;/strong&gt; and &lt;code&gt;SECURITY&lt;/code&gt; hive are even more instructive. They are regf-format hives with stricter access controls. They inherit the entire hive-memory-corruption bug class verbatim; restricting &lt;em&gt;who&lt;/em&gt; can talk to the parser does not change &lt;em&gt;what&lt;/em&gt; the parser does with the bytes it receives.&lt;/p&gt;

The Windows kernel has another old, hierarchical, semantically-rich subsystem that has not been audited at this scale: the Object Manager Namespace, which exposes named kernel objects (events, sections, mutexes, devices, symbolic links) through a path-like API. It is the same era as the registry, the same kind of in-kernel data structure with a path-resolution layer, the same authorization model that has been hardened incrementally over thirty years. James Forshaw&apos;s work has touched it in places; no one has yet read it the way Jurczyk read the Configuration Manager. The Object Manager Namespace is the most plausible next target for a Jurczyk-style audit by anyone who wants to repeat the result on a different subsystem.
&lt;p&gt;The structural argument is the one to remember. The registry&apos;s on-disk format and its in-memory format are the same format, and its recovery semantics depend on deterministic cell placement; the attack surface and the recovery semantics are therefore literally the same code [@pz5-registry-adventure-5; @pz8-registry-adventure-8]. You cannot harden one without weakening the other unless you give up the hybrid-format premise entirely -- in which case, you are not hardening the parser; you are rewriting it. And rewriting it is what backward compatibility forbids.&lt;/p&gt;
&lt;p&gt;If a wholesale redesign is off the table, can the existing parser be hardened in place?&lt;/p&gt;
&lt;h2&gt;8. The Theoretical Limits of In-Place Hardening&lt;/h2&gt;
&lt;p&gt;If Microsoft cannot rewrite the parser, can they at least harden it? Four levers are theoretically available. Each one trades against a different property the existing design depends on.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Lever&lt;/th&gt;
&lt;th&gt;What it would achieve&lt;/th&gt;
&lt;th&gt;Backward-compat cost&lt;/th&gt;
&lt;th&gt;Effectiveness against hive-memory-corruption&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Allocator randomization&lt;/td&gt;
&lt;td&gt;Break the placement predictability the exploitation primitive relies on&lt;/td&gt;
&lt;td&gt;Breaks log-replay recovery semantics that depend on deterministic cell placement [@pz8-registry-adventure-8]&lt;/td&gt;
&lt;td&gt;High in principle; incompatible in practice&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cell-metadata integrity checks&lt;/td&gt;
&lt;td&gt;Catch naive corruption at allocator boundaries&lt;/td&gt;
&lt;td&gt;Modest format change for in-memory layout; on-disk format unaffected&lt;/td&gt;
&lt;td&gt;Low; catches accidental corruption, not crafted-input semantic violations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Structured deserialization at load time&lt;/td&gt;
&lt;td&gt;Validate the entire hive into a separate in-memory structure&lt;/td&gt;
&lt;td&gt;Abandons the hybrid-format premise; effectively rewrites the parser&lt;/td&gt;
&lt;td&gt;High but indistinguishable from rewriting&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Move the parser to user mode&lt;/td&gt;
&lt;td&gt;Reduce blast radius of a parser bug to one process&lt;/td&gt;
&lt;td&gt;Performance and correctness implications for boot-path config&lt;/td&gt;
&lt;td&gt;Mitigation only; the bug class survives in userland&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Allocator randomization&lt;/strong&gt; is the obvious idea. ASLR-like randomization of cell placement would defeat the &quot;place attacker-controlled bytes at predictable index&quot; half of the primitive, but it would also break recovery semantics: log replay assumes that after a crash, the cells in the recovered hive end up at the same indices the log expected, because the on-disk-equals-in-memory format encodes the cell index in the hive itself. PZ #8&apos;s framing of the allocator&apos;s lack of randomness as a &lt;em&gt;design property&lt;/em&gt; rather than an oversight is precisely about this trade-off [@pz8-registry-adventure-8].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cell-metadata integrity checks&lt;/strong&gt; are cheap to add and have an obvious limit. The cell allocator currently has no metadata integrity at all; adding a checksum or a canary would catch a corrupted size header, a stale free-list pointer, or a write that accidentally overran a cell boundary. It would not catch an attacker who shapes a &lt;em&gt;legal&lt;/em&gt; hive that exercises the parser&apos;s combinatorial logic. The semantic bugs Jurczyk hunted do not write garbage cells; they trick the parser into reusing valid cells for purposes the parser does not realize it is being asked to.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Structured deserialization at hive-load time&lt;/strong&gt; is the option computer-science textbooks recommend. Validate the entire input file against a formal grammar, deserialize into a separate in-memory representation that is unrelated to the on-disk byte layout, and let the kernel operate on that. This is what the LangSec discipline calls for, and what structure-aware fuzzing surveys treat as the right shape for parser hardening [@manes-fuzz-survey]. It is also identical to &quot;rewrite the parser.&quot; The hybrid-format premise that has been load-bearing since 1993 has to die for this option to exist.&lt;/p&gt;

Language-theoretic security: a discipline that treats parsers as recognizers for a formal grammar, rejecting inputs outside the grammar instead of recovering from malformed input. The registry parser does the opposite by design: it accepts inputs that the recognizer would call &quot;marginal&quot; (a slightly-malformed log, an off-by-one bin) because recovery from a torn write requires acceptance, not rejection.
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; LangSec&apos;s central recommendation is that a parser should be a &lt;em&gt;recognizer&lt;/em&gt; for a formal language: an input either belongs to the language or it is rejected outright, with no recovery and no partial acceptance. The registry&apos;s regf parser is not a recognizer in this sense, and cannot be retrofitted into one without abandoning the hybrid on-disk-and-in-memory premise.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Moving the parser to user mode&lt;/strong&gt; -- running the parser inside an isolated process and exposing only sanitized handles to kernel callers -- is what the academic literature recommends for other kernel parsers. There is no public Microsoft work on doing this for the registry specifically, and the performance cost of a kernel/user boundary on the boot-path configuration store is, charitably, &quot;unstudied.&quot; The bug class would still exist; the blast radius would shrink.&lt;/p&gt;

Static analysis cannot save us in general. Rice&apos;s theorem says, informally, that any non-trivial semantic property of an arbitrary program is undecidable: there is no algorithm that takes a program and tells you whether it has property $P$, for any interesting $P$. Memory safety is interesting. Therefore, any static-analysis approach to &quot;find every memory-safety bug in the Configuration Manager&quot; must be either unsound (it misses bugs) or incomplete (it flags false positives), and in practice usually both. Formal verification of a *specific* parser against a *specific* specification can sidestep this -- the EverParse project at `github.com/project-everest/everparse` does exactly that for TLS and QUIC message parsers in Microsoft research -- but it requires a formal specification of the input language, and the regf format has none.
&lt;p&gt;The honest answer is the one Jurczyk gives in PZ #7 and PZ #8: the parser can be incrementally hardened, and is being, in response to each individual CVE [@pz7-registry-adventure-7; @pz8-registry-adventure-8]. The deeper design choices that make the parser exploitable are the same choices that make it work at all. We have a thirty-year-old parser that cannot be redesigned, cannot easily be replaced, and can only be hardened in ways that trade safety for compatibility. So what does that tell us about the rest of the Windows kernel?&lt;/p&gt;
&lt;h2&gt;9. Open Problems and What the Audit Implies&lt;/h2&gt;
&lt;p&gt;Jurczyk read one Windows kernel subsystem for twenty months and produced fifty CVEs. Windows has dozens of kernel subsystems. None of them has been read this way.&lt;/p&gt;
&lt;p&gt;That sentence is the article. The rest of this section is bookkeeping.&lt;/p&gt;
&lt;p&gt;First, the open business inside the audit itself. Microsoft chose not to fix some of Jurczyk&apos;s low-severity reports; PZ tracker issue #2508 is the canonical example of a WontFix close, and the broader &quot;low severity in isolation&quot; category is not &quot;not exploitable in combination&quot; -- modern kernel exploitation is bug-chaining, and a benign-looking primitive plus a benign-looking infoleak often compose into something less benign [@pz7-registry-adventure-7]. PZ #1 also explicitly flags higher-level wrapper logic (path translation in &lt;code&gt;CmpDoOpen&lt;/code&gt;, predefined-key abuses, virtualization layers) as parts of the surface that the 20-month audit did not exhaust [@pz1-registry-adventure-1]. There are more registry bugs to find.&lt;/p&gt;
&lt;p&gt;Second, the cross-subsystem implication. Microsoft&apos;s Windows Insider Preview bounty program pays &quot;from $500 to $100,000 USD&quot; for qualifying critical kernel bugs [@msrc-bounty-windows-insider]. The 50-CVE cohort, valued at the upper bound of the Insider Preview range, is somewhere in the neighbourhood of $5M in latent bounty value, all produced by one person reading code.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; At Microsoft&apos;s published $100,000 ceiling for critical Windows kernel bugs under the Windows Insider Preview program [@msrc-bounty-windows-insider], the 50-CVE cohort represents roughly $5M in latent bounty value. That is one person, twenty months, one subsystem. The question is not how to fix the registry; it is how many other subsystems would yield similar numbers under similar treatment.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;What does that imply for the Object Manager Namespace, the I/O Manager, the print stack, the transactional file system, the Common Log File System, or the WinUSB stack? No public audit of any of those subsystems at the depth of Jurczyk&apos;s registry work exists. Some of them have had targeted fuzzing campaigns; none has had a 100,000-line code review by a single expert reader. The expected yield is, charitably, unknown.&lt;/p&gt;

flowchart TD
    A[&quot;Windows kernel subsystems&quot;] --&amp;gt; B[&quot;Registry / Configuration Manager&quot;]
    A --&amp;gt; C[&quot;Object Manager Namespace&quot;]
    A --&amp;gt; D[&quot;I/O Manager&quot;]
    A --&amp;gt; E[&quot;KTM and CLFS&quot;]
    A --&amp;gt; F[&quot;Print spooler stack&quot;]
    A --&amp;gt; G[&quot;Transactional NTFS&quot;]
    A --&amp;gt; H[&quot;GDI and Win32k&quot;]
    B --&amp;gt; B1[&quot;Jurczyk 2022-2023, 50 CVEs&quot;]
    C --&amp;gt; C1[&quot;Partial Forshaw 2014+, logic bugs&quot;]
    D --&amp;gt; D1[&quot;Episodic fuzzing, no public deep audit&quot;]
    E --&amp;gt; E1[&quot;Episodic CLFS exploitation, no full audit&quot;]
    F --&amp;gt; F1[&quot;PrintNightmare-era patches, no full audit&quot;]
    G --&amp;gt; G1[&quot;No public deep audit&quot;]
    H --&amp;gt; H1[&quot;Years of TYPESAFE_CAST + targeted fuzzing&quot;]
&lt;p&gt;Third, Microsoft&apos;s own internal posture. The MSRC SDL pipeline includes OneFuzz-lineage tooling internally, though the public OneFuzz repository was archived in September 2023 [@onefuzz-repo]. No public Microsoft statement confirms or denies whether the registry was systematically fuzzed or audited inside Microsoft before Jurczyk&apos;s 2022 audit. The absence of such a statement is itself information: if Microsoft had a parallel internal effort that found these bugs first, they would normally publish that.&lt;/p&gt;
&lt;p&gt;Fourth, the methodological question that the article cannot answer because nobody has the data. Does manual code audit scale? One researcher, twenty months, one subsystem, fifty CVEs. Two researchers do not produce twice the bugs because of overlap and coordination cost; the typical second-researcher contribution on the same target is sublinear. There is no obvious path to ten Jurczyks reading ten subsystems in parallel and producing five hundred CVEs.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The registry is not interesting because it had bugs. The registry is interesting because someone read it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Jurczyk did not break new ground by finding a bug. He broke new ground by reading the code -- and the implication for everything else nobody has read is left, as Jurczyk himself might say, as an exercise for the reader.&lt;/p&gt;
&lt;h2&gt;10. A Practical Guide&lt;/h2&gt;
&lt;p&gt;Up to here, this article has been about the research. The rest is for practitioners.&lt;/p&gt;
&lt;h3&gt;For vulnerability researchers&lt;/h3&gt;
&lt;p&gt;If you want to understand Jurczyk&apos;s audit at the level required to repeat it, the Project Zero series is the primary text and the reading order is not the publication order. PZ #4 (hives and the registry layout) and PZ #5 (the regf file format) are the canonical references for the &lt;em&gt;substrate&lt;/em&gt;; PZ #6 (kernel-mode objects) is the reverse-engineering of the in-memory structures; PZ #7 (attack surface analysis) is the bug-class taxonomy; PZ #8 (practical exploitation) is the exploitation primitive on Windows 11 with modern mitigations [@pz4-registry-adventure-4; @pz5-registry-adventure-5; @pz6-registry-adventure-6; @pz7-registry-adventure-7; @pz8-registry-adventure-8]. PZ #1 and #2 are the framing and the history; PZ #3 is the bibliography. Read 4 -- 5 -- 6 -- 7 -- 8, in that order, with PZ #1 alongside as a CVE-index lookup.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Audience&lt;/th&gt;
&lt;th&gt;Where to start&lt;/th&gt;
&lt;th&gt;Why&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Researcher learning the surface&lt;/td&gt;
&lt;td&gt;PZ #4 then PZ #5 [@pz4-registry-adventure-4; @pz5-registry-adventure-5]&lt;/td&gt;
&lt;td&gt;Substrate first; specifics later&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Defender / SOC engineer&lt;/td&gt;
&lt;td&gt;PZ #7 attack-surface taxonomy [@pz7-registry-adventure-7]&lt;/td&gt;
&lt;td&gt;Detection patterns map to bug classes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kernel engineer (defensive)&lt;/td&gt;
&lt;td&gt;PZ #4--6 collectively&lt;/td&gt;
&lt;td&gt;Best non-Microsoft technical reference on the Configuration Manager&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Patch manager&lt;/td&gt;
&lt;td&gt;PZ #8&apos;s 17-CVE list + PZ #1 full table [@pz8-registry-adventure-8; @pz1-registry-adventure-1]&lt;/td&gt;
&lt;td&gt;Prioritize the hive-memory-corruption cohort&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

The Jurczyk pattern is reproducible. Pick a closed-source Windows kernel subsystem with a structurally rigid input format. Get the public PDB symbols for `ntoskrnl.exe` (or the relevant driver). Find the equivalent of `RegLoadAppKey` for the surface in question -- the unprivileged user-mode entry point that runs the most kernel code on the most attacker-influenced input. Then read every reachable function. The unglamorous methodology and the long-form Project Zero blog series are the same artifact.Jurczyk&apos;s 2022 registry-specific coverage-guided Bochs harness has never been publicly released. The lineage -- Bochspwn (2013), Bochspwn Reloaded (2018) -- is well-documented in Jurczyk&apos;s public papers and repositories [@bochspwn-reloaded-paper; @bochspwn-reloaded-repo]. The registry-specific configuration is not.
&lt;h3&gt;For defenders&lt;/h3&gt;
&lt;p&gt;The detection story for hive-memory-corruption attempts is unusual. Most real-world exploitation chains will load an attacker-controlled hive via &lt;code&gt;RegLoadAppKey&lt;/code&gt; (or its close relatives &lt;code&gt;RegLoadKey&lt;/code&gt;, &lt;code&gt;RegLoadKeyEx&lt;/code&gt;, &lt;code&gt;RegRestoreKey&lt;/code&gt;) from an unusual path -- typically a temporary directory under the calling user&apos;s profile or an SMB share. The hive file itself can be analyzed offline by mounting it with a forensic parser such as libregf [@libregf-repo] or Suhanov&apos;s regf tools [@msuhanov-repo].&lt;/p&gt;
&lt;p&gt;The kernel exposes the operation via the &lt;code&gt;Microsoft-Windows-Kernel-Registry&lt;/code&gt; &lt;a href=&quot;https://paragmali.com/blog/etw-how-windows-2000s-performance-hack-became-the-edr-substr/&quot; rel=&quot;noopener&quot;&gt;ETW&lt;/a&gt; provider, and &lt;a href=&quot;https://paragmali.com/blog/from-cmdexe-to-a-kusto-row-in-90-seconds-how-sysmon-and-defe/&quot; rel=&quot;noopener&quot;&gt;Sysmon&lt;/a&gt; surfaces registry operations under event IDs 12 (key create/delete), 13 (value set), and 14 (key/value rename) [@ms-sysmon]. A simple detection heuristic is &quot;Medium-IL process performs an unusual rate of hive-load operations on attacker-shaped paths.&quot; Detection logic looks like the following.&lt;/p&gt;
&lt;p&gt;{`
// Toy detection: Medium-IL process loads multiple app hives from
// non-standard paths within a short window. Inspired by Sysmon event IDs
// 12 (registry create/delete) and 13 (registry value set).&lt;/p&gt;
&lt;p&gt;function suspiciousHiveLoad(event, profileWindowMs) {
  const isLoad = event.operation === &apos;CreateKey&apos; || event.operation === &apos;LoadAppKey&apos;;
  if (!isLoad) return false;&lt;/p&gt;
&lt;p&gt;  const path = event.targetPath || &apos;&apos;;
  const fromTempOrShare =
    path.match(/AppData\\Local\\Temp/i) ||
    path.match(/^\\\\[^\\]+\\/) ||
    path.match(/Users\\Public/i);&lt;/p&gt;
&lt;p&gt;  const lowIntegrity = event.integrityLabel === &apos;Medium&apos; || event.integrityLabel === &apos;Low&apos;;&lt;/p&gt;
&lt;p&gt;  const recentCount = countRecentEventsFromPid(event.pid, profileWindowMs);
  const burst = recentCount &amp;gt; 5;&lt;/p&gt;
&lt;p&gt;  return lowIntegrity &amp;amp;&amp;amp; fromTempOrShare &amp;amp;&amp;amp; burst;
}&lt;/p&gt;
&lt;p&gt;function alert(event) {
  if (suspiciousHiveLoad(event, 60000)) {
    console.log(&apos;ALERT: anomalous hive load from PID &apos; + event.pid +
                &apos; path=&apos; + event.targetPath);
  }
}
`}&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The 17 CVEs in Jurczyk&apos;s PZ #8 cohort all share the same exploitation primitive. If you are triaging a backlog of Windows security updates, prioritize fixes for these CVE IDs over the broader 50-CVE list: CVE-2022-34707, -34708, -37956, -37988, -38037; CVE-2023-21675, -21748, -23420, -23421, -23422, -23423, -28248, -35382, -38139; CVE-2024-26182, -43641, -49114 [@pz8-registry-adventure-8].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;For engineers maintaining adjacent code&lt;/h3&gt;
&lt;p&gt;PZ #4, #5, and #6 collectively are the most accessible non-Microsoft technical reference on the Configuration Manager [@pz4-registry-adventure-4; @pz5-registry-adventure-5; @pz6-registry-adventure-6]. If you are doing security review of a subsystem that interacts with the registry -- ETW, KTM, AppX state, group policy -- those three posts plus PZ #7 give you the model of the in-kernel data structures you are talking to.&lt;/p&gt;
&lt;h3&gt;For everyone else&lt;/h3&gt;
&lt;p&gt;The 50 CVE IDs spanning CVE-2022-34707 through CVE-2024-49114 are a checklist for &quot;have these been rolled across our fleet?&quot; [@pz1-registry-adventure-1]. The 17-CVE hive-memory-corruption subset is the priority order [@pz8-registry-adventure-8]. The fixes are in Microsoft&apos;s monthly servicing channel; there are no out-of-band patches required, but the cohort is large enough that a fleet that fell behind on Patch Tuesday in 2022 -- 2024 may have several of these still outstanding.&lt;/p&gt;
&lt;p&gt;The research is published. The detection is uncomplicated. The next twenty months of Windows kernel research will not be about the registry, which makes the question this article ends on -- what about everything else nobody has read -- the only question left.&lt;/p&gt;
&lt;h2&gt;11. FAQ&lt;/h2&gt;
&lt;p&gt;A handful of questions worth correcting before they propagate. These are the misconceptions inherited from secondary summaries of the research, including the prompt for this article.&lt;/p&gt;

No. **Bochspwn Reloaded** is a separate 2017--2018 Project Zero tool, also by Jurczyk, that detects uninitialized kernel memory disclosures via x86 taint tracking [@bochspwn-reloaded-repo; @bochspwn-reloaded-paper]. The 2022--2023 registry research is **The Windows Registry Adventure**, an eight-part Project Zero blog series [@pz1-registry-adventure-1]. The 2022 coverage-guided Bochs harness Jurczyk briefly used on the registry was a separate, unreleased tool sharing the same general lineage, but it is not the public Bochspwn Reloaded repository. Conflating the two is the most common third-party error about this research.

No. At a minimum, Jurczyk and Forshaw fuzzed it in 2016 -- the bug reports filed as Project Zero issues #873, #874, #876, and #993 are the surviving artifacts of that effort [@pz1-registry-adventure-1] -- and Jurczyk built a coverage-guided Bochs harness against it in early 2022 that produced CVE-2022-35768 within days. The 2022--2023 work that produced 50 CVEs was a manual code audit, not a fuzzing campaign. The &quot;fuzzed precisely once&quot; claim mixes up &quot;no published fuzzing campaign at scale&quot; with &quot;no one ever pointed a fuzzer at this,&quot; and the latter is just not true.

No. The Configuration Manager uses **pushlocks** (shared and exclusive modes) on a per-Key-Control-Block basis, plus a hive-wide pushlock for global hive operations [@pz6-registry-adventure-6]. &quot;Lock-free&quot; is a misconception that appears in some secondary summaries -- including the prompt for this article. The actual design is fine-grained pushlock-synchronized, and several of Jurczyk&apos;s temporal hive-memory-corruption bugs exploit the moment a pushlock is released and re-acquired.

All of those are correct at different points in the publication arc. PZ #1 (April 2024) counts 44 from the 90-day cohort plus 6 from the March 2024 low-severity batch = 50 [@pz1-registry-adventure-1]. PZ #5 (December 2024) reports 52 [@pz5-registry-adventure-5]. PZ #7 (May 2025) reports 53 [@pz7-registry-adventure-7]. The growth reflects Microsoft assigning more CVE IDs to Jurczyk&apos;s existing bug reports over time, not new discoveries. &quot;50+&quot; is the safe shorthand; &quot;50 in the original cohort, 53 by mid-2025&quot; is the precise version.

**OffensiveCon 2024**, in Berlin. The talk was &quot;Practical Exploitation of Registry Vulnerabilities in the Windows Kernel&quot;; slides and recording are public [@offcon24-jurczyk-speaker; @offcon24-slides; @offcon24-video]. The earlier **BlueHat Redmond 2023** talk (titled &quot;Exploring the Windows Registry as a powerful LPE attack surface&quot;) was the first public disclosure of the research [@bluehat23-slides; @bluehat23-video]. &quot;OffensiveCon 2025&quot; is wrong; that talk has not happened.

No. Microsoft has never published a regf specification; PZ #5 states this directly: &quot;Throughout the 30 years of the format&apos;s existence, Microsoft has never released its official specification&quot; [@pz5-registry-adventure-5]. Unofficially, two community-maintained specs cover almost all of it: Joachim Metz&apos;s libregf, updated continuously since July 2009 [@libregf-spec], and Maxim Suhanov&apos;s regf project [@msuhanov-spec]. The Microsoft-blessed reference book is *Windows Internals, Part 2, 7th Edition* by Allievi, Russinovich, Ionescu, and Solomon [@winint7-part2]. Everything else is forensics-community reverse engineering.
&lt;p&gt;&amp;lt;StudyGuide slug=&quot;windows-registry-adventure&quot; keyTerms={[
  { term: &quot;regf&quot;, definition: &quot;Microsoft&apos;s binary registry file format, introduced in NT 3.1 (1993) and frozen at v1.3 in NT 4.0 (1996). The on-disk format and the in-memory format are the same format.&quot; },
  { term: &quot;Hive&quot;, definition: &quot;A file-and-in-memory tree of registry keys and values, encoded in regf and parsed by the Windows kernel&apos;s Configuration Manager.&quot; },
  { term: &quot;Cell&quot;, definition: &quot;The unit of allocation inside a hive: length-prefixed bytes whose signed prefix marks free (positive) or allocated (negative), with size in multiples of eight bytes.&quot; },
  { term: &quot;Cell map&quot;, definition: &quot;A page-table-like indirection layer that translates a 32-bit cell index into a kernel virtual address.&quot; },
  { term: &quot;RegLoadAppKey&quot;, definition: &quot;Win32 API since Vista that lets an unprivileged process load an arbitrary hive file. The kernel parser runs on attacker-supplied bytes.&quot; },
  { term: &quot;Hive-based memory corruption&quot;, definition: &quot;Jurczyk&apos;s bug class: spatial (cell-boundary overflows) and temporal (cell-reuse use-after-frees) memory corruption via the deterministic cell allocator.&quot; },
  { term: &quot;Pushlock&quot;, definition: &quot;Windows kernel synchronization primitive (shared/exclusive). The registry uses per-KCB and hive-wide pushlocks; it is not lock-free.&quot; },
  { term: &quot;Double-fetch&quot;, definition: &quot;Pattern where the kernel reads the same attacker-influenced memory twice; section-backed hives since Windows 10 RS4 made this exploitable on hive files from SMB shares.&quot; },
  { term: &quot;Bochspwn Reloaded&quot;, definition: &quot;A 2018 Project Zero tool for detecting kernel infoleaks via Bochs-based taint tracking. NOT the registry-research instrument.&quot; },
  { term: &quot;LangSec&quot;, definition: &quot;Language-theoretic security: parsers as recognizers for a formal grammar. The regf parser is not a LangSec recognizer by design.&quot; }
]} questions={[
  { q: &quot;Why does the Windows kernel run a binary parser on attacker-supplied bytes at Medium IL?&quot;, a: &quot;&lt;code&gt;RegLoadAppKey&lt;/code&gt;, introduced in Vista (2006), explicitly allows an unprivileged process to load an arbitrary hive file as a private app hive. The kernel-mode regf parser runs on those bytes; only the resulting handle is sandboxed.&quot; },
  { q: &quot;Why was bitflipping fuzzing ineffective against regf?&quot;, a: &quot;The base-block validator rejects most random mutations before the parser proper sees them; the interesting bugs are semantic, requiring legal hive images that exercise multi-feature combinations (transactions, virtualization, log replay).&quot; },
  { q: &quot;Why is the cell allocator unrandomized?&quot;, a: &quot;Recovery semantics require deterministic cell placement after log replay; cells encode their indices in the on-disk format. Randomization would break crash recovery.&quot; },
  { q: &quot;Distinguish spatial from temporal hive-memory-corruption violations.&quot;, a: &quot;Spatial: a write crosses a cell boundary into an adjacent cell. Temporal: a write uses a cell-index reference whose backing storage has been freed and reallocated to attacker-influenced content.&quot; },
  { q: &quot;Why is the section-backed hive design in Windows 10 RS4 a double-fetch enabler?&quot;, a: &quot;Hive pages became pageable. The kernel can read a hive byte at validation time and again at use time, and the underlying page can be re-fetched in between -- especially over SMB. CVE-2024-43452 is the canonical example.&quot; }
]} /&amp;gt;&lt;/p&gt;
&lt;p&gt;The eight Project Zero posts run roughly 120,000 words across April 2024 -- May 2025. Microsoft has serviced 53 CVEs from them so far. The registry&apos;s parser remains substantively the same routine it has been since Windows NT 4.0. There is no public roadmap for a redesign. The question that follows -- what is the expected yield of similar audits of every other Windows kernel subsystem that no one has read end-to-end -- is the one a research community could answer in another twenty months, if it chose to.&lt;/p&gt;
</content:encoded><category>windows-kernel</category><category>security-research</category><category>fuzzing</category><category>manual-audit</category><category>project-zero</category><category>registry</category><author>noreply@paragmali.com (Parag Mali)</author></item><item><title>Adminless: How Windows Finally Made Elevation a Security Boundary</title><link>https://paragmali.com/blog/adminless-how-windows-finally-made-elevation-a-security-boun/</link><guid isPermaLink="true">https://paragmali.com/blog/adminless-how-windows-finally-made-elevation-a-security-boun/</guid><description>Administrator Protection replaces UAC with a system-managed admin account created per elevation, gated by Windows Hello, and destroyed when the job is done.</description><pubDate>Sun, 10 May 2026 00:00:00 GMT</pubDate><content:encoded>
**Administrator Protection (informally &quot;Adminless&quot;) replaces Windows 11&apos;s split-token UAC with a separate, system-managed local user account.** The operating system creates this **System Managed Administrator Account (SMAA)** per local admin, links it to the primary admin via paired SAM attributes, and uses it to host elevated processes in a fresh logon session gated by Windows Hello. The kernel asks LSA to authenticate &quot;a new instance of the shadow administrator&quot; without any SMAA credential because the SMAA has none. The mechanism makes the elevation path a security boundary for the first time, with bulletin-grade fixes when it fails. Microsoft shipped it in KB5067036 on October 28, 2025, then reverted it on December 1, 2025 over an application-compatibility issue, not a security failure. This article walks the twenty-year argument that produced the design, the nine pre-GA bypasses Forshaw found and Microsoft fixed, and exactly where the new boundary still leaks.
&lt;h2&gt;1. Two tokens, one user, twenty years&lt;/h2&gt;
&lt;p&gt;Open an elevated console on a Windows 11 device with the registry value &lt;code&gt;TypeOfAdminApprovalMode = 2&lt;/code&gt; set, and run &lt;code&gt;whoami /all&lt;/code&gt;. The user name is no longer yours. It is &lt;code&gt;ADMIN_&amp;lt;sixteen random characters&amp;gt;&lt;/code&gt; -- a local account you never created, owned by an operating-system component you never ran, in a logon session that did not exist five seconds ago and will not exist five seconds after the console closes.&lt;/p&gt;
&lt;p&gt;For twenty years, an elevated Windows command prompt reported the same user name as the unelevated one. The integrity level changed. The token changed. The user did not. That single architectural fact is the load-bearing premise of every UAC bypass ever published. The Vista User Account Control design from 2006 issued two tokens at logon for a member of the local Administrators group: a filtered standard-user token for everyday work, and a full admin token linked to it via the &lt;code&gt;TokenLinkedToken&lt;/code&gt; field [@ms-uac-how-it-works]. When the user clicked Yes on a consent prompt, the Application Information service called &lt;code&gt;CreateProcessAsUser&lt;/code&gt; with the linked token. Same user. Same profile. Same &lt;code&gt;HKCU&lt;/code&gt;. Same logon session. Different integrity level.&lt;/p&gt;
&lt;p&gt;Four resources stayed shared between the filtered and full tokens, and four categories of attack grew out of them. Files dropped in a writable directory the elevated process trusts. Registry values planted under &lt;code&gt;HKEY_CURRENT_USER&lt;/code&gt; that an elevated binary reads before it consults &lt;code&gt;HKEY_CLASSES_ROOT&lt;/code&gt;. COM elevation monikers that hand the attacker an elevated &lt;code&gt;IFileOperation&lt;/code&gt; interface. Path-resolution overrides that redirect &lt;code&gt;%SystemRoot%&lt;/code&gt; for a single auto-elevating process. The UACMe project [@uacme] catalogues 81 such methods, each one a load against the shared-resource shape of Vista&apos;s split token.&lt;/p&gt;
&lt;p&gt;Administrator Protection inverts that shape. The elevated administrator becomes a &lt;em&gt;different account&lt;/em&gt; with a different security identifier, a different profile directory, a different &lt;code&gt;NTUSER.DAT&lt;/code&gt; hive, a different authentication-ID LUID, and a different DOS device object directory under &lt;code&gt;\Sessions\0\DosDevices\&lt;/code&gt;. The operating system manages the account itself. It is created on demand the first time the policy is enabled, linked to the primary admin via paired Security Account Manager attributes, used in a fresh logon session for every elevation, and the elevated token is destroyed when the process exits [@ms-developer-blog-2025, @call4cloud-osint].&lt;/p&gt;
&lt;p&gt;The feature ships under four names -- &lt;strong&gt;Administrator Protection&lt;/strong&gt; in Microsoft Learn, &lt;strong&gt;Adminless&lt;/strong&gt; as the community shorthand this article uses, &lt;strong&gt;ShadowAdmin&lt;/strong&gt; in the &lt;code&gt;samsrv.dll&lt;/code&gt; engineering symbols, &lt;strong&gt;System Managed Administrator Account (SMAA)&lt;/strong&gt; in the Windows Developer Blog [@ms-admin-protection, @ms-developer-blog-2025, @call4cloud-osint] -- and §6 walks each in turn. The launch arc was short: announced at Ignite 2024 by David Weston on November 19, 2024 [@bleepingcomputer-2024], surfaced earlier that fall in Insider Preview build 27718 on October 2, 2024 [@ms-insider-build-27718], shipped to stable Windows in KB5067036 on October 28, 2025 [@ms-kb5067036], and disabled on December 1, 2025 over a WebView2 application-compatibility regression [@forshaw-pz-jan2026, @ms-admin-protection].&lt;/p&gt;
&lt;p&gt;This article walks what changed and what did not. By the end you will know exactly which UAC bypass families are dead, exactly which survive, exactly what the December 2025 revert was about, and exactly where the new boundary still leaks. The path runs through twenty years of design tradeoffs and seven years of binary-level fixes that never converged on a real boundary. It runs through nine Project Zero bypasses Microsoft fixed before shipping. It ends at a question Microsoft&apos;s own design documents do not yet answer: when the prompt is a credential gate instead of a click-through, what is left for the attacker to do?&lt;/p&gt;
&lt;p&gt;The first thing to understand is what UAC was trying to do, and why Microsoft said for twenty years it was not a security boundary.&lt;/p&gt;
&lt;h2&gt;2. &quot;Convenience, not boundary&quot;: UAC as Microsoft conceived it&lt;/h2&gt;
&lt;p&gt;Why did Vista ship UAC at all? For most of Windows history, every interactive logon for a member of the local Administrators group produced one full-admin token. The desktop shell ran as a full administrator. Every child process inherited those rights. The worm era of 2003 to 2005 demonstrated, repeatedly, that one process running in user context owned the whole machine. By 2006 the cost of admin-by-default had become impossible to defend [@wikipedia-uac].The pre-Vista &lt;em&gt;Limited User Account&lt;/em&gt; (LUA) was Microsoft&apos;s first attempt at a fix. The conceptual ancestor of the filtered token failed in practice because roughly half of the third-party application base broke under it, and the documented workaround -- &lt;code&gt;RUNAS.EXE&lt;/code&gt; -- was operationally hostile enough that almost no one used it.&lt;/p&gt;
&lt;p&gt;The redesign that produced UAC pivoted on a single observation. Forcing administrators to run as standard users had failed because too much software assumed admin rights. So Vista would give each admin user &lt;em&gt;two&lt;/em&gt; identities. One would be standard-user enough to run the desktop, the browser, and the day-to-day applications without privilege. The other would carry the admin rights, and the operating system would arrange for the user to opt into it on a per-task basis.&lt;/p&gt;
&lt;p&gt;Mark Russinovich&apos;s June 2007 article &lt;em&gt;Inside Windows Vista User Account Control&lt;/em&gt; in TechNet Magazine [@russinovich-2007-vista] remains the canonical reference for the design. The mechanism is two tokens at logon; the integrity-level taxonomy (Low, Medium, High, System) gating object access; file-system and registry virtualisation rerouting writes by legacy apps; and Mandatory Integrity Control enforcing the no-write-up rule at the kernel-object boundary.&lt;/p&gt;

The mechanism by which Vista UAC assigns two distinct access tokens to a single interactive logon for a member of the local Administrators group. The Local Security Authority issues both at logon: a filtered standard-user token with most privileges removed and the Administrators group marked as deny-only, and a linked full administrator token referenced from the filtered token&apos;s `TokenLinkedToken` field [@ms-uac-how-it-works].
&lt;p&gt;The disclaimer that follows the design is the single most quoted sentence Russinovich ever published about UAC. The article will lift it verbatim once, because every Administrator Protection design decision falls out of its absence:&lt;/p&gt;

It&apos;s important to be aware that UAC elevations are conveniences and not security boundaries. -- Mark Russinovich, *Inside Windows Vista User Account Control*, TechNet Magazine, June 2007 [@russinovich-2007-vista]
&lt;p&gt;This is not an accidental disclaimer. It is the canonical Microsoft classification, preserved into the Microsoft Security Servicing Criteria document [@msrc-servicing-criteria]. James Forshaw of Google Project Zero, writing in January 2026, re-states the position verbatim: &quot;due to the way it was designed, it was quickly apparent it didn&apos;t represent a hard security boundary, and Microsoft downgraded it to a security feature&quot; [@forshaw-pz-jan2026]. The classification is what determined what Microsoft would and would not pay attention to. A &quot;security boundary&quot; gets a security bulletin when an attacker crosses it. A &quot;security feature&quot; does not. A bypass of a boundary is a vulnerability. A bypass of a feature is a quality bug. For twenty years, UAC bypasses were quality bugs.&lt;/p&gt;
&lt;p&gt;The two-tokens-at-logon mechanism is the shape from which the entire bypass canon grows. The twenty years of evolution that follow run along a single timeline.&lt;/p&gt;

timeline
    title Privilege separation in Windows, NT 3.1 to Administrator Protection
    1993 : NT 3.1 ships multi-user accounts and DACLs but admin-by-default desktop culture
    2006 : Vista UAC introduces the split-token model and Mandatory Integrity Control
    2009 : Davidson publishes the first UAC bypass; Windows 7 ships auto-elevation
    2014 : hfiref0x&apos;s UACMe catalogue collects the bypass canon
    2016 : enigma0x3 publishes the registry-hijack family (eventvwr, fodhelper, sdclt)
    2019 : CVE-2019-1388 (consent.exe certificate dialog) is the lone UAC LPE bulletin
    2024 : Insider Preview build 27718 surfaces Administrator Protection; Ignite 2024 announces it
    2025 : KB5067036 ships the SMAA on stable Windows, then reverts on December 1
    2026 : Forshaw&apos;s nine pre-GA bypasses all fixed; the elevation path is now a security boundary
&lt;p&gt;To see why the entire bypass canon grew out of the split-token shape, the next section walks the mechanic at function-name granularity. It is the load-bearing pre-history of everything that comes after.&lt;/p&gt;
&lt;h2&gt;3. The Vista UAC split-token in detail&lt;/h2&gt;
&lt;p&gt;The mechanics at logon. The Local Security Authority Subsystem Service (LSASS) validates credentials. For a user in the local Administrators group, it constructs two tokens. The filtered token has its dangerous privileges removed and the Administrators SID marked deny-only; the full token retains them. The Token Manager wires the filtered token&apos;s &lt;code&gt;TokenLinkedToken&lt;/code&gt; field to a handle on the full token. LSASS hands the filtered token to &lt;code&gt;winlogon.exe&lt;/code&gt;. Winlogon launches &lt;code&gt;userinit.exe&lt;/code&gt;. Userinit launches &lt;code&gt;explorer.exe&lt;/code&gt;. The shell, holding the filtered token, becomes the parent process from which every user-initiated process inherits [@ms-uac-how-it-works].&lt;/p&gt;

The kernel structure that connects the filtered standard-user token to the linked full administrator token in Vista&apos;s split-token model. A process holding the filtered token can read the `TokenLinkedToken` field via the `GetTokenInformation` API to discover the handle of the full token, and pass that handle to `CreateProcessAsUser` to launch an elevated child. The same link is the structural premise of token-stealing attacks: any code path that can read or impersonate the linked token bypasses the consent UI entirely [@ms-uac-how-it-works, @forshaw-pz-jan2026].
&lt;p&gt;The shell shares four resources with anything launched under the full token.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;The same user security identifier.&lt;/strong&gt; Both tokens carry the same primary SID. Files, registry keys, and kernel objects that grant access to the user grant identical access to both processes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The same &lt;code&gt;%USERPROFILE%&lt;/code&gt; directory tree.&lt;/strong&gt; &lt;code&gt;C:\Users\&amp;lt;user&amp;gt;\&lt;/code&gt; is the home of both. The Documents folder, the Downloads folder, the AppData hives, and any application-specific subdirectory belong to one user.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The same &lt;code&gt;HKEY_CURRENT_USER&lt;/code&gt; hive.&lt;/strong&gt; Both tokens map &lt;code&gt;HKCU&lt;/code&gt; to the same &lt;code&gt;NTUSER.DAT&lt;/code&gt; file. An elevated process that reads a user setting reads the value the unelevated user wrote.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The same logon-session LUID.&lt;/strong&gt; The Locally Unique Identifier that identifies an interactive logon session is the same on both tokens. The kernel uses that LUID as a key for per-logon-session caching: the DOS device object directory at &lt;code&gt;\Sessions\0\DosDevices\&amp;lt;LUID&amp;gt;&lt;/code&gt;, drive-letter mappings, mapped network drives, and the credential cache.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The elevation pipeline. A user clicks Yes on a UAC prompt. The mechanism beneath that click runs through a chain of named function calls.&lt;/p&gt;

sequenceDiagram
    participant User as User shell (filtered token)
    participant AppInfo as appinfo.dll (Application Information service)
    participant Consent as consent.exe (secure desktop)
    participant LSA as LSASS
    participant New as Elevated child process&lt;pre&gt;&lt;code&gt;User-&amp;gt;&amp;gt;AppInfo: ShellExecute / CreateProcess &quot;as admin&quot;
AppInfo-&amp;gt;&amp;gt;AppInfo: RAiLaunchAdminProcess RPC
AppInfo-&amp;gt;&amp;gt;AppInfo: Read manifest requestedExecutionLevel
AppInfo-&amp;gt;&amp;gt;AppInfo: Check ConsentPromptBehaviorAdmin
AppInfo-&amp;gt;&amp;gt;Consent: Launch consent.exe on Winlogon desktop
Consent-&amp;gt;&amp;gt;User: Show Yes / No prompt
User--&amp;gt;&amp;gt;Consent: Click Yes
Consent--&amp;gt;&amp;gt;AppInfo: Approved
AppInfo-&amp;gt;&amp;gt;LSA: Resolve TokenLinkedToken handle
AppInfo-&amp;gt;&amp;gt;New: CreateProcessAsUser(linked full token)
Note over New: Same SID and profile and HKCU and logon session
Note over New: Integrity level High
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The prompt runs on the &lt;em&gt;secure desktop&lt;/em&gt;, the same Winlogon-owned &lt;code&gt;Winsta0\Winlogon&lt;/code&gt; desktop where the credential-entry dialog appears at logon, not the user&apos;s interactive &lt;code&gt;Winsta0\Default&lt;/code&gt; desktop [@ms-uac-how-it-works]. User Interface Privilege Isolation (UIPI) blocks lower-integrity input from reaching higher-integrity windows; the secure-desktop switch is its first defence against synthetic-keystroke attacks against the prompt itself.The secure desktop is not invulnerable. It changes the integrity-isolation context, but a process holding the filtered token can still trigger the switch (that is the whole point of clicking Yes), and code running before the switch can in principle modify the surrounding UI state. CVE-2019-1388 in late 2019 turned out to exploit a different aspect entirely -- a UI-interaction path through the consent.exe certificate-viewer dialog -- and not the secure-desktop switch itself.&lt;/p&gt;
&lt;p&gt;Compare this to what comes next. Both tokens share four resources. Each of those resources is a category of attack waiting for a researcher to find it. The next section is the story of what happened when Microsoft tried to make UAC less annoying by silently elevating its own Microsoft-signed binaries -- and what the bypass canon did with the change.&lt;/p&gt;
&lt;h2&gt;4. Windows 7 auto-elevation and the birth of the bypass canon&lt;/h2&gt;
&lt;p&gt;A specific moment. December 2009. Leo Davidson publishes &lt;em&gt;Windows 7 UAC whitelist: Code-injection Issue / Anti-Competitive API / Security Theatre&lt;/em&gt; on pretentiousname.com [@davidson-2009]. The title is the argument. The page itself is sprawling, contentious, and on a few key technical points exactly right. Microsoft&apos;s response, in Davidson&apos;s own words: &quot;this is a non-issue, and ignored my offers to give them full details for several months.&quot; Microsoft Security Essentials eventually classified the &lt;em&gt;binary&lt;/em&gt; (not the technique) as &lt;code&gt;HackTool:Win32/Welevate.A&lt;/code&gt; and &lt;code&gt;HackTool:Win64/Welevate.A&lt;/code&gt;; in Davidson&apos;s pointed observation, &quot;recompiling the binaries in VS2010 means they are no longer detected&quot; [@davidson-2009].Davidson kept writing into his original page over the following decade. A marker buried inside the text reads &quot;As I was typing more words into this page, this appeared in my text editor at the 10,000th word!&quot; In March 2020 he removed the proof-of-concept binaries, noting &quot;I got sick of the page being marked as malware, even by Google (FFS).&quot; The prose remains the canonical first source on UAC bypasses [@davidson-2009].&lt;/p&gt;
&lt;p&gt;What Windows 7 added, in October 2009, to fix Vista&apos;s prompt-fatigue problem [@russinovich-2009-win7]:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The &lt;code&gt;autoElevate=true&lt;/code&gt; manifest attribute, embedded in selected Microsoft-signed Windows binaries.&lt;/li&gt;
&lt;li&gt;An internal whitelist of Microsoft-signed binaries living under &lt;code&gt;%SystemRoot%\System32&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;COM Elevation Moniker&lt;/strong&gt; -- already shipping in Vista (&lt;code&gt;BIND_OPTS3&lt;/code&gt;, syntax &lt;code&gt;Elevation:Administrator!new:&amp;lt;CLSID&amp;gt;&lt;/code&gt;) -- was the activation primitive. Windows 7 extended &lt;em&gt;implicit&lt;/em&gt; auto-elevation to qualifying COM servers whose registrations matched the new whitelist criteria, so callers such as &lt;code&gt;IFileOperation&lt;/code&gt;, &lt;code&gt;ICMLuaUtil&lt;/code&gt;, and &lt;code&gt;IColorDataProxy&lt;/code&gt; could be launched elevated without a consent prompt under the Win7 model [@russinovich-2009-win7, @uacme]. The dedicated registry-curation surface, the &lt;code&gt;COMAutoApprovalList&lt;/code&gt; (&lt;code&gt;HKLM\Software\Microsoft\Windows NT\CurrentVersion\UAC\COMAutoApprovalList&lt;/code&gt;) that UACMe Method 49 references verbatim, did &lt;em&gt;not&lt;/em&gt; ship in Windows 7; it was introduced seven years later in Windows 10 RS1 (build 14393, August 2016) as a Redstone-1 hardening that replaced implicit COM auto-elevation with explicit list curation [@uacme].&lt;/li&gt;
&lt;li&gt;The default consent-prompt behaviour &lt;code&gt;ConsentPromptBehaviorAdmin = 5&lt;/code&gt;: prompt for consent for non-Windows binaries [@russinovich-2009-win7].&lt;/li&gt;
&lt;/ol&gt;

The Windows 7 mechanism by which selected Microsoft-signed binaries elevate without showing the consent prompt to a user who is a member of the local Administrators group. The Application Information service consults a whitelist of signature, path, and manifest attributes; if the binary qualifies, `appinfo.dll` calls `CreateProcessAsUser` with the linked full token and no UI step at all [@russinovich-2009-win7].

A COM activation syntax introduced in Windows Vista that lets an unelevated caller request an elevated instance of a COM server class. The `IBindCtx` is augmented with a `BIND_OPTS3` structure carrying a window handle to attribute the prompt to. The bind moniker `Elevation:Administrator!new:&amp;lt;CLSID&amp;gt;` causes the COM Service Control Manager to launch the server elevated. UACMe methods that target `IFileOperation`, `ICMLuaUtil`, and `IColorDataProxy` all descend from this mechanism [@russinovich-2009-win7, @uacme].
&lt;p&gt;Davidson&apos;s technique against the new whitelist is one paragraph of detail. Use the &lt;code&gt;IFileOperation&lt;/code&gt; COM elevation moniker, which itself auto-elevates, to write a planted &lt;code&gt;CRYPTBASE.DLL&lt;/code&gt; into &lt;code&gt;%SystemRoot%\System32\sysprep\&lt;/code&gt;. The path is a writable destination from the limited token because &lt;code&gt;IFileOperation&lt;/code&gt; runs elevated. Then launch &lt;code&gt;sysprep.exe&lt;/code&gt;, which is auto-elevated as a Microsoft-signed binary in System32. Sysprep loads &lt;code&gt;CRYPTBASE.DLL&lt;/code&gt; from its own directory before the system path. The attacker&apos;s DLL runs at High integrity in the elevated sysprep process [@davidson-2009, @uacme]. No prompt. The whitelist did the work.&lt;/p&gt;
&lt;p&gt;The bypass canon. Davidson&apos;s technique was the start, not the totality. The successors walked the same shape across families.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The DLL side-load family.&lt;/strong&gt; Sysprep was the canonical instance. Subsequent variants targeted &lt;code&gt;cliconfg.exe&lt;/code&gt;, &lt;code&gt;mcx2prov.exe&lt;/code&gt;, &lt;code&gt;migwiz.exe&lt;/code&gt;, and &lt;code&gt;setupsqm.exe&lt;/code&gt; -- each an auto-elevating Microsoft binary that loaded a DLL from a writable directory before consulting the system path. Microsoft removed the auto-elevation attribute from many of these binaries over the Windows 10 1709 cycle, but did so one binary at a time [@uacme].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The registry-hijack family.&lt;/strong&gt; Matt Nelson&apos;s August 2016 disclosure of an &lt;code&gt;eventvwr.exe&lt;/code&gt; plus &lt;code&gt;HKCU\Software\Classes\mscfile\shell\open\command&lt;/code&gt; bypass [@enigma0x3-2016-eventvwr] established the pattern. An auto-elevating binary consults &lt;code&gt;HKEY_CURRENT_USER&lt;/code&gt; before &lt;code&gt;HKEY_CLASSES_ROOT&lt;/code&gt; for a value the binary trusts to dispatch a child process. The limited user, who owns &lt;code&gt;HKCU&lt;/code&gt;, writes whatever they want into the value. The elevated binary executes the attacker&apos;s command line. March 2017 produced &lt;code&gt;sdclt.exe&lt;/code&gt; plus App Paths [@enigma0x3-2017-app-paths] and &lt;code&gt;sdclt.exe&lt;/code&gt; plus &lt;code&gt;IsolatedCommand&lt;/code&gt; [@enigma0x3-2017-sdclt]; May 2017 produced the &lt;code&gt;fodhelper.exe&lt;/code&gt; plus &lt;code&gt;ms-settings&lt;/code&gt; variant [@uacme]. All fileless. All generalising to any auto-elevating binary that walks &lt;code&gt;HKCU&lt;/code&gt; before &lt;code&gt;HKCR&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The COM-elevation-moniker abuse family.&lt;/strong&gt; UACMe&apos;s Method 1 (Davidson&apos;s original &lt;code&gt;IFileOperation&lt;/code&gt;) ages into Methods 41 (&lt;code&gt;ICMLuaUtil&lt;/code&gt;, Oddvar Moe, via &lt;code&gt;ucmCMLuaUtilShellExecMethod&lt;/code&gt;) and 43 (&lt;code&gt;IColorDataProxy&lt;/code&gt; paired with &lt;code&gt;ICMLuaUtil&lt;/code&gt;, Oddvar Moe derivative, via &lt;code&gt;ucmDccwCOMMethod&lt;/code&gt;), each one a different COM interface that auto-elevates and exposes a method useful for arbitrary file or registry write [@uacme].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The environment-variable and path-poisoning family.&lt;/strong&gt; Per-process &lt;code&gt;%windir%&lt;/code&gt; or &lt;code&gt;%SystemRoot%&lt;/code&gt; redirection via registry shims and Image File Execution Options, redirecting auto-elevating binaries to load resources from attacker-controlled directories.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The Windows 7 auto-elevation whitelist &lt;em&gt;was&lt;/em&gt; the bypass. The day Microsoft shipped a class of binaries that could elevate silently based on signing and path, the entire problem of UAC bypass reduced to &quot;make one of those binaries do something the attacker wants it to do.&quot; Every UACMe method that targets a Microsoft-signed binary in &lt;code&gt;System32&lt;/code&gt; descends from this design choice. The 81-method catalogue is not a list of separate vulnerabilities; it is one architectural mistake spreading through the binary inventory.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Enter &lt;strong&gt;hfiref0x&apos;s UACMe&lt;/strong&gt; [@uacme]. The project has been on GitHub since 2014. It currently lists 81 named methods. Each entry pairs the method number with the author credit, the target binary, the technique class, and the &quot;Fixed in&quot; build number. The README, taken together, is the institutional memory of UAC&apos;s failure as a boundary. Forshaw&apos;s January 2026 framing is the operational summary: &quot;A good repository of known bypasses is the UACMe tool which currently lists 81 separate techniques for gaining administrator privileges&quot; [@forshaw-pz-jan2026].&lt;/p&gt;
&lt;p&gt;Microsoft chose to fix individual bypasses rather than redesign the model. The next section asks whether seven years of fixes ever caught up.&lt;/p&gt;
&lt;h2&gt;5. 2017-2024: incremental hardening, no convergence&lt;/h2&gt;
&lt;p&gt;The middle Windows 10 era was the moment Microsoft treated UAC bypasses as a quality problem and shipped fixes at quality-fix cadence, not security-bulletin cadence. The work was real, but it was always one binary or one interface at a time.&lt;/p&gt;
&lt;p&gt;The named milestones, kept short.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Windows 10 1709 (October 2017).&lt;/strong&gt; Beginning with this build, &lt;code&gt;IFileOperation&lt;/code&gt; auto-elevation for callers other than Explorer was restricted [@uacme]. The originating Davidson 2009 family of bypasses, against the sysprep + planted-CRYPTBASE shape, ceased to function for processes other than the shell itself.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tighter &lt;code&gt;appinfo.dll&lt;/code&gt; manifest parsing across multiple Windows 10 builds.&lt;/strong&gt; Stricter binary-signature checks. Stricter path checks. Stricter manifest checks. Each of these closed individual bypass methods; none of them closed a family.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Per-binary hardening recorded in UACMe&apos;s &quot;Fixed in&quot; column.&lt;/strong&gt; UACMe version 3.5.0 retired roughly eighty percent of the 2014-vintage catalogue as obsolete; the v3.2.x branch retains the full historical record. The project&apos;s README warns that &quot;since version 3.5.0, all previously &apos;fixed&apos; methods are considered obsolete and have been removed. If you need them, use v3.2.x branch&quot; [@uacme].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CVE-2019-1388 (November 2019; reporter: Eduardo Braun Prado via Trend Micro&apos;s Zero Day Initiative).&lt;/strong&gt; The lone departure from the &quot;UAC bypasses get no CVE&quot; rule. A UI-interaction path through &lt;code&gt;consent.exe&lt;/code&gt;&apos;s certificate-viewer dialog: an unsigned application could trigger consent.exe to display a certificate dialog whose &quot;View Certificate&quot; link launched Internet Explorer running as &lt;code&gt;NT AUTHORITY\SYSTEM&lt;/code&gt;, and IE&apos;s File menu opened &lt;code&gt;cmd.exe&lt;/code&gt; at the same integrity level [@nvd-cve-2019-1388]. Microsoft fixed it on the November 2019 Patch Tuesday and gave it an LPE bulletin.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CVE-2019-1388 was a &lt;em&gt;prompt-UI&lt;/em&gt; bug -- specifically, a crash-path that surfaced an IE process at SYSTEM integrity via the certificate viewer -- not a UAC-bypass bug in the categorical sense. The classification distinction matters: Microsoft did not change its position that UAC was not a boundary; the bulletin treated this as a separate UI defect that incidentally crossed the boundary. CISA later added the CVE to the Known Exploited Vulnerabilities Catalog [@nvd-cve-2019-1388].&lt;/p&gt;
&lt;p&gt;The accumulating evidence by 2024 was three observations.&lt;/p&gt;
&lt;p&gt;UACMe&apos;s catalogue has grown from its 2014 origins to 81 methods today [@uacme]. Each &lt;em&gt;family&lt;/em&gt; of attack survived the &lt;em&gt;individual&lt;/em&gt; fixes. As Davidson predicted in 2009, the auto-elevation whitelist was the structural problem; patching each whitelisted binary as a separate bug was a treadmill, not a convergence.&lt;/p&gt;
&lt;p&gt;Microsoft&apos;s own Security Servicing Criteria continued to classify UAC as a security feature, not a boundary, throughout the period [@msrc-servicing-criteria, @forshaw-pz-jan2026]. The decision was load-bearing. Fixing the elevation pipeline at &lt;em&gt;quality&lt;/em&gt; cadence meant accepting that bypasses would appear quarterly and would not appear in the Patch Tuesday bulletins until the day Microsoft changed its mind about the classification.&lt;/p&gt;
&lt;p&gt;The third piece of evidence is what the attackers were doing while the defenders were churning the binary list. Microsoft&apos;s own number, quoted by the Windows Developer Blog from the Microsoft Digital Defense Report 2024, is &lt;em&gt;39,000 token-theft incidents per day&lt;/em&gt; [@ms-developer-blog-2025]. A token, once stolen from an elevated process, requires no further bypass: it is a bearer credential good for the lifetime of the logon session. The same logon session is the one the unelevated user and the elevated process share under the split-token model. The &quot;one logon session&quot; property of UAC&apos;s design is the structural premise that token theft depends on.&lt;/p&gt;
&lt;p&gt;There is one further thread worth naming here. Forshaw&apos;s broader 2022 Kerberos work in the user-credential-delegation space is a thread that survives the elevation-redesign question entirely. The May 2022 &lt;em&gt;Exploiting RBCD using a normal user account&lt;/em&gt; post [@forshaw-2022-rbcd] is the representative artifact. Network-credential delegation primitives -- Resource-Based Constrained Delegation, User-to-User Kerberos, S4U2Self -- operate at a layer beneath token-level elevation, and survive even a perfect SMAA design because they do not run through the elevation path at all.&lt;/p&gt;
&lt;p&gt;Piecewise fixes never converged on a boundary. The question that drove the next five years of Microsoft work was the obvious one: if the issue is the shared-resource model itself, what is the smallest plausible change that fixes it?&lt;/p&gt;
&lt;h2&gt;6. The breakthrough: the System Managed Administrator Account&lt;/h2&gt;
&lt;p&gt;The load-bearing design decision is one sentence. Stop trying to make one user account play both roles. The elevated administrator should be a different account with a different SID, a different profile, a different &lt;code&gt;HKCU&lt;/code&gt;, a different logon session, and a different DOS device object directory -- and the operating system should manage that account itself.&lt;/p&gt;
&lt;p&gt;What is striking about the design is how prosaic the underlying mechanism is. Multi-user accounts have shipped with Windows NT since version 3.1 in 1993. The architecture for running an elevated process under a separate local user has been present in NT for thirty-three years. What changed is that Microsoft finally chose to &lt;em&gt;enforce&lt;/em&gt; the multi-user model for privilege separation, by making the operating system itself create and manage the second account, link it to the primary admin via paired Security Account Manager attributes, and use it for every elevation. The sophistication is in linkage, in lifecycle, and in &lt;em&gt;removing auto-elevation&lt;/em&gt;, not in any single new primitive.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The thing that changes between UAC and Administrator Protection is not the elevation &lt;em&gt;mechanism&lt;/em&gt; (a manifest, a prompt, a &lt;code&gt;CreateProcessAsUser&lt;/code&gt; call) but the elevation &lt;em&gt;classification&lt;/em&gt;. An elevation bypass used to be a quality bug. It is now a security-bulletin vulnerability. Every Administrator Protection design decision -- separate account, fresh logon session, removed auto-elevation, Hello-gated consent -- is a consequence of the classification change.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The names. Microsoft Learn&apos;s term is &lt;strong&gt;Administrator Protection&lt;/strong&gt; [@ms-admin-protection]. Microsoft&apos;s announcement material at Ignite 2024 and in the Insider Preview build 27718 post uses the same &quot;Administrator Protection&quot; label [@ms-insider-build-27718]; &lt;strong&gt;Adminless&lt;/strong&gt; is the community shorthand that stuck. The internal engineering term in &lt;code&gt;samsrv.dll&lt;/code&gt; (the Security Account Manager service DLL) is &lt;strong&gt;ShadowAdmin&lt;/strong&gt; [@call4cloud-osint]. The Windows Developer Blog&apos;s canonical term for the underlying entity is the &lt;strong&gt;System Managed Administrator Account (SMAA)&lt;/strong&gt; [@ms-developer-blog-2025].&lt;/p&gt;

The hidden local user account that Windows creates per primary administrator when the `TypeOfAdminApprovalMode` policy is set to 2. The SMAA has its own random user name (typically `ADMIN_`), its own SID, its own profile directory under `C:\Users\ADMIN_\`, its own `NTUSER.DAT` and therefore its own `HKCU`, and its own membership in the local Administrators group. The operating system uses it to host elevated processes; the user never logs into it directly [@ms-developer-blog-2025, @call4cloud-osint].
&lt;p&gt;The SMAA lifecycle. Four beats. Each anchored to a verified source.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Provisioning.&lt;/strong&gt; When &lt;code&gt;TypeOfAdminApprovalMode = 2&lt;/code&gt; is set under &lt;code&gt;HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System&lt;/code&gt; (either by Group Policy or by the Intune Settings Catalog), &lt;code&gt;samsrv.dll&lt;/code&gt;&apos;s &lt;code&gt;ShadowAdminAccount::CreateShadowAdminAccount&lt;/code&gt; runs once per existing local-administrator account. &lt;code&gt;CreateRandomShadowAdminAccountName&lt;/code&gt; produces an &lt;code&gt;ADMIN_&amp;lt;random&amp;gt;&lt;/code&gt; name. &lt;code&gt;AddAccountToLocalAdministratorsGroup&lt;/code&gt; adds the new account to the Administrators group. Accounts managed by Windows LAPS (Local Administrator Password Solution) are skipped; their lifecycle is owned by a different subsystem and Microsoft did not want the SMAA mechanism to fight LAPS rotation [@call4cloud-osint].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Linking.&lt;/strong&gt; Two paired SAM attributes encode the trust relationship between the two accounts. The primary admin&apos;s user record gets a &lt;code&gt;ShadowAccountForwardLinkSid&lt;/code&gt; attribute pointing at the SMAA&apos;s SID. The SMAA&apos;s user record gets a &lt;code&gt;ShadowAccountBackLinkSid&lt;/code&gt; attribute pointing back at the primary admin. These two attributes are the only structural relationship between the two accounts; everything else -- profile, HKCU, group memberships -- is independent [@call4cloud-osint].&lt;/p&gt;

Two paired SAM-database attributes that encode the trust relationship between a primary admin user and its System Managed Administrator Account. The forward link sits on the primary admin&apos;s record and points at the SMAA&apos;s SID. The back link sits on the SMAA&apos;s record and points back at the primary admin. The Application Information service uses the forward link at elevation time to resolve which SMAA to launch the elevated process under [@call4cloud-osint].

The registry value under `HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System` that selects the elevation policy. Value 0 disables UAC. Value 1 selects classic Admin Approval Mode (the Vista / Win7 / Win10 split-token behaviour). Value 2 selects Admin Approval Mode with Administrator Protection: every elevation routes through the SMAA path. The value is set by Group Policy (&quot;User Account Control: Configure type of Admin Approval Mode&quot;) or by an Intune Settings Catalog policy and requires a reboot to take effect [@ms-admin-protection, @call4cloud-osint].
&lt;p&gt;&lt;strong&gt;Per-elevation use.&lt;/strong&gt; &lt;code&gt;appinfo.dll&lt;/code&gt;&apos;s &lt;code&gt;RAiLaunchAdminProcess&lt;/code&gt; RPC endpoint reads &lt;code&gt;TypeOfAdminApprovalMode&lt;/code&gt;. When the value is 2, it walks the forward link to find the calling user&apos;s SMAA, launches &lt;code&gt;consent.exe&lt;/code&gt; on the secure desktop in &lt;em&gt;credential&lt;/em&gt; prompt mode (not Yes/No), authenticates the primary user via Windows Hello (PIN, fingerprint, face, or password fallback), asks the kernel to ask LSA for a fresh primary token for the SMAA in a brand-new logon session, and calls &lt;code&gt;CreateProcessAsUser&lt;/code&gt; with that token, the user&apos;s requested executable, and the SMAA&apos;s profile environment [@ms-developer-blog-2025, @ms-admin-protection, @forshaw-pz-jan2026]. The credential-less LSA logon at the heart of step three of this beat is walked in §7.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Teardown.&lt;/strong&gt; When the elevated process exits, the SMAA&apos;s token handle goes out of scope. The logon session is reaped. The elevated profile directory remains on disk at &lt;code&gt;C:\Users\ADMIN_&amp;lt;random&amp;gt;\&lt;/code&gt; -- it has to, to preserve per-elevation user state across reboots -- but the live admin token does not. There is no persistent High-integrity process running between elevations [@ms-developer-blog-2025].&lt;/p&gt;

flowchart TD
    Start[Policy enabled: TypeOfAdminApprovalMode = 2] --&amp;gt; Provision
    Provision[samsrv.dll: CreateShadowAdminAccount per local admin] --&amp;gt; Naming
    Naming[CreateRandomShadowAdminAccountName -&amp;gt; ADMIN_random] --&amp;gt; AddGroup
    AddGroup[AddAccountToLocalAdministratorsGroup] --&amp;gt; Link
    Link[SAM linkage: ShadowAccountForwardLinkSid /&lt;br /&gt;ShadowAccountBackLinkSid] --&amp;gt; Idle[SMAA exists, no token live]
    Idle --&amp;gt;|Each elevation| RPC[appinfo.dll: RAiLaunchAdminProcess]
    RPC --&amp;gt; Prompt[consent.exe: Hello credential prompt]
    Prompt --&amp;gt; LSA[Kernel asks LSA: credential-less logon for SMAA]
    LSA --&amp;gt; Run[CreateProcessAsUser with SMAA token]
    Run --&amp;gt;|Process exits| Teardown[Token handle released;&lt;br /&gt;logon session reaped]
    Teardown --&amp;gt; Idle

Windows creates a temporary isolated admin token to get the job done. This temporary token is immediately destroyed once the task is complete, ensuring that admin privileges do not persist. -- David Weston, Microsoft Ignite 2024 keynote, November 19, 2024 [@bleepingcomputer-2024]
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The single design decision behind Administrator Protection: the elevated and unelevated halves of an administrator must be different accounts. Different SID, different profile, different &lt;code&gt;HKCU&lt;/code&gt;, different logon session, different DOS device object directory. The shared-resource attacks of the UAC bypass canon cannot persist if there are no shared resources.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The mechanism is now described. The next section walks it at function-name granularity for a single elevation, end to end -- and in particular, the credential-less LSA logon at step six that does the load-bearing work of minting the SMAA token without any SMAA credential.&lt;/p&gt;
&lt;h2&gt;7. The elevation pipeline end to end&lt;/h2&gt;
&lt;p&gt;Walk a single elevation. Nine steps.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The caller invokes &lt;code&gt;ShellExecute&lt;/code&gt; or &lt;code&gt;CreateProcess&lt;/code&gt; with an elevation request. For the shell-launched case the user right-clicks an executable and selects &quot;Run as administrator&quot;; the same RPC endpoint serves manifest-declared &lt;code&gt;requestedExecutionLevel = &quot;requireAdministrator&quot;&lt;/code&gt; callers and &lt;code&gt;Elevation:Administrator!new:&amp;lt;CLSID&amp;gt;&lt;/code&gt; COM moniker requests.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;appinfo.dll&lt;/code&gt;&apos;s &lt;code&gt;RAiLaunchAdminProcess&lt;/code&gt; RPC endpoint, hosted inside the Application Information service in &lt;code&gt;svchost.exe&lt;/code&gt;, receives the call [@ms-uac-how-it-works].&lt;/li&gt;
&lt;li&gt;&lt;code&gt;appinfo&lt;/code&gt; reads &lt;code&gt;HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System\TypeOfAdminApprovalMode&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If the value is 2 (Admin Approval Mode with Administrator Protection), &lt;code&gt;appinfo&lt;/code&gt; reads the calling user&apos;s SAM record, locates the &lt;code&gt;ShadowAccountForwardLinkSid&lt;/code&gt; attribute, and validates the corresponding &lt;code&gt;ShadowAccountBackLinkSid&lt;/code&gt; on the SMAA&apos;s SAM record. The linkage check is what binds a given elevated process to a given primary user; without both attributes pointing at each other, the elevation is refused [@call4cloud-osint].&lt;/li&gt;
&lt;li&gt;&lt;code&gt;appinfo&lt;/code&gt; launches &lt;code&gt;consent.exe&lt;/code&gt; on the secure desktop in &lt;em&gt;credential&lt;/em&gt; prompt mode rather than the classic Yes/No mode. The prompt asks the primary user to authenticate via Windows Hello (PIN, fingerprint, face, or password fallback), not the SMAA. The SMAA &lt;em&gt;has no human credentials&lt;/em&gt;. The Windows Developer Blog states the property explicitly [@ms-developer-blog-2025], and Forshaw&apos;s January 2026 post restates it in operational terms: &quot;The user does not need to know the credentials for the shadow administrator as there aren&apos;t any. Instead UAC can be configured to prompt for the limited user&apos;s credentials, including using biometrics if desired&quot; [@forshaw-pz-jan2026].&lt;/li&gt;
&lt;li&gt;On a positive Hello result, &lt;code&gt;appinfo.dll&lt;/code&gt; -- running as &lt;code&gt;NT AUTHORITY\SYSTEM&lt;/code&gt; inside the Application Information service -- asks the kernel to ask LSA for a fresh primary access token for the SMAA&apos;s SID in a brand-new logon session. The LSA logon is &lt;em&gt;credential-less&lt;/em&gt;. The kernel asks LSA to authenticate &quot;a new instance of the shadow administrator,&quot; and LSA fulfils the request without any SMAA credential because the SMAA has no credential to verify. The trust architecture mirrors the way the Service Control Manager asks LSA for service-account tokens: SCM is trusted to ask for the token; LSA mints it on the strength of the &lt;em&gt;request&lt;/em&gt; rather than on the strength of any credential. In Administrator Protection, &lt;code&gt;appinfo.dll&lt;/code&gt; is the trusted requester, and its request is gated on the user-side Hello result it received in step 5. The Forshaw verbatim that anchors the mechanism is below this section [@forshaw-pz-jan2026, @ms-developer-blog-2025].&lt;/li&gt;
&lt;li&gt;&lt;code&gt;appinfo&lt;/code&gt; calls &lt;code&gt;CreateProcessAsUser&lt;/code&gt; with the SMAA token, the user&apos;s requested executable, and the SMAA&apos;s profile environment block (&lt;code&gt;USERPROFILE=C:\Users\ADMIN_&amp;lt;random&amp;gt;&lt;/code&gt;, &lt;code&gt;USERNAME=ADMIN_&amp;lt;random&amp;gt;&lt;/code&gt;, the SMAA&apos;s &lt;code&gt;NTUSER.DAT&lt;/code&gt; mapped as &lt;code&gt;HKCU&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;The new process loads at High integrity, holding the SMAA&apos;s primary token, in a fresh logon session with a freshly minted authentication-ID LUID. The DOS device directory at &lt;code&gt;\Sessions\0\DosDevices\&amp;lt;LUID&amp;gt;&lt;/code&gt; does not yet exist; the kernel will create it on first reference.&lt;/li&gt;
&lt;li&gt;Subsequent &lt;code&gt;SeAccessCheck&lt;/code&gt; calls on system objects evaluate against the SMAA&apos;s local Administrators group membership and succeed. The elevated process can write to &lt;code&gt;HKLM&lt;/code&gt;, modify program files, install services, load WHQL-signed drivers (subject to App Control for Business and HVCI), and otherwise behave as a member of the Administrators group [@ms-developer-blog-2025].&lt;/li&gt;
&lt;/ol&gt;

The mechanism by which the Local Security Authority mints a primary access token for the SMAA without verifying any SMAA credential. `appinfo.dll`, running as `NT AUTHORITY\SYSTEM` inside the Application Information service, requests the logon on the SMAA&apos;s behalf after the primary user has succeeded against the Hello credential gate. LSA fulfils the request because the *requester* is trusted; the architecture mirrors the way the Service Control Manager requests service-account tokens. The &quot;credential-less&quot; label is descriptive of the SMAA side of the exchange: the SMAA never has a human credential to verify, so LSA cannot and does not ask for one [@forshaw-pz-jan2026, @ms-developer-blog-2025].
&lt;p&gt;The trust architecture is not new in Administrator Protection. The Service Control Manager has asked LSA for service-account tokens since Windows NT 3.1 in 1993; LSA accepts the request because SCM is the trusted requester, not because the service account presented a credential. Administrator Protection generalises the same pattern to elevation: &lt;code&gt;appinfo.dll&lt;/code&gt; is the trusted requester, and the SMAA is its functional analogue of a service account. What is new is the user-side gate -- the trusted requester only makes the request after a positive Hello result on the &lt;em&gt;primary user&apos;s&lt;/em&gt; credential.&lt;/p&gt;

in Administrator Protection the kernel calls into the LSA and authenticates a new instance of the shadow administrator. This results in every token returned from `TokenLinkedToken` having a unique logon session, and thus does not currently have the DOS device object directory created. -- James Forshaw, *Bypassing Windows Administrator Protection*, Google Project Zero, January 26, 2026 [@forshaw-pz-jan2026]
&lt;p&gt;The &quot;unique logon session&quot; property in Forshaw&apos;s quote is exactly the structural property the lazy-DOS-device-directory bypass exploits, and §12 walks that exploit in full. For now, the load-bearing observation is the credential-less logon itself: the SMAA token is real, the logon session is real, the integrity level is real, but no SMAA credential ever changes hands. The trust is in the requester, gated by a Hello gesture from the primary user.&lt;/p&gt;

sequenceDiagram
    participant User as User shell (primary admin filtered token)
    participant AppInfo as appinfo.dll (NT AUTHORITY\SYSTEM)
    participant SAM as samsrv.dll / SAM database
    participant Consent as consent.exe (secure desktop)
    participant Hello as Windows Hello / TPM
    participant LSA as LSASS
    participant Elev as Elevated SMAA process&lt;pre&gt;&lt;code&gt;User-&amp;gt;&amp;gt;AppInfo: ShellExecute &quot;as admin&quot;
AppInfo-&amp;gt;&amp;gt;AppInfo: RAiLaunchAdminProcess RPC
AppInfo-&amp;gt;&amp;gt;AppInfo: Read TypeOfAdminApprovalMode = 2
AppInfo-&amp;gt;&amp;gt;SAM: Resolve ShadowAccountForwardLinkSid
SAM--&amp;gt;&amp;gt;AppInfo: SMAA SID + backlink check OK
AppInfo-&amp;gt;&amp;gt;Consent: Launch consent.exe (credential mode)
Consent-&amp;gt;&amp;gt;Hello: Request Hello gesture for primary user
Hello--&amp;gt;&amp;gt;Consent: PIN / biometric / password verified
Consent--&amp;gt;&amp;gt;AppInfo: Approved
AppInfo-&amp;gt;&amp;gt;LSA: Credential-less logon for SMAA (trusted-requester pattern)
LSA--&amp;gt;&amp;gt;AppInfo: Fresh SMAA primary token and fresh LUID
AppInfo-&amp;gt;&amp;gt;Elev: CreateProcessAsUser with SMAA token and profile
Note over Elev: Different SID and USERPROFILE and HKCU and LUID
Note over Elev: Integrity level High -- DOS device dir not yet created
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A practical illustration of the shift, displayed as the diff between the pre-AP and post-AP elevated console session.&lt;/p&gt;
&lt;p&gt;{`
// Modelled output of &apos;whoami /all&apos; run from an elevated console.
// Before: TypeOfAdminApprovalMode = 1 (classic UAC).
// After:  TypeOfAdminApprovalMode = 2 (Administrator Protection).&lt;/p&gt;
&lt;p&gt;const before = {
  user: &apos;CONTOSO\\alice&apos;,
  sid: &apos;S-1-5-21-123456789-987654321-1122334455-1001&apos;,
  profile: &apos;C:\\Users\\alice&apos;,
  authId: &apos;0x3e7:0x000abcde&apos;,
  integrity: &apos;S-1-16-12288 (High)&apos;,
  groups: [&apos;BUILTIN\\Administrators (Enabled)&apos;]
};&lt;/p&gt;
&lt;p&gt;const after = {
  user: &apos;WIN11-PC\\ADMIN_9f2c7e1bdc4a8033&apos;,
  sid: &apos;S-1-5-21-123456789-987654321-1122334455-1051&apos;,
  profile: &apos;C:\\Users\\ADMIN_9f2c7e1bdc4a8033&apos;,
  authId: &apos;0x3e7:0x000abf42&apos;,
  integrity: &apos;S-1-16-12288 (High)&apos;,
  groups: [&apos;BUILTIN\\Administrators (Enabled)&apos;],
  shadowBacklink: &apos;CONTOSO\\alice&apos;
};&lt;/p&gt;
&lt;p&gt;console.log(&apos;Different user name:&apos;, before.user !== after.user);
console.log(&apos;Different SID:&apos;,       before.sid !== after.sid);
console.log(&apos;Different profile:&apos;,   before.profile !== after.profile);
console.log(&apos;Different LUID:&apos;,      before.authId !== after.authId);
console.log(&apos;Same integrity:&apos;,      before.integrity === after.integrity);
`}&lt;/p&gt;
&lt;p&gt;The pipeline is now a single chain of named function calls. The next section asks what &lt;em&gt;changed&lt;/em&gt; about the four shared-resource properties from §3, and which UAC-bypass family each fix forecloses.&lt;/p&gt;
&lt;h2&gt;8. The four shared-resources fixes, precisely&lt;/h2&gt;
&lt;p&gt;Each of the four shared resources from §3 maps to a precise Administrator Protection fix, and each fix maps to a named UAC-era attack class it forecloses.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Shared resource (UAC)&lt;/th&gt;
&lt;th&gt;Administrator Protection fix&lt;/th&gt;
&lt;th&gt;UAC-era attack class foreclosed&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Same SID across both tokens&lt;/td&gt;
&lt;td&gt;SMAA has its own SID; no shared user identity&lt;/td&gt;
&lt;td&gt;Same-user file and registry ACE confusion&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Same &lt;code&gt;%USERPROFILE%&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;SMAA has &lt;code&gt;C:\Users\ADMIN_&amp;lt;random&amp;gt;\&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;DLL side-load family (sysprep / CRYPTBASE)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Same &lt;code&gt;HKCU&lt;/code&gt; hive&lt;/td&gt;
&lt;td&gt;SMAA has its own &lt;code&gt;NTUSER.DAT&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Registry-hijack family (eventvwr, fodhelper, sdclt)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Same logon-session LUID&lt;/td&gt;
&lt;td&gt;SMAA gets a fresh LUID per elevation&lt;/td&gt;
&lt;td&gt;Token-theft via &lt;code&gt;TokenLinkedToken&lt;/code&gt;; logon-session DOS device hijack&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Profile separation.&lt;/strong&gt; The SMAA owns its own &lt;code&gt;%USERPROFILE%&lt;/code&gt; directory tree under &lt;code&gt;C:\Users\ADMIN_&amp;lt;random&amp;gt;\&lt;/code&gt;. Files created by elevated processes land there by default. Library folder divergence is the most visible consequence: an elevated Notepad&apos;s File &amp;gt; Save dialog opens at the SMAA&apos;s &lt;code&gt;Documents&lt;/code&gt;, not the primary user&apos;s. The primary user cannot see those files in their own Explorer without explicit cross-profile navigation. The structural property that closes is the writable-shared-directory premise of the Davidson 2009 DLL side-load family. Sysprep + CRYPTBASE was a profile-shared attack; without a shared profile, the elevated binary searches a different directory tree from the one the limited user can write to [@ms-developer-blog-2025].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Registry separation.&lt;/strong&gt; The SMAA&apos;s &lt;code&gt;HKCU&lt;/code&gt; maps to the SMAA&apos;s &lt;code&gt;NTUSER.DAT&lt;/code&gt;, not the primary user&apos;s. When &lt;code&gt;eventvwr.exe&lt;/code&gt;, running in an SMAA process, queries &lt;code&gt;HKCU\Software\Classes\mscfile\shell\open\command&lt;/code&gt;, it reads the SMAA&apos;s hive, not the primary user&apos;s. The primary user has no write access to the SMAA&apos;s &lt;code&gt;NTUSER.DAT&lt;/code&gt;. The entire registry-hijack family -- eventvwr / mscfile [@enigma0x3-2016-eventvwr], fodhelper / ms-settings, sdclt / IsolatedCommand [@enigma0x3-2017-sdclt], sdclt / App Paths [@enigma0x3-2017-app-paths] -- forecloses on the same property: the elevated binary&apos;s &lt;code&gt;HKCU&lt;/code&gt; lookup walks a hive the attacker does not control [@ms-developer-blog-2025].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Logon-session separation.&lt;/strong&gt; Every SMAA elevation gets a fresh authentication-ID LUID. The Local Security Authority allocates a new logon session for each elevation; when the elevated process exits, the session is reaped. Per-logon-session kernel resource caches, including the DOS device object directory at &lt;code&gt;\Sessions\0\DosDevices\&amp;lt;LUID&amp;gt;&lt;/code&gt; and the credential cache, do not flow across the boundary. Token handles cannot be reused. Drive-letter overrides under the limited user&apos;s logon session do not appear in the SMAA&apos;s session [@forshaw-pz-jan2026].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;No auto-elevation.&lt;/strong&gt; The &lt;code&gt;autoElevate=true&lt;/code&gt; manifest attribute is no longer honoured by &lt;code&gt;appinfo.dll&lt;/code&gt; under &lt;code&gt;TypeOfAdminApprovalMode = 2&lt;/code&gt;. Every elevation that previously went silent now prompts. The Windows Developer Blog states the change directly: &quot;With administrator protection, all auto-elevations in Windows are removed and users need to interactively authorize every admin operation&quot; [@ms-developer-blog-2025]. Forshaw&apos;s January 2026 framing of the consequence: &quot;as auto-elevation is no longer permitted they will always show a prompt, therefore these are not considered bypasses&quot; [@forshaw-pz-jan2026]. This is the single most consequential fix in the design. The auto-elevation whitelist &lt;em&gt;was&lt;/em&gt; the bypass; removing the whitelist eliminates the class at the source, including the entire silent-elevation primitive class that Forshaw&apos;s older &lt;code&gt;RAiProcessRunOnce&lt;/code&gt; research relied on.&lt;/p&gt;

Multi-user separation is the original UNIX privilege model. The `root` user holds privilege; ordinary users do not; the boundary between them is the file-permission system enforced by the kernel. Windows NT shipped the same primitives in 1993 -- discretionary access control lists on every securable object, per-user profiles, multi-user logon sessions -- but the surrounding culture treated Administrator-as-default as the path of least resistance. The architectural sophistication in Administrator Protection is in *linkage* (the SAM forward / back attributes), *lifecycle* (provisioning on policy enable, teardown on process exit), and *enforcement* (removal of auto-elevation as a mechanism). The primitives themselves are old.
&lt;p&gt;The four fixes share a property. Each one breaks a shared resource that an attacker depends on. But there is one more piece of the redesign that has not yet been described: the prompt itself is no longer a Yes/No click-through. The next section asks what happens when the consent UI becomes a credential.&lt;/p&gt;
&lt;h2&gt;9. Windows Hello as the consent gate&lt;/h2&gt;
&lt;p&gt;The classic UAC prompt is a Yes / No on the secure desktop. Administrator Protection turns the prompt into a &lt;em&gt;credential&lt;/em&gt; prompt for the &lt;em&gt;primary user&apos;s&lt;/em&gt; Windows Hello: a PIN, a fingerprint, a face match, or a password fallback. The credential is for the primary user, not the SMAA, because the SMAA has no human credentials; the Hello verification is what &lt;em&gt;authorises&lt;/em&gt; the cross-profile elevation [@ms-admin-protection, @ms-developer-blog-2025, @forshaw-pz-jan2026].&lt;/p&gt;
&lt;p&gt;To talk precisely about what the gate does, name the primitive it closes. Under classic UAC, the consent prompt treated a click on the secure desktop as sufficient evidence of consent; physical presence was the entire evidence requirement. That primitive shows up in three sub-cases that the UAC literature has documented for two decades.&lt;/p&gt;

The primitive by which the legacy UAC consent dialog accepted a click on the secure desktop as sufficient evidence of consent, without verifying *who* clicked. Three operational sub-cases follow. *Unattended-session click-through* -- an attacker (or co-located third party) with brief physical access to an unlocked screen showing a UAC prompt clicks Yes on the presumption that whoever is at the keyboard is the legitimate user. *Habituated-click click-through* -- the legitimate user has clicked Yes on hundreds of UAC prompts and clicks one more without conscious attention. *Pretext click-through* -- a malicious application argues a legitimate-looking case to the user and elicits the Yes click. Administrator Protection&apos;s credential gate cost-raises all three sub-cases without fully eliminating any [@forshaw-pz-jan2026, @ms-admin-protection].
&lt;p&gt;&lt;strong&gt;Unattended-session click-through.&lt;/strong&gt; An attacker who walks up to an unlocked screen showing a UAC prompt can click Yes and elevate. The legitimate user has authenticated; the prompt assumes the person at the keyboard is the legitimate user. Post-AP, the click is not sufficient. The Hello biometric or PIN is required, and the attacker (who does not know either) cannot complete the gesture. Microsoft&apos;s Ignite 2024 framing addresses this primitive implicitly with &quot;elevation rights only when needed&quot; and &quot;interactively authorize every admin operation&quot; [@bleepingcomputer-2024].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Habituated-click click-through.&lt;/strong&gt; A user who has clicked Yes on hundreds of UAC prompts over the course of a year clicks Yes on a malicious one as reflex. The classic UAC prompt requires no attentional engagement beyond physical presence and a click. Hello&apos;s gesture (a four-digit PIN entry, a fingerprint press, a face-recognition glance) is higher-friction and harder to perform inattentively. The Windows Developer Blog frames the property as &quot;just-in-time administrator privileges, incorporating Windows Hello to enhance both security and user convenience&quot; [@ms-developer-blog-2025].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pretext click-through.&lt;/strong&gt; A malicious application that argues its case to the user -- a fake installer, a re-skinned setup utility, a Trojan masquerading as a legitimate update -- can elicit a Yes click pre-AP. Post-AP, the user is also asked for a credential, which is a stronger user-side check. The user is more likely to interrogate &quot;why am I being asked for my PIN &lt;em&gt;again&lt;/em&gt;?&quot; than &quot;why is a prompt appearing?&quot; Microsoft Learn captures the intent as &quot;users are aware of potentially harmful actions before they occur, providing an extra layer of defense against threats&quot; [@ms-admin-protection].&lt;/p&gt;
&lt;p&gt;None of the three sub-cases is &lt;em&gt;fully&lt;/em&gt; eliminated. Forshaw is explicit that visible-prompt bypasses are not classified as security vulnerabilities by Microsoft&apos;s design-document position: bypasses that result in a visible prompt are not security bulletins, because the user could equivalently have launched the prompt themselves [@forshaw-pz-jan2026]. What the gate does is &lt;em&gt;cost-raise&lt;/em&gt; each sub-case. The unattended-screen attack requires a stolen PIN or coerced biometric. The habituated user must perform a gesture they cannot perform inattentively. The pretext attack must justify the second authentication, not just the first.&lt;/p&gt;
&lt;p&gt;What it does &lt;em&gt;not&lt;/em&gt; close is worth naming, because three primitives that look like they belong on the credential gate&apos;s account sheet were already closed by independent mechanisms, and the article should say so to avoid the common over-attribution mistake.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Synthetic-keystroke &lt;code&gt;SendInput&lt;/code&gt; against &lt;code&gt;consent.exe&lt;/code&gt;.&lt;/strong&gt; Already closed by UIPI in Vista 2006, and doubly closed by the secure-desktop switch to &lt;code&gt;Winsta0\Winlogon&lt;/code&gt;. Even UI Access processes -- whose purpose is to bypass UIPI for accessibility -- cannot reach into the secure desktop [@forshaw-pz-feb2026].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Headless UI Automation against the prompt.&lt;/strong&gt; Same UIPI / secure-desktop boundary closes it. Redundant with respect to the credential gate.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CVE-2019-1388-class UI-interaction paths surfaced through the prompt&apos;s own UI.&lt;/strong&gt; Closed by Microsoft&apos;s November 2019 HHCtrl patch and the cert-viewer UI redesign, prior to any Administrator Protection development [@nvd-cve-2019-1388].&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The credential is hardware-rooted via &lt;a href=&quot;https://paragmali.com/blog/the-tpm-in-windows-one-primitive-twenty-five-years-and-the-c/&quot; rel=&quot;noopener&quot;&gt;TPM&lt;/a&gt; or &lt;a href=&quot;https://paragmali.com/blog/pluton-a-tpm-on-silicon-microsoft-can-patch/&quot; rel=&quot;noopener&quot;&gt;Pluton&lt;/a&gt; on capable hardware. The PIN is unsealed only under the user&apos;s gesture; the biometric flows through Enhanced Sign-in Security (ESS) on capable hardware; the credential itself never leaves the Trusted Platform Module or Pluton enclave when ESS is engaged [@ms-windows-hello-ess]. The detail of the Hello architecture itself -- FIDO2 attestation, the &lt;code&gt;ngc&lt;/code&gt; protector, the ESS isolation path through the Secure Kernel -- belongs to the &lt;a href=&quot;https://paragmali.com/blog/your-face-is-not-your-password-inside-windows-hellos-hardwar/&quot; rel=&quot;noopener&quot;&gt;Windows Hello article&lt;/a&gt; in this series, and is not re-derived here.&lt;/p&gt;
&lt;p&gt;The new risk the gate does &lt;em&gt;not&lt;/em&gt; close is the obvious one. Phishing the prompt now phishes a &lt;em&gt;real credential&lt;/em&gt;, not just consent. A malicious application that can convince the user to authenticate on its behalf gets the elevation the user would otherwise have given to a legitimate request. The credential remains hardware-rooted and is not exfiltrated to the malware, but the elevation produces a working SMAA token in the attacker&apos;s process. This is the surface §15 carries forward to open problems.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The credential gate closes one specific primitive: &lt;em&gt;consent-without-identity-verification&lt;/em&gt;. It cost-raises three sub-cases (unattended-session, habituated-click, pretext click-through) without eliminating any. The structural boundary is profile separation plus fresh logon session plus auto-elevation removal; the credential gate is the fourth, defence-in-depth, property that ensures the boundary cannot be silently crossed by anyone holding only the limited user&apos;s physical access.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The prompt is a credential gate, but it remains a UI element. The next section asks how this elevation model compares to what other operating systems do.&lt;/p&gt;
&lt;h2&gt;10. Competing approaches: what other operating systems do&lt;/h2&gt;
&lt;p&gt;Three one-paragraph treatments. The article does not re-derive each system; it positions Administrator Protection against the field.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Linux: &lt;code&gt;sudo&lt;/code&gt; plus PolKit &lt;code&gt;pkexec&lt;/code&gt; plus PAM modules.&lt;/strong&gt; The authority model on Linux is file-based. &lt;code&gt;/etc/sudoers&lt;/code&gt; (or its LDAP equivalent) is the policy table; the &lt;code&gt;sudoers&lt;/code&gt; plugin reads it and decides whether to permit a given user to run a given command [@sudo-ws-sudoers]. PolKit -- &lt;code&gt;polkitd&lt;/code&gt; and its authentication-agent helpers -- is the parallel mechanism for GUI privileged-service requests, with actions and mechanisms separated in the polkit configuration files [@polkit-docs]. Biometric integration arrives through the PAM stack: &lt;code&gt;pam_fprintd&lt;/code&gt; for fingerprint, &lt;code&gt;pam_u2f&lt;/code&gt; for FIDO2 tokens, &lt;code&gt;pam_yubico&lt;/code&gt; for Yubikeys. There is no profile separation by default; &lt;code&gt;sudo -i&lt;/code&gt; switches &lt;code&gt;HOME&lt;/code&gt; to root&apos;s home directory but does not separate per-elevation. The model is per-command authorisation, not per-account isolation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;macOS: Authorization Services plus Touch ID via &lt;code&gt;pam_tid&lt;/code&gt;.&lt;/strong&gt; GUI elevation prompts are gated by &lt;code&gt;authorizationdb&lt;/code&gt;, a property-list-format policy database whose rules name which credentials (admin password, Touch ID, system-wide entitlements) authorise which actions [@apple-auth-services]. Touch ID is verified by the Secure Enclave Processor; the credential never leaves the SEP, and Authorization Services integrates with &lt;code&gt;pam_tid&lt;/code&gt; to allow &lt;code&gt;sudo&lt;/code&gt; invocations to use the gesture [@apple-pam-tid]. There is no separate admin profile; Transparency, Consent, and Control (TCC) guards privileged resource access at the per-action level, not the per-profile level. The Mac architecture privileges hardware-rooted consent (Touch ID, Secure Enclave) over account separation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Microsoft&apos;s own &lt;code&gt;sudo.exe&lt;/code&gt; (Windows 11 24H2).&lt;/strong&gt; An inbox terminal transport that triggers the &lt;em&gt;existing&lt;/em&gt; UAC or Administrator Protection pipeline; not an alternative to either [@ms-sudo-docs]. The &lt;code&gt;forceNewWindow&lt;/code&gt; mode opens an elevated console in a new window. The &lt;code&gt;disableInput&lt;/code&gt; mode keeps the elevated console in the current window but blocks keyboard input to it from the unelevated terminal. The &lt;code&gt;normal&lt;/code&gt; (inline) mode preserves POSIX-style pipes between the unelevated and elevated processes. Microsoft Learn warns explicitly about the inline mode: &quot;Sudo for Windows can be used as a potential escalation of privilege vector when enabled in certain configurations&quot; [@ms-sudo-docs]. The mechanism is RPC between the unelevated and elevated &lt;code&gt;sudo.exe&lt;/code&gt; processes; the elevation itself still goes through &lt;code&gt;appinfo.dll&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Intune Endpoint Privilege Management (EPM).&lt;/strong&gt; Cloud-policy-driven virtual-account elevation [@ms-epm-overview]. EPM performs elevation via a &lt;em&gt;virtual&lt;/em&gt; account that is not a member of the local Administrators group; the elevation rights are conferred only for the duration of the policy-permitted action. Three elevation modes are available: Automatic (no user interaction), User-confirmed (a prompt), and Elevate as Current User (the action runs as the user&apos;s elevated identity rather than the virtual account). EPM is architecturally complementary to Administrator Protection: EPM is the &lt;em&gt;enterprise policy&lt;/em&gt; story, Administrator Protection is the &lt;em&gt;per-device architecture&lt;/em&gt; story. The two can coexist on the same device.&lt;/p&gt;
&lt;p&gt;The distinguishing property of Administrator Protection in this comparison is whole-profile separation: the SMAA&apos;s own profile, the SMAA&apos;s own &lt;code&gt;HKCU&lt;/code&gt;, the SMAA&apos;s own library folders, plus a fresh logon session per elevation. Neither Linux &lt;code&gt;sudo&lt;/code&gt; nor macOS Authorization Services provides that property as a default desktop primitive. EPM provides per-elevation isolation via the virtual account but does not give the elevated process a persistent profile, which is what makes Administrator Protection&apos;s compatibility story so different from EPM&apos;s.&lt;/p&gt;
&lt;p&gt;Administrator Protection is the architecturally tightest desktop elevation model now in production. The next section asks where the boundary still leaks.&lt;/p&gt;
&lt;h2&gt;11. Theoretical limits: what Administrator Protection cannot fix&lt;/h2&gt;
&lt;p&gt;Four structural ceilings.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Showing a prompt is not crossing the boundary.&lt;/strong&gt; Microsoft&apos;s design position is explicit: bypasses that result in a &lt;em&gt;visible&lt;/em&gt; elevation prompt are not security bulletins, because the user could equivalently have right-clicked &quot;Run as administrator.&quot; Forshaw&apos;s January 2026 post states the position verbatim: &quot;I expect that malware will still be able to get administrator privileges even if that&apos;s just by forcing a user to accept the elevation prompt&quot; [@forshaw-pz-jan2026]. The operational consequence is that social-engineering the consent dialog remains a structural attack surface. The prompt is a UI element. The boundary is the credential gate. The gate is only as strong as the user&apos;s resistance to whatever pretext induces them to authenticate.&lt;/p&gt;

The MSRC servicing-criteria definition of a security boundary: a logical separation between code or data of different trust levels, intended to be enforced by the operating system and accompanied by a Microsoft commitment to issue a security update when an unauthorised crossing is found. UAC under the classic split-token model is classified as a *security feature*, not a boundary; bypasses receive quality-fix attention but not security-bulletin attention. Administrator Protection is the first elevation mechanism classified as a security boundary, with bulletin-grade fixes when it fails [@msrc-servicing-criteria, @forshaw-pz-jan2026].
&lt;p&gt;&lt;strong&gt;Admin equals kernel.&lt;/strong&gt; Once code is running inside an SMAA elevated process, it has the local Administrators group; it can write to &lt;code&gt;HKLM&lt;/code&gt;; it can install services; it can load WHQL-signed drivers; it can call into kernel-mode interfaces gated by &lt;code&gt;SeLoadDriverPrivilege&lt;/code&gt; and the App Control for Business policy. The MSRC servicing-criteria position that &quot;admin-to-kernel is not a security boundary&quot; continues to apply inside the SMAA [@msrc-servicing-criteria]. Administrator Protection makes the path &lt;em&gt;to&lt;/em&gt; admin into a boundary; it does not change the relationship between admin and kernel. Driver-loading controls remain the domain of WHQL signing, the Microsoft Vulnerable Driver Blocklist (default-on in Windows 11 since the 2022 update), App Control for Business policies, and Hypervisor-protected Code Integrity (HVCI) [@ms-vuln-driver-blocklist]. The &lt;a href=&quot;https://paragmali.com/blog/windows-app-identity-33-year-reinvention/&quot; rel=&quot;noopener&quot;&gt;App Identity article&lt;/a&gt; in this series covers the App Control mechanism in detail.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The SMAA is in the local Administrators group.&lt;/strong&gt; Discretionary access control list-based exposures of admin-only resources -- &lt;code&gt;CREATOR OWNER&lt;/code&gt; ACEs on persistent objects, world-writable DACLs on certain &lt;code&gt;\Sessions\0\DosDevices&lt;/code&gt; entries, default-permissive ACLs on a handful of legacy registry trees -- still grant the SMAA full access. The boundary is between &lt;em&gt;standard user&lt;/em&gt; and &lt;em&gt;SMAA&lt;/em&gt;, not between &lt;em&gt;SMAA&lt;/em&gt; and &lt;em&gt;SYSTEM&lt;/em&gt;. The SMAA is a high-privilege actor inside the operating system; the relationship between it and the rest of the privileged surface is unchanged.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Out of scope per Microsoft Learn.&lt;/strong&gt; Remote logon, roaming profiles, backup-admin accounts, Managed Service Accounts and group Managed Service Accounts (MSAs and gMSAs), virtual accounts for services, and domain-admin scenarios are explicitly outside the Administrator Protection model in its current form [@ms-admin-protection]. The feature is local-machine-only, interactive-admin-only. Domain administrators who log into a workstation will not see the SMAA path; service accounts under &lt;code&gt;LOCAL SERVICE&lt;/code&gt;, &lt;code&gt;NETWORK SERVICE&lt;/code&gt;, or &lt;code&gt;IIS_IUSRS&lt;/code&gt; are unaffected.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; A genuine architectural ceiling on consent-prompt elevation: the prompt is a UI element; the boundary is the credential gate; the gate is only as strong as the user&apos;s resistance to social engineering. Closing the gap requires out-of-band consent (smartcard, phone push) or per-action policy without human consent in the loop (EPM&apos;s automatic mode). Neither is the default.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Four limits, four sentences. The next section walks the concrete evidence of what actually leaked in the pre-GA Insider Preview builds, and what Microsoft did about it.&lt;/p&gt;
&lt;h2&gt;12. Forshaw&apos;s nine bypasses, classified&lt;/h2&gt;
&lt;p&gt;Between October 2024, when Administrator Protection first appeared in Insider Preview build 27718, and October 2025, when KB5067036 made the feature available on stable Windows, James Forshaw of Google Project Zero audited the mechanism and found nine separate silent-bypass paths. Microsoft fixed all nine -- either in the KB5067036 ship or in subsequent security bulletins [@forshaw-pz-jan2026]. The fact pattern is the structural confirmation that Administrator Protection is now treated as a security boundary. Under the UAC classification, none of those nine would have received CVEs. Each one would have been a quality bug. The bypass canon ran for twenty years without bulletins. The fact that the first cohort of Administrator Protection bypasses produced nine bulletin-eligible fixes is exactly the change in posture the classification change implies.&lt;/p&gt;

All the issues that I reported to Microsoft have been fixed, either prior to the feature being officially released (in optional update KB5067036) or as subsequent security bulletins. -- James Forshaw, *Bypassing Windows Administrator Protection*, Google Project Zero, January 26, 2026 [@forshaw-pz-jan2026]
&lt;p&gt;Walk the nine as three classes.&lt;/p&gt;
&lt;h3&gt;The lazy DOS device directory hijack&lt;/h3&gt;
&lt;p&gt;The single most interesting vulnerability in the feature&apos;s history; Forshaw&apos;s January 26, 2026 deep analysis [@forshaw-pz-jan2026]; Project Zero issue 432313668 [@pz-issue-432313668]. The mechanism turns on a behaviour change Administrator Protection itself introduced. Every SMAA elevation gets a &lt;em&gt;fresh&lt;/em&gt; logon session, which means the per-logon-session DOS device object directory at &lt;code&gt;\Sessions\0\DosDevices\&amp;lt;LUID&amp;gt;&lt;/code&gt; is not created at SMAA logon time. The kernel routine &lt;code&gt;SeGetTokenDeviceMap&lt;/code&gt; creates the directory &lt;em&gt;lazily&lt;/em&gt;, on the first reference. The owner of the new directory is the owner of the access token that triggered the creation [@forshaw-pz-jan2026, @theregister-2026].&lt;/p&gt;

The impersonation level (`SecurityIdentification`) at which an impersonating thread can read security information about the impersonated token -- the SID set, the privilege set -- but cannot perform privileged operations or open kernel objects as the impersonated user. The kernel allows access checks to consult an identification-level token for *reading* the security information; certain code paths inadvertently use that information for *granting* operations, which is the structural primitive Forshaw&apos;s lazy DOS device directory exploit depends on [@forshaw-pz-jan2026].
&lt;p&gt;The &lt;code&gt;SECURITY_IMPERSONATION_LEVEL&lt;/code&gt; enumeration in &lt;code&gt;winnt.h&lt;/code&gt; defines four levels in ascending order: &lt;code&gt;SecurityAnonymous&lt;/code&gt; (value 0), &lt;code&gt;SecurityIdentification&lt;/code&gt; (1), &lt;code&gt;SecurityImpersonation&lt;/code&gt; (2), &lt;code&gt;SecurityDelegation&lt;/code&gt; (3). &lt;code&gt;SecurityIdentification&lt;/code&gt; is the second-lowest -- it sits one above &lt;code&gt;SecurityAnonymous&lt;/code&gt; -- and is the level Windows uses when it wants to ask the kernel &quot;what would this token be allowed to do?&quot; without actually doing the operation. The trap is when a code path that runs &lt;em&gt;as the caller&lt;/em&gt; uses an identification-level impersonation to read a token property -- here, the linked-token field -- and the resulting object inherits the caller&apos;s owner SID rather than the impersonated token&apos;s.&lt;/p&gt;
&lt;p&gt;The exploit chain. An attacker running as the primary user (filtered token, Medium integrity) starts an elevation. Before the SMAA process touches its DOS device directory, the attacker impersonates the SMAA&apos;s &lt;code&gt;TokenLinkedToken&lt;/code&gt; at identification level and triggers a code path that walks the directory. The kernel creates &lt;code&gt;\Sessions\0\DosDevices\&amp;lt;SMAA_LUID&amp;gt;&lt;/code&gt; lazily; in the affected code path, the owner of the new directory becomes the attacker&apos;s primary token&apos;s owner SID rather than the SMAA&apos;s.&lt;/p&gt;
&lt;p&gt;The attacker plants a &lt;code&gt;C:&lt;/code&gt; symbolic link inside the directory pointing at an attacker-controlled location. When the elevated SMAA process loads its DLLs, the resolution walks &lt;code&gt;\Sessions\0\DosDevices\&amp;lt;SMAA_LUID&amp;gt;\C:&lt;/code&gt; first; the symlink redirects the load to the attacker&apos;s directory; the attacker&apos;s DLL runs in the High-integrity SMAA process [@forshaw-pz-jan2026].&lt;/p&gt;

sequenceDiagram
    participant Att as Attacker (limited user)
    participant Kern as &quot;Kernel (SeGetTokenDeviceMap)&quot;
    participant SMAA as SMAA elevated process&lt;pre&gt;&lt;code&gt;Note over SMAA: Fresh logon session -- DOS device dir not yet created
Att-&amp;gt;&amp;gt;Att: Impersonate SMAA TokenLinkedToken at Identification level
Att-&amp;gt;&amp;gt;Kern: Reference \Sessions\0\DosDevices\&amp;lt;SMAA_LUID&amp;gt;
Kern-&amp;gt;&amp;gt;Kern: Lazy-create directory
Note over Kern: Owner SID inherited from impersonating token
Att-&amp;gt;&amp;gt;Kern: Create C: symlink under attacker control
SMAA-&amp;gt;&amp;gt;Kern: Resolve C: at first DLL load
Kern--&amp;gt;&amp;gt;SMAA: Returns attacker symlink target
SMAA-&amp;gt;&amp;gt;SMAA: Load attacker DLL at High integrity
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What makes this bypass extraordinary is that it is &lt;em&gt;caused by&lt;/em&gt; the feature&apos;s design. Pre-Administrator-Protection, the user&apos;s primary logon session was created at desktop logon and the DOS device directory existed before any elevation. Lazy directory creation never came up. The SMAA design&apos;s &quot;fresh logon session per elevation&quot; property -- the same property Forshaw&apos;s January 2026 pull-quote in §7 establishes via the credential-less LSA logon -- is exactly the precondition the lazy-creation path exploits.&lt;/p&gt;
&lt;p&gt;Microsoft&apos;s pre-GA fix has two parts. First, the manifest-parsing access check uses the SYSTEM-impersonating-the-low-user identity rather than the user&apos;s primary token. Second, the DOS device directory is materialised with the correct owner before any user-controlled code path can trigger the lazy-creation path [@forshaw-pz-jan2026]. The Register&apos;s coverage of the disclosure noted &quot;the most notable of the nine bugs he reported was a Logon Sessions flaw that relied upon five different Windows behaviors. He added that he likely only found it because he was previously familiar with the OS&apos;s &apos;weird behavior when creating the DOS device object directory&apos;&quot; [@theregister-2026].&lt;/p&gt;
&lt;h3&gt;The five UI Access bypasses&lt;/h3&gt;
&lt;p&gt;Forshaw&apos;s February 2026 post details the second class, comprising five of the nine bypasses [@forshaw-pz-feb2026]. UI Access is a token flag retrofitted in Vista to let accessibility applications cross UIPI. To qualify, an executable needs three things: a manifest declaring &lt;code&gt;uiAccess=&quot;true&quot;&lt;/code&gt;, a trusted code-signing certificate, and an installation location under an administrator-only directory (typically &lt;code&gt;%ProgramFiles%&lt;/code&gt;). The Application Information service&apos;s &lt;code&gt;RAiLaunchAdminProcess&lt;/code&gt; endpoint launches qualifying UI Access processes &lt;em&gt;without showing the consent prompt&lt;/em&gt;, on the theory that the three-criteria check is itself sufficient evidence of administrator approval [@forshaw-pz-feb2026].&lt;/p&gt;

The token flag (`TOKEN_UIACCESS`) that allows a process to interact with windows of higher integrity level than its own, bypassing User Interface Privilege Isolation. UI Access is meant for accessibility software (screen readers, on-screen keyboards) that needs to interact with elevated UI. To qualify, an executable must carry a `uiAccess=&quot;true&quot;` manifest, a trusted code-signing certificate, and an administrator-only installation directory; qualifying processes run without showing the consent prompt and at integrity level High [@forshaw-pz-feb2026].
&lt;p&gt;Under classic UAC, a UI Access process ran with the filtered standard-user token bumped from Medium to High integrity -- not with the full admin token. Forshaw&apos;s February 2026 post states the mechanism verbatim: &quot;the service will take a copy of the caller&apos;s access token, enable the UI Access flag and increase the integrity level... If the caller is a limited user of an UAC administrator it will set the integrity level to High&quot; [@forshaw-pz-feb2026].&lt;/p&gt;
&lt;p&gt;Under Administrator Protection, the pre-GA design preserved that behaviour unchanged: the UI Access process inherited the limited user&apos;s primary token (not the SMAA&apos;s), bumped to High integrity. That decision was the structural flaw. A High-integrity process under the limited user can interact with the SMAA&apos;s windows whenever a High-integrity SMAA process exists on the same desktop, send messages to them, read clipboard data, and -- through &lt;code&gt;GetProcessHandleFromHwnd&lt;/code&gt; -- obtain a process handle on the SMAA process that lets the limited-user process inject code into it.&lt;/p&gt;
&lt;p&gt;The five UI Access variants exploit different sub-categories of the same structural property. The Quick Assist binary, a remote assistance application on Windows 10 and 11 that carries the uiAccess flag, is one such variant; R41N3RZUF477 published a public proof-of-concept that exploits the &lt;code&gt;BrowserExecutableFolder&lt;/code&gt; group policy to make Quick Assist load WebView2 from an attacker-controlled directory [@quickassist-bypass]. The remaining four exploit, respectively, weaknesses in the secure-application-directory check, the manifest parsing routine, COM marshalling in UI Access contexts, and message-only window handling [@forshaw-pz-feb2026].&lt;/p&gt;
&lt;p&gt;Microsoft&apos;s pre-GA fix is structural: UI Access processes no longer run as the limited user. They are created with a &lt;em&gt;filtered copy of the SMAA&apos;s token&lt;/em&gt; (the SMAA&apos;s SID, the SMAA&apos;s profile, but with &lt;code&gt;SeLoadDriverPrivilege&lt;/code&gt; and similar removed). Profile separation is restored at the cost of a more complex token-creation path [@forshaw-pz-feb2026].&lt;/p&gt;
&lt;h3&gt;The remaining three: implementation flaws&lt;/h3&gt;
&lt;p&gt;The third class -- three bypasses described by Forshaw only as &quot;implementation flaws and long-standing UAC issues&quot; -- is not detailed publicly [@forshaw-pz-jan2026]. The article does not invent details. Forshaw names the category and cites the framing; the engineering specifics are presumably in Microsoft Security Response Center advisories or are still under disclosure. What can be said is that two of the three appear from Forshaw&apos;s framing to be UAC-era bugs that Administrator Protection inherited rather than introduced, and one is an Administrator-Protection-specific implementation flaw.&lt;/p&gt;
&lt;p&gt;The bypass canon ran for twenty years without bulletins. The fact that all nine pre-GA Administrator Protection bypasses received fixes -- including a deep one rooted in the feature itself -- is the structural confirmation that the elevation path is now a boundary. The next section asks why Microsoft pulled the feature in December 2025.&lt;/p&gt;
&lt;h2&gt;13. The compatibility surface and the December 2025 revert&lt;/h2&gt;
&lt;p&gt;About one month after KB5067036 made Administrator Protection available, Microsoft pulled it. Forshaw, writing in January 2026, gives the canonical attribution: &quot;As of 1st December 2025 the Administrator Protection feature has been disabled by Microsoft while an application compatibility issue is dealt with. The issue is unlikely to be related to anything described in this blog post so the analysis doesn&apos;t change&quot; [@forshaw-pz-jan2026]. Microsoft Learn confirms: &quot;The feature previously listed in the October 2025 non-security update (KB5067036) has been reverted and will roll out at a later date&quot; [@ms-admin-protection, @ms-kb5067036].The November 2025 KB5067036 amendment is worth knowing. Microsoft included an unrelated fix for an AutoCAD MSI-repair UAC-prompt regression in the same cumulative; that fix shipped and was not reverted. The WebView2 installer regression is what caused the Administrator Protection revert specifically [@ms-kb5067036].&lt;/p&gt;
&lt;p&gt;The structural causes. The Windows Developer Blog (May 2025) [@ms-developer-blog-2025] enumerates the surface where applications break under the SMAA model.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Single sign-on does not cross.&lt;/strong&gt; Domain and Microsoft Entra credentials cached for the primary user&apos;s session are not available inside the SMAA&apos;s session. Any elevated process touching Microsoft Graph, Entra ID, or Kerberos-protected resources must re-authenticate. The login dialogs an elevated installer triggers are not failures of the application; they are consequences of the separated logon session.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Network drives do not carry.&lt;/strong&gt; Drive-mapping in the primary user&apos;s session is not inherited by the SMAA. Installers that mount network shares to install per-machine components break. The workaround for affected installers is to use UNC paths directly rather than drive letters.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Library folders diverge.&lt;/strong&gt; Files saved to &lt;code&gt;Documents&lt;/code&gt;, &lt;code&gt;Desktop&lt;/code&gt;, &lt;code&gt;Downloads&lt;/code&gt;, or &lt;code&gt;Pictures&lt;/code&gt; from an elevated app land in &lt;code&gt;C:\Users\ADMIN_&amp;lt;random&amp;gt;\&lt;/code&gt; rather than the primary user&apos;s home. A user clicks Save in an elevated text editor and saves to &quot;Documents&quot;; from their own Explorer, the file is invisible.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HKCU diverges.&lt;/strong&gt; Application settings -- theme, recent-files lists, per-user COM registrations, last-opened paths -- live in the SMAA&apos;s &lt;code&gt;HKCU&lt;/code&gt;, not the primary user&apos;s. The canonical example in Microsoft&apos;s documentation is Notepad&apos;s dark-mode theme [@ms-developer-blog-2025]: the primary user sets the theme; an elevated Notepad opens in the default theme; the two sessions never agree.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;WebView2 installers fail.&lt;/strong&gt; The error message &quot;Microsoft Edge can&apos;t read and write to its data directory&quot; is the recognisable symptom of an installer that assumes one shared profile. The WebView2 runtime stores per-user state in &lt;code&gt;AppData\Local\Microsoft\EdgeWebView\&lt;/code&gt; under whichever profile is active at install time; if the runtime is installed under the SMAA&apos;s profile and then used by an unelevated application running as the primary user, the data-directory write fails. This is the regression that triggered the December 2025 revert.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hyper-V and WSL incompatibilities.&lt;/strong&gt; Microsoft Learn explicitly tells IT administrators not to enable Administrator Protection on devices that require Hyper-V or WSL [@ms-admin-protection].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Visual Studio.&lt;/strong&gt; Microsoft&apos;s own development environment is &quot;not supported in such a configuration&quot; when run elevated. Extensions don&apos;t carry; settings don&apos;t carry; project-dialog paths point at the SMAA&apos;s profile rather than the developer&apos;s actual workspace.&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Microsoft Learn explicitly excludes Hyper-V and WSL devices from the recommended enablement set [@ms-admin-protection]. Symptoms of incorrect enablement include WSL distribution startup failures (the WSL service runs under a different account from the launching user, and the SMAA&apos;s logon-session-isolation properties interact badly with WSL&apos;s named-pipe communication) and Hyper-V Manager connection errors that are difficult to attribute to the elevation model.&lt;/p&gt;
&lt;/blockquote&gt;

I guess app compatibility is ultimately the problem here, Windows isn&apos;t designed for such a radical change. I&apos;d have also liked to have seen this as a separate configurable mode rather than replacing admin-approval completely. -- James Forshaw, *Bypassing Windows Administrator Protection*, Google Project Zero, January 26, 2026 [@forshaw-pz-jan2026]

Administrator Protection is the right architecture, and the compatibility surface is the bill of materials for twenty years of admin-as-default assumption. Application developers have written installer logic, theme-persistence code, drive-letter assumptions, and HKCU-shared state into shipping software for two decades, on the structural premise that the elevated process and the unelevated user share a profile. The December 2025 revert is the first iteration&apos;s learning round, not a structural failure. The same revert pattern accompanied the Windows Vista UAC rollout in 2006-2007, the Windows 7 auto-elevation introduction in 2009 (which itself softened the Vista prompt fatigue at the cost of the bypass canon), and the Smart App Control rollout in Windows 11 22H2. Microsoft will re-enable Administrator Protection when the WebView2 regression and a handful of installer-pattern fixes have shipped.
&lt;p&gt;The architecture survives audit. The deployment is held back by twenty years of accumulated software assumptions. The next section asks what tools defenders now have that they did not have before.&lt;/p&gt;
&lt;h2&gt;14. The audit and detection surface&lt;/h2&gt;
&lt;p&gt;Every privileged operation on a device with Administrator Protection enabled now generates an ETW (Event Tracing for Windows) event in the &lt;code&gt;Microsoft-Windows-LUA&lt;/code&gt; provider [@ms-admin-protection]. This is the first time the elevation pipeline itself is the &lt;em&gt;source&lt;/em&gt; of a stable, operationally useful audit trail.&lt;/p&gt;
&lt;p&gt;The basics.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Provider: &lt;code&gt;Microsoft-Windows-LUA&lt;/code&gt;, GUID &lt;code&gt;{93c05d69-51a3-485e-877f-1806a8731346}&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Event ID 15031: Elevation Approved.&lt;/li&gt;
&lt;li&gt;Event ID 15032: Elevation Denied or Failed.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each event carries the caller user SID, the application name and path, the elevation outcome, the SMAA used to host the elevation, and the authentication method (Hello PIN, biometric, password) [@ms-admin-protection]. The authentication method field records the &lt;em&gt;primary user&apos;s&lt;/em&gt; Hello credential, not the SMAA&apos;s; the SMAA&apos;s authentication in step 6 of §7 is the credential-less LSA logon and has no method field of its own. The Microsoft Learn-documented &lt;code&gt;logman&lt;/code&gt; invocation to capture the trace is short:&lt;/p&gt;

The Event Tracing for Windows provider that surfaces Administrator Protection elevation events. Provider GUID `{93c05d69-51a3-485e-877f-1806a8731346}`. Event ID 15031 marks an elevation that succeeded; Event ID 15032 marks an elevation that was denied or failed. Each event carries fields for the caller&apos;s SID, the application path, the elevation outcome, the SMAA used, and the authentication method [@ms-admin-protection].
&lt;p&gt;{`
// Pseudocode for a detection pipeline that reads ETW Event 15031
// (Administrator Protection elevation approved) and flags unusual
// application paths per SMAA correlation key.&lt;/p&gt;
&lt;p&gt;const allowList = new Set([
  &apos;C:\\Windows\\System32\\mmc.exe&apos;,
  &apos;C:\\Windows\\System32\\regedit.exe&apos;,
  &apos;C:\\Windows\\System32\\cmd.exe&apos;,
  &apos;C:\\Program Files\\Microsoft VS Code\\Code.exe&apos;,
]);&lt;/p&gt;
&lt;p&gt;function onEtwEvent(event) {
  if (event.provider !== &apos;Microsoft-Windows-LUA&apos;) return;
  if (event.id !== 15031) return;&lt;/p&gt;
&lt;p&gt;  const smaa = event.fields.shadowAccountName;
  const app  = event.fields.applicationPath;
  const auth = event.fields.authenticationMethod;
  const user = event.fields.callerUserSid;&lt;/p&gt;
&lt;p&gt;  if (!allowList.has(app)) {
    emit({
      severity: &apos;high&apos;,
      title: &apos;Unexpected elevation under Administrator Protection&apos;,
      smaa, app, auth, user,
      hint: &apos;Was the Hello prompt phished?&apos;
    });
  }
}
`}&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; For detection engineers, the &lt;code&gt;ADMIN_&amp;lt;random&amp;gt;&lt;/code&gt; name is the highest-value correlation key on the device. It is stable per primary admin (the SMAA name is created once and persists across elevations), distinct from the limited-user SID (the SMAA has its own SID, so user-by-SID correlations and SMAA-by-name correlations are independent axes), and present in every ETW 15031 / 15032 event. A detection rule that groups elevations by SMAA name and flags unexpected application paths is the canonical &quot;someone phished a Hello prompt&quot; alert pattern.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Defenders now have the audit trail they did not have under UAC. The next section asks what residual attack surface survives the SMAA architecture, the Hello gate, and the new audit trail.&lt;/p&gt;
&lt;h2&gt;15. Open problems: what survives&lt;/h2&gt;
&lt;p&gt;Five residual attack surfaces, each acknowledged in Microsoft&apos;s own documentation, Forshaw&apos;s Project Zero posts, or the operational literature on Windows privilege escalation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The user is still the weak link.&lt;/strong&gt; Every elevation depends on a human accepting the prompt. The Hello credential gate makes that human&apos;s decision more costly to fake than the classic Yes/No, but the gate does not change the fact that a successful prompt is a successful elevation. The three sub-cases of consent-without-identity-verification from §9 -- unattended-session, habituated-click, pretext click-through -- are cost-raised, not closed. Phishing-the-prompt remains a live attack surface and Microsoft does not classify it as a vulnerability [@forshaw-pz-jan2026]. Out-of-band consent -- a phone-push approval channel, a smartcard tap, a separate hardware key tap -- would close the gap; none of these is the Administrator Protection default.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Loopback authentication.&lt;/strong&gt; The structural property that Windows services authenticate to themselves over the local network stack is independent of the SMAA model. SMB to &lt;code&gt;localhost&lt;/code&gt;, Kerberos against the local machine account, NTLM challenge-response between processes on the same box -- these protocols predate UAC and are not changed by Administrator Protection. Forshaw&apos;s broader 2022 Kerberos research [@forshaw-2022-rbcd] catalogues the class. The &lt;a href=&quot;https://paragmali.com/blog/ntlmless-the-death-of-ntlm-in-windows/&quot; rel=&quot;noopener&quot;&gt;NTLMless article&lt;/a&gt; in this series covers SMB signing, Extended Protection for Authentication (EPA), and channel binding mitigations that defenders should pair with Administrator Protection to close the loopback path.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Service-account &lt;code&gt;SeImpersonatePrivilege&lt;/code&gt;.&lt;/strong&gt; The Potato lineage of attacks (cataloged in the &lt;a href=&quot;https://paragmali.com/blog/windows-access-control-25-years-of-attacks/&quot; rel=&quot;noopener&quot;&gt;Access Control article&lt;/a&gt; in this series) runs in service accounts (&lt;code&gt;IIS_IUSRS&lt;/code&gt;, &lt;code&gt;LOCAL SERVICE&lt;/code&gt;, &lt;code&gt;NETWORK SERVICE&lt;/code&gt;), not in interactive admin sessions. Administrator Protection scopes itself to interactive admin elevation; the Potato class is structurally out of scope.&lt;/p&gt;

Service-account Potato attacks run inside `IIS_IUSRS`, `LOCAL SERVICE`, and `NETWORK SERVICE` rather than in interactive admin sessions. The attacker has compromised a service that holds `SeImpersonatePrivilege`, then uses one of several primitives (the SSPI / NEGOEX dance, the EFS RPC interface, a printer-spooler endpoint) to coerce a higher-privileged service into authenticating against the attacker&apos;s local socket, and impersonates the resulting token. Administrator Protection&apos;s promise is around the *interactive elevation* path -- the flow from a logged-in user clicking an installer to an elevated process running. Potato is a separate problem class with its own mitigations: removing `SeImpersonatePrivilege` from service accounts that don&apos;t need it, applying EPA, and patching the named primitives one by one.
&lt;p&gt;&lt;strong&gt;Driver loading once inside an SMAA elevation.&lt;/strong&gt; Admin equals kernel applies once a process is running inside the SMAA. Vulnerable-driver loading, kernel-mode code execution, and rootkit installation fall under the §11 &quot;admin equals kernel&quot; ceiling -- WHQL signing, the Vulnerable Driver Blocklist, App Control for Business, and HVCI remain the four-mechanism mitigation surface, with the App Identity article in this series covering the App Control mechanism. Administrator Protection does not change the relationship between admin and kernel; it changes the relationship between standard user and admin.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Hello credential phishing surface.&lt;/strong&gt; The prompt now phishes a &lt;em&gt;real credential&lt;/em&gt; rather than a click-through approval. A malicious application that successfully argues its case to the user gets a Hello gesture against the primary user&apos;s PIN or biometric. The credential remains hardware-rooted; ESS-engaged biometrics never leave the TPM or Pluton enclave; the malware does not learn the PIN. But the malware does get the elevation. The Windows Hello article in this series covers FIDO2 / ESS / PIN architecture hardening. Defender-side mitigation is the ETW 15031 / 15032 detection rule set on unexpected application paths [@ms-admin-protection].&lt;/p&gt;
&lt;p&gt;The boundary is real, the audit trail is new, and the five-class residual surface is the next decade of work. The next section turns to operator-side practicalities.&lt;/p&gt;
&lt;h2&gt;16. Practical guide&lt;/h2&gt;
&lt;p&gt;Six tips, each tied to one Microsoft Learn or Windows Developer Blog primary source. Remember that, as of December 2025, Microsoft has reverted the rollout and the feature is currently disabled on stable Windows; the guidance below applies once Microsoft re-enables it. The Spoiler below contains the verbatim commands.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Enable.&lt;/strong&gt; Set &lt;code&gt;TypeOfAdminApprovalMode = 2&lt;/code&gt; via Group Policy (&quot;User Account Control: Configure type of Admin Approval Mode&quot; -&amp;gt; &quot;Admin Approval Mode with Administrator Protection&quot;) or via the Intune Settings Catalog OMA-URI. A reboot is required for the new policy to take effect [@ms-admin-protection, @ms-kb5067036].&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Verify.&lt;/strong&gt; Run &lt;code&gt;whoami&lt;/code&gt; in an elevated console. The profile name shows &lt;code&gt;ADMIN_&amp;lt;random&amp;gt;&lt;/code&gt;. Run &lt;code&gt;whoami /priv&lt;/code&gt; to confirm the SMAA has the Administrators group enabled [@ms-admin-protection, @call4cloud-osint].&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Capture.&lt;/strong&gt; Start the ETW trace with the documented &lt;code&gt;logman&lt;/code&gt; invocation; filter for Event IDs 15031 and 15032 [@ms-admin-protection]. The provider GUID is stable across builds.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Do not enable&lt;/strong&gt; on devices that require Hyper-V or WSL. Re-evaluate when Microsoft re-enables the broad rollout [@ms-admin-protection, @forshaw-pz-jan2026].&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;For application developers&lt;/strong&gt;, follow the Windows Developer Blog (May 19, 2025) guidance [@ms-developer-blog-2025]: install per-user packages unelevated; use &lt;code&gt;%ProgramFiles%&lt;/code&gt; (and accept the elevated install path); avoid context switching during install; avoid sharing files between elevated and unelevated profiles; remove auto-elevation dependencies. The auto-elevation manifest attribute is no longer honoured under Administrator Protection, so any installer that relied on silent elevation needs to be reworked.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;For IT admins&lt;/strong&gt; on already-enabled devices broken by an elevated install: disable Administrator Protection temporarily, reinstall the application unelevated, then re-enable [@ms-developer-blog-2025].&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Enable via Group Policy registry value (administrator console, persists across reboots):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-powershell&quot;&gt;# Set TypeOfAdminApprovalMode to 2 (Admin Approval Mode with Administrator Protection)
reg add &quot;HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System&quot; /v TypeOfAdminApprovalMode /t REG_DWORD /d 2 /f
# Reboot required:
shutdown /r /t 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Capture the elevation event trace:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-cmd&quot;&gt;logman start AdminProtectionTrace -p {93c05d69-51a3-485e-877f-1806a8731346} -ets
:: After some elevations:
logman stop AdminProtectionTrace -ets
:: Process the .etl with PerfView, Message Analyzer, or:
wevtutil qe Microsoft-Windows-LUA/Operational /q:&quot;*[System[(EventID=15031 or EventID=15032)]]&quot; /f:text
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Verify the SMAA presence after enablement:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-powershell&quot;&gt;Get-LocalUser | Where-Object Name -like &apos;ADMIN_*&apos;
# After an elevation, run from the elevated console:
whoami
# Expect: WIN11-PC\ADMIN_&amp;lt;random16hex&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The single most common mistake in response to an Administrator Protection compatibility problem is to disable UAC globally by setting &lt;code&gt;EnableLUA = 0&lt;/code&gt;. This returns the device to the Windows XP single-token model, removes Mandatory Integrity Control enforcement on application processes, and effectively defeats every layer of UAC and Administrator Protection together. It is universally discouraged. The correct fix is per-application, via manifest, or per-device, via the documented Administrator Protection compatibility list.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Six tips, one boundary, one operational checklist. The next section answers the most common misconceptions.&lt;/p&gt;
&lt;h2&gt;17. Frequently asked questions&lt;/h2&gt;

No. Administrator Protection runs in `appinfo.dll` inside the Application Information service, which runs in `svchost.exe` in VTL0 (the normal Windows kernel context). The SMAA itself is a normal SAM-database account, not a Virtual Secure Mode trustlet. The cross-process protections of Virtualization-Based Security apply to LSASS Credential Guard and a handful of other VTL1 services; the elevation pipeline is not one of them. The Secure Kernel article in this series treats VTL0 / VTL1 separation in detail.

Partially. Administrator Protection replaces Admin Approval Mode UAC when `TypeOfAdminApprovalMode = 2`. The credential-prompt path (the over-the-shoulder elevation that asks a standard user to enter an administrator&apos;s credentials) and classic Admin Approval Mode (`TypeOfAdminApprovalMode = 1`) coexist with Administrator Protection across different configurations [@ms-admin-protection]. On a device with Administrator Protection enabled, only the interactive admin&apos;s elevation path goes through the SMAA; the standard-user-asking-for-admin-credentials path is unchanged.

No. There is absolutely an admin token; it lives in a different account, in a different logon session, for a bounded lifetime. The marketing language describes lifetime and isolation, not nonexistence [@ms-developer-blog-2025, @bleepingcomputer-2024]. The SMAA&apos;s token persists for the lifetime of the elevated process; when the process exits, the token handle is released and the logon session is reaped. Between elevations, no SMAA token exists in memory.

No. Malware can still elevate if the user accepts the Hello prompt. The boundary Administrator Protection creates is between *silent* elevation and *consented* elevation, not between any elevation and none. Microsoft&apos;s design position is explicit: &quot;I expect that malware will still be able to get administrator privileges even if that&apos;s just by forcing a user to accept the elevation prompt&quot; [@forshaw-pz-jan2026]. The three sub-cases of consent-without-identity-verification from §9 are cost-raised, not eliminated. What changes is that the elevation must be visible. Defenders gain the ETW 15031 audit trail as a result.

No. EPM uses a virtual elevated account on a per-request basis with cloud-side policy, and the virtual account is *not* a member of the local Administrators group [@ms-epm-overview]. Administrator Protection uses a persistent local SMAA per admin user, with on-box `appinfo.dll` policy, and the SMAA *is* a member of the local Administrators group [@call4cloud-osint]. EPM is centrally policy-driven and works on standard-user devices; Administrator Protection is per-device architecture and applies only to interactive admin users. The two can coexist on the same device.

No. Per Microsoft Learn, remote logon, roaming profiles, and backup admins are out of scope [@ms-admin-protection]. A domain administrator who logs into a workstation interactively will not see the SMAA path. Microsoft has stated that domain scenarios may be added in future iterations; the current GA-target form is local-machine-only, interactive-admin-only.

No. Mimikatz inside the elevated SMAA session still has `SeDebugPrivilege` and can call `OpenProcess` on `lsass.exe` to dump LSASS unless LSA Protection (Run As Protected Process Light) and Credential Guard are also enabled. Administrator Protection protects the *elevation path*; it does not protect the *resulting privileged session*. To protect the privileged session, pair Administrator Protection with LSA Protection (`RunAsPPL=1`), Credential Guard, App Control for Business, and HVCI. The Secure Kernel article in this series covers the LSA Protection mechanism.
&lt;p&gt;The misconceptions are cleared. The next section returns to the opening hook with the new vocabulary the article has built.&lt;/p&gt;
&lt;h2&gt;18. The user-elevation companion to Credential Guard&lt;/h2&gt;
&lt;p&gt;Return to the two &lt;code&gt;whoami /all&lt;/code&gt; outputs from §1, this time with the vocabulary the article has built.&lt;/p&gt;
&lt;p&gt;The first output shows the primary user under classic UAC. One SID, one profile, one &lt;code&gt;HKCU&lt;/code&gt;, one logon-session LUID; the elevated console is the same user as the unelevated console, distinguished only by the integrity level on the token.&lt;/p&gt;
&lt;p&gt;The second output shows the same login under Administrator Protection. A different user name -- &lt;code&gt;ADMIN_&amp;lt;random&amp;gt;&lt;/code&gt; -- with a different SID linked to the primary admin via &lt;code&gt;ShadowAccountForwardLinkSid&lt;/code&gt; and &lt;code&gt;ShadowAccountBackLinkSid&lt;/code&gt;. A different profile under &lt;code&gt;C:\Users\ADMIN_&amp;lt;random&amp;gt;\&lt;/code&gt;. A different &lt;code&gt;NTUSER.DAT&lt;/code&gt; mapped as &lt;code&gt;HKCU&lt;/code&gt;. A fresh authentication-ID LUID minted by LSASS through the credential-less logon path described in §7, on the strength of &lt;code&gt;appinfo.dll&lt;/code&gt;&apos;s trusted request and a Hello gesture the primary user just performed. An ETW Event 15031 in the &lt;code&gt;Microsoft-Windows-LUA&lt;/code&gt; provider, freshly emitted, recording the elevation as approved, the application path, and the authentication method.&lt;/p&gt;
&lt;p&gt;The thesis lands. The elevation path is now itself a security boundary, with bulletin-grade fixes when it fails. Administrator Protection is the user-elevation companion to Credential Guard. Where Credential Guard isolated LSA secrets from admin-equals-kernel &lt;em&gt;inside&lt;/em&gt; the machine -- the &lt;a href=&quot;https://paragmali.com/blog/the-windows-secure-kernel/&quot; rel=&quot;noopener&quot;&gt;Secure Kernel article&lt;/a&gt; in this series covers the VBS-rooted isolation in detail -- Administrator Protection isolates the elevation path &lt;em&gt;from&lt;/em&gt; the standard-user session. The two answer the two halves of the question the foundational Access Control article in this series left open: if admin equals kernel and tokens are bearer credentials, what is left to harden? The answer is the path that gets you there (Administrator Protection) and the data that is there once you arrive (Credential Guard).&lt;/p&gt;
&lt;p&gt;The December 2025 revert is the first iteration&apos;s learning round. The architecture is the right one. The application base catches up next. Forshaw&apos;s framing in February 2026 -- that Microsoft might have shipped this as a configurable mode rather than replacing admin approval completely -- is a reasonable critique, and the re-enablement is likely to address it. Until then, the operational reality on most stable Windows devices is the classic split-token model, with all the bypass canon it implies, and the SMAA design remains an Insider-Preview-and-policy-opted-in posture.&lt;/p&gt;
&lt;p&gt;What stays unchanged is the structural insight. The mechanism Microsoft used to make the elevation path a boundary is not novel; multi-user accounts have shipped in Windows NT since 1993. What changed is the &lt;em&gt;classification&lt;/em&gt;. Microsoft accepted, after twenty years of evidence, that the elevation pipeline needed to be a security boundary, and accepted with it the engineering cost: separate accounts, separate profiles, separate logon sessions, removal of auto-elevation, a credential gate instead of a click-through, an audit-trail ETW provider, and a willingness to ship bulletin-grade fixes for every Forshaw finding. The classification was the engineering decision. Everything else followed.&lt;/p&gt;
&lt;p&gt;This is what it took, in mechanism and in time, to make the elevation path real [@forshaw-pz-jan2026].&lt;/p&gt;
&lt;p&gt;&amp;lt;StudyGuide slug=&quot;adminless-administrator-protection-in-windows&quot; keyTerms={[
  { term: &quot;Split-token model&quot;, definition: &quot;The Vista UAC mechanism that issues two access tokens at logon for a member of the local Administrators group: a filtered standard-user token and a linked full administrator token referenced via the TokenLinkedToken field.&quot; },
  { term: &quot;System Managed Administrator Account (SMAA)&quot;, definition: &quot;The hidden local user account that Windows creates per primary administrator when TypeOfAdminApprovalMode = 2, used to host elevated processes in a fresh logon session.&quot; },
  { term: &quot;ShadowAccountForwardLinkSid / ShadowAccountBackLinkSid&quot;, definition: &quot;The paired SAM attributes that encode the trust relationship between a primary admin user and its SMAA.&quot; },
  { term: &quot;TypeOfAdminApprovalMode&quot;, definition: &quot;The registry value selecting the elevation policy: 0 disables UAC; 1 selects classic Admin Approval Mode; 2 selects Admin Approval Mode with Administrator Protection.&quot; },
  { term: &quot;Auto-elevation&quot;, definition: &quot;The Windows 7 mechanism by which selected Microsoft-signed binaries elevated without showing a consent prompt; removed under Administrator Protection.&quot; },
  { term: &quot;COM Elevation Moniker&quot;, definition: &quot;The COM activation syntax that lets an unelevated caller request an elevated instance of a COM server class; the structural primitive of many UACMe bypasses.&quot; },
  { term: &quot;Credential-less LSA logon&quot;, definition: &quot;The mechanism by which LSA mints a primary access token for the SMAA without verifying any SMAA credential, on the strength of appinfo.dll&apos;s trusted request and the primary user&apos;s Hello result.&quot; },
  { term: &quot;Consent-without-identity-verification&quot;, definition: &quot;The primitive by which the legacy UAC consent dialog accepted a click on the secure desktop as sufficient evidence of consent. Administrator Protection&apos;s credential gate cost-raises three sub-cases (unattended-session, habituated-click, pretext click-through) without eliminating any.&quot; },
  { term: &quot;UI Access flag&quot;, definition: &quot;The token flag (TOKEN_UIACCESS) that allows a process to interact with windows of higher integrity, bypassing UIPI; the basis of five of Forshaw&apos;s nine pre-GA Administrator Protection bypasses.&quot; },
  { term: &quot;ETW provider Microsoft-Windows-LUA&quot;, definition: &quot;The Event Tracing for Windows provider, GUID {93c05d69-51a3-485e-877f-1806a8731346}, that surfaces Administrator Protection elevation events. Event 15031 = approved; Event 15032 = denied/failed.&quot; },
  { term: &quot;Security boundary (MSRC servicing criteria)&quot;, definition: &quot;A logical separation between code or data of different trust levels accompanied by a Microsoft commitment to issue a security update when an unauthorised crossing is found. Administrator Protection is the first elevation mechanism to be classified as a security boundary.&quot; }
]} questions={[
  { q: &quot;What four shared resources of the Vista split-token model do the four Administrator Protection fixes attack?&quot;, a: &quot;Same SID across both tokens; same %USERPROFILE%; same HKCU hive; same logon-session LUID.&quot; },
  { q: &quot;Why is the auto-elevation whitelist &apos;the bypass&apos;, in Davidson&apos;s framing?&quot;, a: &quot;The day Microsoft shipped a class of binaries that elevated silently based on signing and path, the entire UAC-bypass problem reduced to making one of those binaries do something the attacker wanted it to do. The whitelist itself was the structural mistake.&quot; },
  { q: &quot;What does the SAM forward/back linkage do at elevation time?&quot;, a: &quot;appinfo.dll&apos;s RAiLaunchAdminProcess reads the calling user&apos;s ShadowAccountForwardLinkSid, walks to the SMAA, and validates the matching ShadowAccountBackLinkSid. Without both attributes pointing at each other, the elevation is refused.&quot; },
  { q: &quot;What is the credential-less LSA logon at step 6 of the Administrator Protection pipeline, and why is the SMAA mintable without a credential?&quot;, a: &quot;After a positive Hello result on the primary user&apos;s credential, appinfo.dll asks the kernel to ask LSA to authenticate a new instance of the shadow administrator. LSA fulfils the request because the requester (appinfo.dll as SYSTEM) is trusted -- the same trust-the-requester pattern SCM uses to obtain service-account tokens -- and the SMAA has no human credential to verify in any case.&quot; },
  { q: &quot;Which class of Forshaw&apos;s nine pre-GA bypasses is uniquely caused by Administrator Protection itself rather than inherited from UAC?&quot;, a: &quot;The lazy DOS device directory hijack. The &apos;fresh logon session per elevation&apos; design property means the per-session DOS device directory is created lazily on first reference; an identification-level impersonation of the SMAA&apos;s linked token could trick the kernel into creating it with the attacker&apos;s owner SID.&quot; },
  { q: &quot;Why did Microsoft revert Administrator Protection on December 1, 2025?&quot;, a: &quot;A WebView2 application-compatibility regression: installers that wrote per-user state into the elevated SMAA&apos;s profile broke under unelevated callers running as the primary user. Forshaw confirmed the revert was unrelated to security findings.&quot; }
]} /&amp;gt;&lt;/p&gt;
</content:encoded><category>windows</category><category>security</category><category>uac</category><category>administrator-protection</category><category>privilege-escalation</category><category>windows-hello</category><category>project-zero</category><author>noreply@paragmali.com (Parag Mali)</author></item></channel></rss>