1. Overview

Field Value
Unpatched binary mup_unpatched.sys
Patched binary mup_patched.sys
Overall similarity 0.9873
Functions matched by name 357
Functions with a real logic change 3 (all WIL feature-staging)
Functions identical (mnemonics; only relocated references differ) 354
Functions only in one build 1 removed / 3 added (WIL/WPP helpers)

Verdict: There is no security-relevant change in this patch. The only functions whose instruction logic actually changed are three internal Windows Implementation Library (WIL) feature-staging routines. WIL is Microsoft's velocity/feature-flag library that is statically linked into many drivers; it decides at runtime whether an experimental "feature" is enabled. The change refactors and slightly tightens how a feature's dependencies are evaluated. None of the changed code is on the UNC/SMB attack surface, none of it consumes attacker-controlled input, and every Mup* UNC function (create dispatch, prefix resolution, UNC-hardening configuration, provider selection) is byte-for-byte identical between the two builds apart from relocated branch/reference targets. This is ordinary library churn from a WIL rebuild, not a fix.

An earlier reading of this diff described a "UNC Hardening integrity/mutual-auth bypass." That reading was based on masked sub_* addresses and does not survive symbol resolution: the named functions are WIL feature-flag internals, and the bit values interpreted as RequireIntegrity/RequireMutualAuth are WIL feature-state encodings, not SMB security flags. The sections below document the real functions, the real change, and why it carries no security weight.


2. Change Summary

The three functions that actually changed

Named function Unpatched addr Patched addr Nature
wil_details_GetCurrentFeatureEnabledState 0x140003244 0x1400032E4 Feature-enabled-state computation; dependency-walk loop factored out into a new helper and gated on a (state & 0xC00) == 0xC00 condition.
wil_details_EvaluateFeatureDependencies_ReevaluateCachedFeatureEnabledState 0x140012200 0x140012200 Same dependency-gating logic in the cached-state lock cmpxchg re-evaluation variant.
wil_InitializeFeatureStaging 0x1400230F0 0x1400230F0 Registration refactor: an inline RtlRegisterFeatureUsageProvider sequence is replaced by a call to a new helper wil_details_RegisterFeatureUsageProvider.

All three are wil_details_* / wil_* symbols — internal WIL feature-staging code. There is no Mup* (Multiple UNC Provider) function among them.

Functions present in only one build (all library helpers, not Mup logic)

  • Added in patched: wil_details_AreDependenciesEnabled (0x140002C3C), wil_details_RegisterFeatureUsageProvider (0x14001238C), WPP_SF_d (a WPP trace-format helper).
  • Removed from unpatched: WPP_SF_D (a WPP trace-format helper differing only in a format specifier).

The two added wil_details_* functions are the extracted helpers that the three changed functions now call; they are not new security checks. WPP_SF_DWPP_SF_d is a tracing-format-string helper churn.

What the WIL bits actually are

wil_details_GetCurrentFeatureEnabledState calls wil_RtlStagingConfig_QueryFeatureState (the ntoskrnl feature-staging configuration query) and packs the result into a small state word. The bit values are WIL feature-state encodings — an experimental-feature enable/variant state and a dependency/change-tracking marker — not SMB or UNC-hardening flags. The same feature-state word is what wil_details_FeatureStateCache_ReevaluateCachedFeatureEnabledState tests (e.g. test dword ptr [rcx+2Ch], 4000000h), and that function is identical in both builds. There is no RequireIntegrity/RequireMutualAuth/0xc00-SMB-policy semantics anywhere in this code.


3. What actually changed (decompilation)

wil_details_GetCurrentFeatureEnabledState

Unpatched (0x140003244) computes the feature-enabled-state word and, when the "walk dependencies" bit is set, inlines a loop over the dependency list at *(a1 + 32), evaluating each dependency via wil_details_FeatureStateCache_ReevaluateCachedFeatureEnabledState:

