1. Overview

Field Value
Unpatched binary mup_unpatched.sys
Patched binary mup_patched.sys
Overall similarity 0.9862 (very high)
Matched functions 361
Changed functions 5 (plus relocation-only churn)
Identical functions 356
Unmatched (unpatched) 0
Unmatched (patched) 2 added (both WIL helpers)

Verdict: There is no security-relevant change between the two builds. The functions that actually changed are all part of the statically-linked Windows Implementation Library (WIL) feature-staging runtime — wil_details_GetCurrentFeatureEnabledState, wil_details_FeatureStateCache_ReevaluateCachedFeatureEnabledState, and wil_details_EvaluateFeatureDependencies_ReevaluateCachedFeatureEnabledState. The patch is a WIL library version bump that adds feature-dependency evaluation (a new helper wil_details_AreDependenciesEnabled) and a new feature-state cache marker bit (0x40000). None of these routines are the Multiple UNC Provider network path. Every real Mup* function is byte-for-byte identical between the two builds apart from jump-target relocation (caused by the WIL functions growing) and one benign compiler refactor of pointer arithmetic in MupCallSurrogatePrePost. The 0xc00 and 0x40000 bit values are WIL feature-state cache encodings, not "Hardened UNC Paths" mutual-authentication / message-integrity flags.

The remainder of this report documents the changed functions accurately, shows why the WIL-encoding bits are not security policy flags, and records the independent full-diff triage that confirms no omitted fix.


2. Changed-Function Analysis

Finding 1 — wil_details_GetCurrentFeatureEnabledState (WIL feature state, not UNC flags)

Field Value
Severity None (informational)
Change class WIL feature-staging library churn
Affected function wil_details_GetCurrentFeatureEnabledState (unpatched 0x1400032CC, patched 0x140003384)
Reachability WIL internal; called from wil_details_FeatureStateCache_ReevaluateCachedFeatureEnabledState and wil_details_IsEnabledFallback, not from an IRP dispatch path

What this function is:

wil_details_GetCurrentFeatureEnabledState reads a WIL feature descriptor and computes the current enabled state for that feature. Near the top it calls wil_RtlStagingConfig_QueryFeatureState (0x1400113C0) to read the staged configuration, then builds a WIL state word out of the query result. The bytes it reads at descriptor offsets +0x1c+0x1f and the list pointer at +0x20 are WIL feature-descriptor fields (feature kind, change-time flags, and the feature-dependency list), not UNC provider capability bytes.

What actually changed:

The patched build adds WIL feature-dependency evaluation. After computing the state word (ebx), the patched code does:

0x14000342c  mov  edx, 0C00h        ; two WIL state bits
0x140003435  and  eax, edx
0x140003437  cmp  eax, edx          ; both bits set?
0x140003439  jnz  ...
0x140003450  mov  rcx, rbp
0x140003453  call wil_details_AreDependenciesEnabled   ; NEW WIL helper
0x140003469  btr  eax, 0Ah          ; clear WIL state bit 0x400 if deps not enabled

wil_details_AreDependenciesEnabled (0x140002CA8) is a newly added WIL helper that walks the feature's dependency list (the +0x20 pointer) and returns whether the dependencies are currently enabled. When they are not, WIL clears the 0x400 state bit. This is standard WIL feature-dependency gating introduced by a newer WIL revision. It is not a "provider capability" check and it has no bearing on UNC authentication.

The 0x400 / 0x800 masks are produced from the two 32-bit halves of the wil_RtlStagingConfig_QueryFeatureState output via the neg/sbb/and idiom; they encode the queried WIL feature state, not "mutual authentication required" / "message integrity required."


Finding 2 — wil_details_EvaluateFeatureDependencies_ReevaluateCachedFeatureEnabledState

Field Value
Severity None (informational)
Change class WIL feature-staging library churn
Affected function wil_details_EvaluateFeatureDependencies_ReevaluateCachedFeatureEnabledState (0x140012D90, same address in both builds)
Reachability WIL internal; reached from wil_details_EvaluateFeatureDependencies (0x140012C9C) and wil_details_EvaluateFeatureDependencies_GetCachedFeatureEnabledState (0x140012D54)

