1. Overview

  • Unpatched Binary ID: ci_unpatched.dll
  • Patched Binary ID: ci_patched.dll
  • Overall Similarity Score: 0.95
  • Diff Statistics:
  • Matched Functions: 380
  • Changed Functions: 88
  • Identical Functions: 292
  • Unmatched Functions: 0 (both directions)

Verdict: The primary change tightens a System Integrity (SI) policy trust check where, on the non-strict path, a policy could be treated as "platform secured" via a single flag bit without the full identity check. The patch also removes one policy identity from a hardcoded list of policy IDs that are required to be Windows-signed (which relaxes, not tightens, the requirement for that identity), adds a feature-gated flag check to the VBS/HVCI (Virtualization-Based Security) policy-failure path, and switches one catalog-hash lookup from bsearch to the bounds-checked bsearch_s. Separately, the patch hardens the EFI Secure Boot signature-database parser (SbpParseSignatureDatabase, reached from SbParseKEK via SbEFIGetVariable): the merged-list allocation size, previously computed with raw shl/add and no overflow check, is now validated with RtlULongLongMult plus carry checks in the newly extracted helper SbpParseSignatureDatabaseFromBuffer before the buffer is allocated and attacker-controlled variable data is copied in (CWE-190 integer-overflow hardening; see Finding 4).


2. Vulnerability Summary

Finding 1: SI Policy "Platform Secured" Trust Check Bypass

  • Severity: Medium
  • Vulnerability Class: Trust Bypass / Improperly Implemented Security Check (CWE-358)
  • Affected Function: SIPolicyIsPolicyPlatformSecured (sub_18006FC88)

Root Cause: SIPolicyIsPolicyPlatformSecured decides whether a loaded System Integrity policy is "platform secured" (return 1) based on a policy-options flag dword at offset +0x710 of the policy structure. In the unpatched build, when the function is called with arg2 = 0 (the non-strict path) and bit 2 (value & 4) is set in that flag dword, it immediately returns 1 (platform secured), skipping the stricter check. The patched build removes this early-return shortcut: on the arg2 = 0 path it now requires bit 0 (value & 1) to be set AND a hardcoded 16-byte policy-identity value at offset +0x6CC/+0x6D4 (0x4C0644C9A244370E / 0x7630566E01F651B5) to match before returning platform-secured. There is no page-hash table or binary search in this function; the check is a policy flag test plus a fixed identity comparison.

The "platform secured" result is a trust gate: one caller honors a policy's PlatformSecureSetting security-policy query only when the owning policy is platform-secured, and another proceeds with image validation once any loaded policy is platform-secured. Removing the bit-2 shortcut therefore narrows which policies are treated as platform-secured. The severity is assessed as Medium rather than High because the end-to-end impact depends on an attacker being able to get a policy loaded and evaluated whose +0x710 flag has bit 2 set while lacking the fixed identity, which cannot be demonstrated from these two binaries alone.

Call Chain: 1. SI policy load / evaluation 2. SIPolicyParsePolicyData and related policy setup 3. SIPolicyIsPolicyPlatformSecured (sub_18006FC88) (platform-secured determination)

Finding 2: Removal of a Policy Identity from the Windows-Signing Mandate List (Relaxation)

  • Severity: Informational (not a security fix; the patched build is the less strict one for this identity)
  • Vulnerability Class: Signing-requirement relaxation of a hardcoded policy-ID list (no unpatched-vulnerable / patched-fixed direction)
  • Affected Function: SIPolicyIsPolicyMustBeWindowsSigned (sub_18006FB74)

Root Cause: SIPolicyIsPolicyMustBeWindowsSigned compares a 16-byte policy identity against a built-in list of hardcoded policy-identity constants and returns 1 if any match. The unpatched build contains one extra entry: identity 0x4C3279F4784C4414 (at offset +0x0) with 0xD1DA542FBF0A5A6 (at offset +0x8, i.e. a1[1]). The patch removes this one entry; all other entries are unchanged in both builds.