// unpatched: dependency loop is inlined
if ( (v8 & 0x40) != 0 ) {
    v11 = *(unsigned int ****)(a1 + 32);
    if ( v11 != nullptr ) {
        do {
            ...
            LOBYTE(v13) = wil_details_FeatureStateCache_ReevaluateCachedFeatureEnabledState(*v12, v21, (__int64)v12);
            ...
        } while ( ... );
    }
}

Patched (0x1400032E4) factors that same loop into the new helper wil_details_AreDependenciesEnabled and adds a gate on the combined feature-state bits:

// patched: dependency loop is now a helper, plus a (state & 0xC00)==0xC00 gate
if ( (v10 & 0xC00) == 0xC00 )
    v12 = 1;
else { v12 = 0; if ( (v10 & 0x40) == 0 ) { v6 = 0; goto LABEL_18; } }
v13 = *(_QWORD *)(a1 + 32) == 0 || wil_details_AreDependenciesEnabled(a1);
if ( v12 != 0 && !v13 )
    v10 &= ~0x400u;                 // clear a feature-state bit when dependencies not satisfied
if ( (v10 & 0x40) == 0 || !v13 )
    goto LABEL_17;

wil_details_AreDependenciesEnabled (0x140002C3C, patched-only) is exactly the loop that used to be inlined — it walks *(a1 + 32) and evaluates each dependency feature through wil_details_FeatureStateCache_ReevaluateCachedFeatureEnabledState, returning whether all dependencies are enabled.

This is a feature-flag dependency evaluation: a staged feature is only reported "enabled" if the features it depends on are also enabled. It is not an authorization or integrity check, and the list at *(a1 + 32) is a WIL feature-dependency list, not a UNC provider list.

wil_details_EvaluateFeatureDependencies_ReevaluateCachedFeatureEnabledState

The same dependency-gating logic in the cached-state re-evaluation path. The patched build adds and eax, 0xC00; cmp eax, 0xC00; setz bpl and, after the dependency loop, if (both-bits-requested && no-satisfying-dependency) btr edx, 0Ah before the existing lock cmpxchg that updates the cached feature-state word. Same WIL feature-staging semantics as above.

wil_InitializeFeatureStaging

Pure refactor. The unpatched build inlines:

lea  rax, wil_details_RecordFeatureUsageReporting
lea  r8,  g_wil_details_featureUsageProvider
mov  cs:g_wil_details_recordFeatureUsage, rax
lea  rcx, wil_details_OnFeatureUsageProviderFlushNotification
call cs:__imp_RtlRegisterFeatureUsageProvider

The patched build replaces the whole sequence with call wil_details_RegisterFeatureUsageProvider. Feature-usage-telemetry registration extracted into a helper; no behavioral or security-boundary change.


4. Assembly evidence

wil_details_GetCurrentFeatureEnabledState

Unpatched, the dependency evaluation is an inline call inside the loop:

; wil_details_GetCurrentFeatureEnabledState @ 0x140003244 (unpatched)
000000014000334C  call    wil_details_FeatureStateCache_ReevaluateCachedFeatureEnabledState

Patched, the loop is a helper call preceded by the new combined-bit gate and followed by the conditional bit clear:

; wil_details_GetCurrentFeatureEnabledState @ 0x1400032E4 (patched)
0000000140003389  mov     edx, 0C00h                       ; combined feature-state mask
000000014000338E  mov     eax, ebx
0000000140003390  and     eax, edx
0000000140003394  cmp     eax, edx                         ; both bits set?
00000001400033A9  jz      short loc_1400033B7              ; dependency list == 0 -> treat as satisfied
00000001400033AE  call    wil_details_AreDependenciesEnabled
00000001400033C2  btr     ebx, 0Ah                         ; clear feature-state bit when deps unsatisfied

wil_details_AreDependenciesEnabled at 0x140002C3C exists only in the patched build. At that same address the unpatched build holds a different function, wil_details_FeatureReporting_IncrementOpportunityInCache — the address was reused, so the two must not be treated as one function across builds.