What this function is:

This is the dependency-aware counterpart to Finding 1. It re-evaluates a cached WIL feature-enabled state and atomically writes the recomputed state word back into the WIL feature cache via lock cmpxchg. The list it walks at arg+0x20 is the WIL feature-dependency list; the byte checks at +0x1d/+0x1e distinguish dependency-descriptor kinds.

What actually changed:

The patched build adds the same WIL dependency gate as Finding 1: it masks the state word with 0xc00, and when both bits are set it treats the result of the dependency check as a condition to clear WIL state bit 0x400 (btr edx, 0Ah) before the atomic write. This mirrors the wil_details_AreDependenciesEnabled behavior added to GetCurrentFeatureEnabledState. The btr ecx, 9 that clears bit 0x200 is present in both builds and is unrelated to the change. This is WIL cache-encoding churn, not a security fix.


Finding 3 — wil_details_FeatureStateCache_ReevaluateCachedFeatureEnabledState

Field Value
Severity None (informational)
Change class WIL feature-staging library churn
Affected function wil_details_FeatureStateCache_ReevaluateCachedFeatureEnabledState (unpatched 0x14000317C, patched 0x14000321C)

What actually changed:

This function recomputes a feature's cached state and commits it with lock cmpxchg. The patched build adds a new WIL cache-marker bit: bts eax, 12h sets bit 0x40000 in the value written to the cache. The surrounding state-encoding masks (0x9C1, 0xFFFFF63E, 0x400, and the btr ...,0Ah clear) already exist in the unpatched build; the patch only adds the 0x40000 marker and reshuffles register allocation (adds r12, moves rbpr14/r15). Bit 0x40000 is a WIL feature-state cache encoding flag; nothing here touches UNC providers or authentication.


3. Why the changed bits are not security policy flags

The report's original thesis rested on reading 0x400/0x800/0x40000 as "mutual authentication required," "message integrity required," and an "enforcement-tracking flag." That reading is not supported by the binaries:

  • The three changed routines are named, in both .asm listings, wil_details_GetCurrentFeatureEnabledState, wil_details_FeatureStateCache_ReevaluateCachedFeatureEnabledState, and wil_details_EvaluateFeatureDependencies_ReevaluateCachedFeatureEnabledState. These are Windows Implementation Library feature-staging routines.
  • The 0x400/0x800 masks are derived from the two halves of wil_RtlStagingConfig_QueryFeatureState's output — a WIL staged-configuration query — not from any registry-backed Hardened UNC Paths policy word.
  • The "new provider-validation helper" is wil_details_AreDependenciesEnabled, a WIL feature-dependency evaluator, and the +0x20 list it walks is the feature-dependency list.
  • Bit 0x40000 is set by bts ...,12h inside a WIL state-cache commit and is a cache encoding marker.

There is no code path in either build that maps these bits to SMB/UNC mutual authentication, message integrity, or provider enforcement.


4. Pseudocode Diff

wil_details_GetCurrentFeatureEnabledState

// UNPATCHED (0x1400032CC): compute WIL state word, gate list walk on bit 6 (0x40)
int32_t merged = base | flags;              // 0x14000336b: or ecx, edx
int32_t bit6   = (merged >> 6) & 1;         // 0x14000336f: shr eax,6; and eax,1
int32_t state  = bit6 | merged;
// walk feature-descriptor list at [desc+0x20] when bit6 set

// PATCHED (0x140003384): add WIL feature-dependency gate
int32_t merged = base | flags;              // 0x14000342a: or ebx, ecx
if ((merged & 0xc00) == 0xc00) {            // 0x14000342c..0x140003437
    int32_t deps = (desc[0x20] == 0) ? 1
                 : wil_details_AreDependenciesEnabled(desc); // 0x140003453
    if (!deps)
        state = merged & ~0x400;            // 0x140003469: btr eax,0Ah
}