The direction of this change is a relaxation, not a tightening. In both builds the sole caller reaches the customized-signed acceptance path (SIPolicyCheckPolicyCustomizedSigned, which allows a non-Windows/third-party signer) only when the policy is not Windows-signed (status 0xC0430005) AND SIPolicyIsPolicyMustBeWindowsSigned returns 0. A policy whose identity is on the list is therefore barred from the customized-signed path and must be Windows-signed. Removing identity 0x4C3279F4784C4414 from the list means the patched build no longer forces that identity to be Windows-signed: it may now be accepted through the customized-signed path. So the unpatched build is the stricter one here; this is a policy-ID list adjustment, not a trust revocation and not a vulnerability being fixed. This is a policy-identity constant compare, not a certificate-chain or signer-hash check.

The separately-changed CiHvciIsVbsPolicyFailure (sub_18006C428) is a distinct HVCI/VBS policy-failure detector (it does not call SIPolicyIsPolicyMustBeWindowsSigned); its patched change is described in Finding 2b below.

Call Chain: 1. SI policy evaluation 2. SIPolicyIsPolicyMustBeWindowsSigned (sub_18006FB74) (built-in policy-identity allowlist compare)

Finding 2b: VBS/HVCI Policy-Failure Gate Tightened

  • Severity: Low
  • Vulnerability Class: Improperly Implemented Security Check (CWE-358)
  • Affected Function: CiHvciIsVbsPolicyFailure (sub_18006C428)

Root Cause: CiHvciIsVbsPolicyFailure walks loaded policies looking for a specific hardcoded policy identity (0x4B5E588BA072029F / 0x87F67DD6AA05F9B7) to decide whether an HVCI/VBS policy failure occurred. The patch adds a feature-gated pre-check: when Feature_CodeIntegrity_TrustedLaunchPolicy__private_IsEnabledDeviceUsageNoInline (sub_180018DF8) returns non-zero, it re-reads the flag dword at offset +0x938 and returns 0 (no failure) unless bit 0x100000 is set and bit 0x200000 is clear. The +0x938 offset is unchanged between builds.

Finding 3: Hardening of the SHA-256 Catalog Hash Binary Search

  • Severity: Low (defensive hardening; no out-of-bounds condition demonstrated in either build)
  • Vulnerability Class: Potential Out-of-Bounds Read / Improper Bounds Handling (CWE-125)
  • Affected Function: I_FindFileOrHeaderHashInLoadedCatalogs (sub_1800D6FEC)

Root Cause: I_FindFileOrHeaderHashInLoadedCatalogs looks up a file/header hash in the sorted hash tables of loaded catalogs. In the unpatched build the SHA-256 branch (a3 == 32780) uses the standard bsearch (element size 0x20, comparator I_HashSearchCompareRoutineSHA256). The patch transitions that call to the bounds-checked variant bsearch_s (with CipFileHashSearchCompareRoutineSHA256, element size 0x20, and a null context argument), which adds runtime parameter validation. The SHA-1 branch (a3 == 32772, element size 0x14) continues to use bsearch in both builds. This is a defensive hardening change; neither build exhibits a demonstrable out-of-bounds read.

Finding 4: Integer-Overflow Hardening of the EFI Secure Boot Signature-Database Parser

  • Severity: Low (defensive integer-overflow hardening on an untrusted parser; a demonstrable 64-bit overflow is not provable from these binaries, see below)
  • Vulnerability Class: Integer Overflow in size computation (CWE-190) guarding an undersized-allocation heap buffer overflow (CWE-787 / CWE-122)
  • Affected Function: SbpParseSignatureDatabase (unpatched @0x18000BDDC) — in the patch the size/allocation logic is split out into the newly added helper SbpParseSignatureDatabaseFromBuffer (@0x18001E1DC), called from the patched SbpParseSignatureDatabase (@0x18000E0FC).

Root Cause: SbpParseSignatureDatabase retrieves an EFI (UEFI) Secure Boot signature-database variable via SbEFIGetVariable (at 0x18000BE21 in the unpatched build) and parses its EFI_SIGNATURE_LIST records to build a merged descriptor array. It is reached from SbParseKEK (@0x18001E16C in the patched build), which parses the Secure Boot KEK/db variable contents — firmware/Secure-Boot configuration data that is exactly the untrusted input this parser exists to validate.

In the unpatched build the allocation size for the merged list is computed with raw shift/add and no overflow validation. After the counting pass, the entry counts in r14/rdi and the raw variable size in r15 are combined as lea rcx,[r14+rdi]; shl rcx,4; add rcx,r15 and passed straight to SbeAlloc (at 0x18000BE54). The attacker-controlled variable data is then copied into that buffer with memmove (at 0x18000BF62). There is no RtlULongLongMult or carry check anywhere in the function; in fact RtlULongLongMult does not appear anywhere in the unpatched binary.