wil_details_FeatureStateCache_ReevaluateCachedFeatureEnabledState (unchanged)

This function (the one that evaluates a cached feature state) is present in both builds — unpatched 0x1400030E0, patched 0x140003180 — with an identical mnemonic sequence; the only differences are relocated loc_* branch targets. It is not part of the change.


5. Trigger Conditions

None applicable. There is no vulnerability here to trigger. The changed code is WIL feature-staging library logic that runs during feature-flag queries; it does not process UNC paths, network data, IRP contents, or any other attacker-influenced input, and its outcome is governed by the compiled-in feature-staging configuration, not by a remote server or a local caller.


6. Exploit Primitive & Development Notes

None. No memory-corruption, information-disclosure, or authorization primitive exists in this diff. The change neither adds nor removes any security check on the UNC/SMB path. Mitigations such as SMEP/SMAP/CFG/HVCI are irrelevant because there is no code-execution or policy primitive to discuss.


7. Debugger Notes

No security-relevant behavior to reproduce. For orientation only: the three changed functions are wil_details_GetCurrentFeatureEnabledState (patched 0x1400032E4), wil_details_EvaluateFeatureDependencies_ReevaluateCachedFeatureEnabledState (0x140012200), and wil_InitializeFeatureStaging (0x1400230F0). They are reached from WIL feature-flag query stubs, not from IRP_MJ_CREATE on a UNC path. mup.sys uses a 0x140000000 preferred base; rebase any address by the actual load delta.


8. Changed Functions — Full Triage

Function Change type Note
wil_details_GetCurrentFeatureEnabledState (0x1400032440x1400032E4) WIL feature-staging Dependency-walk loop factored into wil_details_AreDependenciesEnabled; adds a (state & 0xC00) == 0xC00 gate that clears one feature-state bit when a staged feature's dependencies are not all enabled. Not a security boundary.
wil_details_EvaluateFeatureDependencies_ReevaluateCachedFeatureEnabledState (0x140012200) WIL feature-staging Same dependency-gating logic in the cached-state lock cmpxchg re-evaluation variant. Not a security boundary.
wil_InitializeFeatureStaging (0x1400230F0) WIL feature-staging Feature-usage-provider registration extracted from an inline sequence into wil_details_RegisterFeatureUsageProvider. Refactor only.

No Mup* function changed. An independent content diff of all 357 name-matched functions found only these three with differing instruction sequences; every other function (including all UNC-hardening, prefix-resolution, provider-selection, and create-path code) is identical apart from relocated references.


9. Unmatched / Added-Removed Functions

  • Added in patched: wil_details_AreDependenciesEnabled (0x140002C3C), wil_details_RegisterFeatureUsageProvider (0x14001238C) — the two helpers the changed functions now call — and WPP_SF_d, a WPP trace-format helper.
  • Removed from unpatched: WPP_SF_D, a WPP trace-format helper differing only in a format specifier.

All are WIL/WPP library helpers. None is a Mup security routine, an added sanitizer, or a removed mitigation.


10. Confidence & Caveats

Confidence: high that there is no security-relevant change.

  • An independent, name-matched content diff of both builds shows only three functions with real instruction-level changes, all wil_details_* / wil_* feature-staging symbols.
  • The changed code queries the ntoskrnl feature-staging configuration (wil_RtlStagingConfig_QueryFeatureState) and evaluates feature dependencies; it does not touch UNC parsing, SMB negotiation, provider security context, or any attacker-controlled input.
  • The bit values (0x400, 0x800, 0xC00, 0x40) are WIL feature-state encodings; wil_details_FeatureStateCache_ReevaluateCachedFeatureEnabledState, which consumes the same word, is identical in both builds.
  • Every Mup* UNC function is unchanged except for relocated branch/reference targets.

Nature of the change. WIL feature-staging library churn from a rebuild: a feature-dependency evaluation loop was extracted into a helper and a staged feature is now gated on its dependencies being enabled. This is normal velocity/feature-flag plumbing, not a security fix.