wil_details_EvaluateFeatureDependencies_ReevaluateCachedFeatureEnabledState

// UNPATCHED (0x140012D90): atomic commit, clears WIL bit 0x200 only
new = (old & ~1) | dep_bit;
new &= ~0x200;                              // 0x140012e2e: btr ecx,9  (both builds)
lock cmpxchg [cache], new;

// PATCHED: add WIL dependency gate before the same commit
bool both = (arg2 & 0xc00) == 0xc00;
new = (old & ~1) | dep_bit;
if (both && !dep_ok) new &= ~0x400;         // 0x140012e56: btr edx,0Ah
new &= ~0x200;                              // btr ecx,9 (unchanged)
lock cmpxchg [cache], new;

wil_details_FeatureStateCache_ReevaluateCachedFeatureEnabledState

// UNPATCHED (0x14000317C): commit WIL state without 0x40000 marker
// PATCHED  (0x14000321C): eax |= 0x40000  (bts eax,12h) before lock cmpxchg

5. Assembly Analysis

wil_details_GetCurrentFeatureEnabledState — unpatched (0x1400032CC)

00000001400032CC  mov     [rsp+arg_10], rbx
00000001400032D2  sub     rsp, 40h
00000001400032D6  mov     al, [rcx+1Ch]              ; WIL feature-descriptor kind
00000001400032F8  mov     edx, [rcx+18h]             ; WIL descriptor change-time field
000000014000330C  call    wil_RtlStagingConfig_QueryFeatureState
0000000140003326  and     edx, 400h                  ; WIL state bit from query hi/lo halves
0000000140003331  and     r8d, 800h                  ; WIL state bit
0000000140003338  or      r8d, edx
000000014000336B  or      ecx, edx                   ; merge WIL state word
000000014000336F  shr     eax, 6                     ; gate list walk on bit 6
000000014000337F  jz      loc_14000340D
0000000140003385  mov     rdi, [rdi+20h]             ; WIL feature-dependency list
00000001400033CD  call    wil_details_FeatureStateCache_ReevaluateCachedFeatureEnabledState
000000014000341C  retn

wil_details_GetCurrentFeatureEnabledState — patched (0x140003384), new dependency gate

000000014000342A  or      ebx, ecx                   ; merge WIL state word
000000014000342C  mov     edx, 0C00h                 ; two WIL state bits
0000000140003435  and     eax, edx
0000000140003437  cmp     eax, edx                   ; both set?
0000000140003439  jnz     short loc_140003440
0000000140003453  call    wil_details_AreDependenciesEnabled   ; NEW WIL helper
0000000140003460  test    r14d, r14d
0000000140003469  btr     eax, 0Ah                   ; clear WIL bit 0x400 if deps disabled
0000000140003498  retn

wil_details_AreDependenciesEnabled (0x140002CA8) is present only in the patched build. At the same address in the unpatched build sits an unrelated function (wil_details_FeatureReporting_IncrementOpportunityInCache) — an example of address reuse across builds; the helper is genuinely new, added by the WIL revision.

wil_details_FeatureStateCache_ReevaluateCachedFeatureEnabledState — the 0x40000 marker

In the patched build the state value written by lock cmpxchg [r12], esi has bit 0x40000 set via bts eax, 12h. The unpatched build commits the same state word without that bit. All other encoding masks (0x9C1, 0xFFFFF63E, 0x400, btr ...,0Ah) are identical in both builds.


6. Real Mup* Attack Surface — Unchanged

The Multiple UNC Provider network-facing functions did not change in logic. The following Mup* functions show differences only because the WIL functions grew and pushed later code down, shifting jump/return-target addresses:

MupGetIoStatus, MupPostAcquireForSectionSynchronisation, MupStateMachine, MupSurrogateGetUncProviderDeviceObject, MupiGetNextUncHardeningConfigurationEntry, MupiGetNextUncProvider, MupiSetProviderFlags — each differs only in relocated locret_/jump-table target addresses; instruction streams are otherwise identical.