In the patched build every size multiplication that was previously a bare shl is replaced by a checked 64-bit multiply, RtlULongLongMult (multiplier 0x10), whose NTSTATUS result is tested with test eax,eax; js loc_18001E5BC (error path). Each subsequent addition of the sub-region sizes is followed by an explicit carry check (add r10,[rbp+pullResult]; cmp r10,[rbp+pullResult]; jb loc_18001E574, where loc_18001E574 sets STATUS_INTEGER_OVERFLOW = 0xC0000095). Only after all multiplications and additions pass is the buffer allocated with SbeAlloc (at 0x18001E2EC) and the attacker data copied in with memmove (at 0x18001E324).

The change is a genuine, correctly-directed integer-overflow hardening on an untrusted UEFI-variable parsing path (the patched build is the stricter one). It is rated Low rather than higher because the guarded operands are 32-bit entry counts multiplied by 16 and added to a 32-bit variable size; the arithmetic is performed in 64-bit registers and the counts are bounded by the parsed variable size, so a full 64-bit overflow of the allocation size — and therefore the undersized-allocation-plus-memmove heap overflow it would cause — is not demonstrable from these two binaries alone. It is best characterized as defense-in-depth (CWE-190) that forecloses an undersized SbeAlloc followed by an oversized memmove of attacker-controlled EFI-variable data.

Call Chain: 1. Secure Boot variable evaluation 2. SbParseKEK (@0x18001E16C) (parses the KEK/db Secure Boot variable) 3. SbpParseSignatureDatabase (retrieves the variable via SbEFIGetVariable) 4. SbpParseSignatureDatabaseFromBuffer (@0x18001E1DC) (patched-only; overflow-checked size computation before SbeAlloc/memmove)


3. Pseudocode Diff

SIPolicyIsPolicyPlatformSecured (sub_18006FC88) (Platform-Secured Determination)

// UNPATCHED SIPolicyIsPolicyPlatformSecured @ 0x18006FC88:
char SIPolicyIsPolicyPlatformSecured(int64_t a1, char a2) {
    int v2 = *(int32_t*)(a1 + 0x710);   // policy-options flags
    if (a2 != 0) {
        if ((v2 & 0x18) == 0) goto full_check;
        return 1;                        // strict path (preserved in patch)
    }
    if ((v2 & 4) != 0)
        return 1;                        // <--- VULNERABLE: bit 2 alone => platform secured
full_check:
    uint32_t v4 = *(uint32_t*)(a1 + 0x28);
    if (a2 != 0) return 0;
    if ((v2 & 1) == 0) return 0;
    uint64_t v6 = -(int64_t)(v4 < 6) & 0xFFFFFFFFFFFFF944ull;
    if (*(uint64_t*)(v6 + a1 + 0x6CC) != 0x4C0644C9A244370Eull ||
        *(uint64_t*)(v6 + a1 + 0x6D4) != 0x7630566E01F651B5ull)
        return 0;
    return 1;                            // identity match required
}

// PATCHED SIPolicyIsPolicyPlatformSecured @ 0x180074028:
char SIPolicyIsPolicyPlatformSecured(int64_t a1, char a2) {
    int v2 = *(int32_t*)(a1 + 0x710);   // same +0x710 offset in patched
    if (a2 != 0 && (v2 & 0x18) != 0)
        return 1;                        // only the strict (a2!=0) path returns early
    // The (a2==0 && v2&4) shortcut is REMOVED.
    uint32_t v5 = *(uint32_t*)(a1 + 0x28);
    if (a2 != 0) return 0;
    if ((v2 & 1) == 0) return 0;
    uint64_t v7 = -(int64_t)(v5 < 6) & 0xFFFFFFFFFFFFF944ull;
    if (*(uint64_t*)(v7 + a1 + 0x6CC) != 0x4C0644C9A244370Eull ||
        *(uint64_t*)(v7 + a1 + 0x6D4) != 0x7630566E01F651B5ull)
        return 0;
    return 1;
}

SIPolicyIsPolicyMustBeWindowsSigned (sub_18006FB74) (Hardcoded Windows-Signing Mandate List)

// UNPATCHED SIPolicyIsPolicyMustBeWindowsSigned @ 0x18006FB74:
char SIPolicyIsPolicyMustBeWindowsSigned(uint64_t* a1) {
    if (a1[0] == 0x4730CB9F976D12C8 && a1[1] == 0x8E234308605452BE) return 1;
    if (a1[0] == 0x4B5E588BA072029F && a1[1] == 0x87F67DD6AA05F9B7) return 1;

    // This entry is REMOVED in the patch (identity no longer forced Windows-signed):
    if (a1[0] == 0x4C3279F4784C4414 && a1[1] == 0xD1DA542FBF0A5A6)
        return 1;

    // [remaining hardcoded comparisons, unchanged in both builds...]
    return SIPolicyGetSystemPolicyDefinitionByID() != 0;
}

// PATCHED SIPolicyIsPolicyMustBeWindowsSigned @ 0x180073F34:
// The 0x4C3279F4784C4414 / 0xD1DA542FBF0A5A6 entry is entirely absent;
// all other entries are unchanged. Because a "must be Windows-signed" match
// blocks the customized-signed acceptance path in the caller, removing this
// entry RELAXES the requirement for that identity (it may now be accepted
// via customized signing).

4. Assembly Analysis

SIPolicyIsPolicyPlatformSecured (sub_18006FC88) Assembly Analysis

; UNPATCHED ci!SIPolicyIsPolicyPlatformSecured @ 0x18006FC88
; policy pointer in rcx, a2 (strict flag) in dl
mov     eax, [rcx+710h]   ; load policy-options flags
mov     r8, rcx
test    dl, dl            ; a2 == 0 ?
jz      loc_18006FCDD     ; a2==0 -> check bit 2
test    al, 18h           ; a2!=0: bits 3/4
jnz     loc_18006FCE1     ; -> return 1
mov     r9d, [rcx+28h]
; ... full check: (al & 1) plus identity compare vs g_SiPolicyLegacyIDs / qword_18002F258 ...
loc_18006FCDD:
test    al, 4             ; <--- check bit 2
jz      loc_18006FC99     ; if 0, fall into full check
loc_18006FCE1:
mov     al, 1             ; <--- return platform-secured
retn                      ; <--- BYPASS: bit 2 alone marks the policy secured

In the patched build (@ 0x180074028) the flags are still read from [rcx+710h]. The a2==0 branch jumps straight to the full check (test al,18h; jz loc_18007403D); the test al, 4 / mov al,1; retn shortcut is gone, so an a2==0 policy is only "platform secured" when bit 0 is set and the hardcoded identity at +0x6CC/+0x6D4 matches.

SbpParseSignatureDatabase / SbpParseSignatureDatabaseFromBuffer Assembly Analysis (Finding 4)

; UNPATCHED ci!SbpParseSignatureDatabase @ 0x18000BDDC
; ... EFI variable fetched into [rbp+Src], size into [rbp+Size]:
000000018000BE21  call    SbEFIGetVariable
; ... counting pass produces entry counts in r14 / rdi (r15d) ...
; allocation of merged descriptor array + data (NO overflow check):
000000018000BE42  mov     edi, r15d
000000018000BE45  mov     r15d, dword ptr [rbp+Size]
000000018000BE49  lea     rcx, [r14+rdi]       ; count_a + count_b
000000018000BE4D  shl     rcx, 4               ; * 16, raw, unchecked
000000018000BE51  add     rcx, r15             ; + Size, raw, unchecked
000000018000BE54  call    SbeAlloc
; ... later, attacker data copied into the buffer:
000000018000BF62  call    memmove
; PATCHED ci!SbpParseSignatureDatabaseFromBuffer @ 0x18001E1DC
; each *16 is a checked 64-bit multiply; overflow -> error path:
000000018001E25F  mov     ecx, esi             ; ullMultiplicand = count
000000018001E261  mov     edx, 10h             ; ullMultiplier = 16
000000018001E269  call    RtlULongLongMult
000000018001E270  js      loc_18001E5BC        ; overflow -> free + return
000000018001E287  call    RtlULongLongMult     ; second count * 16
000000018001E290  js      loc_18001E5BC
; addition of sub-region sizes with explicit carry check:
000000018001E29A  add     r10, [rbp+pullResult]
000000018001E29E  cmp     r10, [rbp+pullResult]
000000018001E2A2  jb      loc_18001E574        ; carry -> STATUS_INTEGER_OVERFLOW 0xC0000095
000000018001E2B7  call    RtlULongLongMult     ; third count * 16
000000018001E2C0  js      loc_18001E5BC
000000018001E2CA  add     rdx, r10
000000018001E2CD  cmp     rdx, r10
000000018001E2D0  jb      loc_18001E574
000000018001E2D9  lea     rcx, [rdx+r14]       ; + Size
000000018001E2DD  cmp     rcx, rdx
000000018001E2E0  jb      loc_18001E574
000000018001E2EC  call    SbeAlloc             ; allocate only after all checks pass
000000018001E324  call    memmove