MupCallSurrogatePrePost (unpatched 0x14001D3F0, patched 0x14001D4C0) is the one Mup function with a real code difference, and it is a compiler refactor of linked-list pointer arithmetic: manual add/dereference sequences were replaced with scaled indexing ([rbx+rax*8+...], [rsi+rax*8+8]). The control flow and the STATUS_MORE_PROCESSING_REQUIRED (0x103) comparison are preserved. Semantics are unchanged; not security-relevant.


7. Exploit Primitive

None. There is no security bug here to exploit. The changed code is WIL feature-staging bookkeeping; it does not alter any UNC authentication, integrity, provider-selection, or hardening decision. There is no memory-corruption primitive, no policy bypass, and no attacker-reachable behavioral difference between the two builds.


8. Trigger / Reachability

The changed WIL routines run during feature-state evaluation inside the driver's own WIL runtime (feature descriptor queries and cache re-evaluation). They are not gated behind, and do not implement, the Hardened UNC Paths policy. No user-mode UNC operation produces a security-relevant difference in behavior between the unpatched and patched builds.


9. Changed Functions — Full Triage

Function Address (unpatched → patched) Similarity Nature
wil_details_GetCurrentFeatureEnabledState 0x1400032CC → 0x140003384 0.748 WIL feature-dependency evaluation added (calls new wil_details_AreDependenciesEnabled). Not security-relevant.
wil_details_EvaluateFeatureDependencies_ReevaluateCachedFeatureEnabledState 0x140012D90 (same) 0.754 Same WIL dependency gate before the state-cache lock cmpxchg. Not security-relevant.
wil_details_FeatureStateCache_ReevaluateCachedFeatureEnabledState 0x14000317C → 0x14000321C 0.973 Adds WIL cache-marker bit 0x40000 (bts eax,12h) plus register reallocation. Not security-relevant.
MupCallSurrogatePrePost 0x14001D3F0 → 0x14001D4C0 0.926 Compiler refactor of linked-list pointer arithmetic (manual add → scaled rax*8). Semantics identical. Not security-relevant.
wil_InitializeFeatureStaging 0x1400230F4 (same) 0.983 Call-target relocations; RtlRegisterFeatureUsageProvider call moved into new wrapper wil_details_RegisterFeatureUsageProvider (0x140012F2C). Not security-relevant.

All remaining Mup* differences are jump-target relocation only (no logic change).


10. Independent Full-Diff Triage

An independent function-by-function comparison of both builds (matching by content across relocations, not by reused address) was performed to confirm nothing security-relevant was omitted:

  • Added in patched (2): wil_details_AreDependenciesEnabled (0x140002CA8) and wil_details_RegisterFeatureUsageProvider (0x140012F2C). Both are WIL library helpers introduced by the WIL revision; neither touches UNC provider selection or authentication.
  • Removed in unpatched: none.
  • Content-changed: the five functions in Section 9 plus a set of Mup*/library functions whose only differences are relocated jump/return targets (normalizing address operands: instruction streams match).
  • No omitted security fix was found. In particular, no Mup* routine that participates in UNC path handling, provider registration, hardening-configuration parsing, or authentication changed in logic.

11. Unmatched Functions

Direction Functions
Removed (unpatched-only) None
Added (patched-only) wil_details_AreDependenciesEnabled (0x140002CA8), wil_details_RegisterFeatureUsageProvider (0x140012F2C) — both WIL helpers

12. Confidence & Caveats

Confidence: High. The changed functions are named as WIL feature-staging routines in both disassembly listings, the new helper is wil_details_AreDependenciesEnabled, and the flag-source call is wil_RtlStagingConfig_QueryFeatureState. The 0xc00 and 0x40000 bits are WIL feature-state cache encodings. Every UNC-facing Mup* function is identical except for relocation and one semantics-preserving compiler refactor.

Conclusion: This patch is a WIL feature-staging library version bump. It contains no security-relevant change to the Multiple UNC Provider driver.