The unpatched build has no size-overflow validation on this path (RtlULongLongMult is absent from the entire unpatched binary); the patched build gates every multiplication and addition before allocating and copying.


5. Trigger Conditions

To trigger the primary weakness (SI Policy "Platform Secured" Bypass):

  1. Cause a System Integrity policy to be loaded/evaluated whose policy-options flag dword at offset +0x710 has bit 2 (0x4) set but that does not carry the hardcoded identity value at +0x6CC/+0x6D4.
  2. A code path calls SIPolicyIsPolicyPlatformSecured with arg2 = 0 (the non-strict path).
  3. In the unpatched build the function hits the bit 2 early return and reports the policy as "platform secured" without the identity check.
  4. Observable Effect: The policy is treated as platform-secured (a trusted state) on the strength of a single flag bit. In the patched build the same input requires bit 0 set and the fixed identity match, otherwise it returns not-secured. The failure is purely logical; no BSOD occurs.

6. Exploit Primitive & Development Notes

  • Provided Primitive: SI-policy trust-state bypass. The unpatched logic lets a policy be classified as "platform secured" (a trusted state that downstream code relies on) using only flag bit 2, without the fixed policy-identity match. This is a logic/trust weakness, not a direct memory-corruption or code-execution primitive.
  • Exploitation Requirements:
  • An attacker must reach a state where a loaded SI policy has bit 2 set in the flag dword at +0x710 while lacking the hardcoded identity at +0x6CC/+0x6D4, and where a caller invokes the function with arg2 = 0.
  • Mitigations & Bypasses:
  • VBS / HVCI: In a related change, CiHvciIsVbsPolicyFailure (sub_18006C428) adds a feature-gated check (Feature_CodeIntegrity_TrustedLaunchPolicy__private_IsEnabledDeviceUsageNoInline, sub_180018DF8) that tightens the HVCI/VBS policy-failure path via the flag bits at +0x938.
  • KASLR / SMEP / SMAP: Not directly applicable, as this is a validation/trust-logic change rather than a memory-corruption chain.

7. Debugger PoC Playbook

For a researcher with a kernel debugger (WinDbg / KD) attached to the unpatched binary:

Breakpoints

Run the following commands to intercept the vulnerable logic:

bp ci!SIPolicyIsPolicyPlatformSecured
bp ci!SIPolicyIsPolicyPlatformSecured+0x55  "Location of the 'test al, 4' shortcut (loc_18006FCDD)"
bp ci!SIPolicyIsPolicyMustBeWindowsSigned   "To monitor the hardcoded policy-identity allowlist"

What to Inspect

  • At ci!SIPolicyIsPolicyPlatformSecured:
  • rcx: Pointer to the SI policy structure.
  • dl (rdx): The arg2 strict flag. The shortcut requires dl == 0.
  • [rcx+0x710]: Inspect the policy-options flags. Use dd rcx+0x710 L1. Bit 2 (0x4) must be set.
  • At the loc_18006FCDD shortcut:
  • Single-step (t) through test al, 4. If it sets al = 1 and returns without reaching the identity compare at +0x6CC/+0x6D4, the shortcut is confirmed.

Trigger Setup

  1. Boot Windows normally.
  2. Arrange for an SI policy to be loaded/evaluated so that SIPolicyIsPolicyPlatformSecured is invoked with arg2 = 0.
  3. Trace into the function, then artificially set [rcx+0x710] |= 4 in the debugger to observe the immediate "platform secured" return in the unpatched build.

Expected Observation

After setting bit 2, the unpatched build sets al = 1 and returns immediately, skipping the identity compare. The patched build falls through to require bit 0 and the fixed identity at +0x6CC/+0x6D4, returning 0 when those do not hold.


8. Changed Functions — Full Triage

Function Name Similarity Change Type Note on Change
SIPolicyIsPolicyPlatformSecured (sub_18006FC88) 0.50 Security Removed early-return "platform secured" shortcut for !arg2 && result & 4.
SIPolicyIsPolicyMustBeWindowsSigned (sub_18006FB74) 0.40 Relaxation Removed one entry (0x4C3279F4784C4414 / 0xD1DA542FBF0A5A6) from the Windows-signing mandate list; that identity is no longer forced to be Windows-signed (patched is less strict).
CiHvciIsVbsPolicyFailure (sub_18006C428) 0.45 Security Added feature-gated (Feature_CodeIntegrity_TrustedLaunchPolicy..., sub_180018DF8) check on flag bits at +0x938 in the HVCI/VBS policy-failure path.
I_FindFileOrHeaderHashInLoadedCatalogs (sub_1800D6FEC) 0.60 Security Swapped the SHA-256 catalog-hash bsearch to the secure bsearch_s variant.
SbpParseSignatureDatabase (unpatched @0x18000BDDC) / SbpParseSignatureDatabaseFromBuffer (patched-only @0x18001E1DC) 0.35 Security EFI Secure Boot signature-database parser: patched replaces raw shl-based allocation-size math with checked RtlULongLongMult + carry checks before SbeAlloc/memmove (CWE-190 integer-overflow hardening).
wil_details_FeatureStateCache_ReevaluateCachedFeatureEnabledState (sub_180018FC8) 0.65 Behavioral WIL feature-state cache: patched adds | 0x40000 to the cached feature-state value.
SymCryptFdefDecideModulusType (sub_18000E878) 0.60 Behavioral SymCrypt library math routine; patched adds (v & 0xC000) == 0 guard on a CPU-feature path.
I_ParseCatalogAndMapHashes (sub_1800882F4) 0.35 Behavioral Purely structural; inlined I_AllocateCatalogParseBuffers (sub_1800884A0) (pool allocator for 0xed0-byte struct).
CiQueryInformation (sub_1800D50A0) 0.70 Behavioral Gated a flag on global configuration bit (data_180045e70 & 0x400000).
SIPolicyParsePolicyData (sub_18006E09C) 0.55 Behavioral Updated policy structure offsets (+0xa80 to +0xaa0); added VBS checks.
CipValidateFileHash (sub_1800DB310) 0.50 Behavioral Struct offset shifts and VBS gating.
CiUnpackPolicy (sub_1800AD8EC) 0.60 Behavioral Both builds call memmove; the referenced symbol difference is only an address shift, not a memcpy-to-memmove switch.
CipMinCryptToAuthRoot2 (sub_180054BC4) 0.50 Behavioral Refactored policy verification logic for HVCI compatibility.

9. Unmatched Functions

One function was added in the patched build: SbpParseSignatureDatabaseFromBuffer (@0x18001E1DC). The patch extracted the EFI signature-database parsing/allocation logic (previously inline in SbpParseSignatureDatabase) into this new helper and added the integer-overflow checks described in Finding 4. No functions were removed. All other modifications occurred inline within existing functions.


10. Confidence & Caveats

  • Confidence Level: High for the diff facts, which are verified directly against both binaries. The decompilation and assembly confirm the bit 2 early-return being removed from SIPolicyIsPolicyPlatformSecured (CWE-358) and the single entry 0x4C3279F4784C4414 / 0xD1DA542FBF0A5A6 being dropped from SIPolicyIsPolicyMustBeWindowsSigned. The direction of the second change was re-checked against its caller and is a relaxation of a Windows-signing mandate, not a trust revocation. The end-to-end exploit impact of Finding 1 is less certain (see below), which is why it is rated Medium rather than High.
  • Assumptions:
  • The exact conditions that set bit 2 (value & 4) at offset +0x710 of the SI policy structure are not visible in these two functions and are inferred to originate in policy parsing/setup. A researcher must trace policy initialization to find what sets this bit and whether it is attacker-influenceable.
  • Verification Needed: The two callers of SIPolicyIsPolicyPlatformSecured were located in this binary: one honors a policy's PlatformSecureSetting security-policy query only for platform-secured policies, and one proceeds with image validation once a loaded policy is platform-secured. A dynamic PoC would still be needed to show that an attacker-loadable policy can carry +0x710 bit 2 set without the fixed identity and thereby gain a meaningful trust elevation.