mup.sys — WIL feature-state cache library churn
KB5094126
1. Overview
- Unpatched Binary:
mup_unpatched.sys - Patched Binary:
mup_patched.sys - Overall Similarity: 99.2%
- Diff Statistics: 364 matched functions, 2 functions with behavioral body changes, 0 added/removed functions. One additional difference is a trace-stub symbol rename (
WPP_SF_d→WPP_SF_D) with an identical body. - Verdict: No security-relevant change. Both behavioral changes are inside the statically-linked Windows Implementation Library (WIL) feature-staging code (
wil_details_*). One refines how WIL's cached feature-enabled-state value is recomputed and committed; the other adjusts the arguments passed when registering WIL's feature-usage telemetry provider. Neither touches MUP's UNC/redirector request handling, and neither is reachable from attacker-controlled file I/O. There is no memory-safety defect, no race with security impact, and no exploit primitive.
2. Changed Function Summary
wil_details_FeatureStateCache_ReevaluateCachedFeatureEnabledState @ 0x140003180
- Nature: WIL feature-staging library behavior refinement. Not security-relevant.
- What it is: This function recomputes WIL's cached "feature enabled state" for a compile-time feature gate and commits the new packed 32-bit value with an
_InterlockedCompareExchange(lock cmpxchg) retry loop. It is part of the Windows Implementation Library feature-management infrastructure, not the Multiple UNC Provider request path. The state pointer it updates is a compile-time WIL feature descriptor (Feature_364057912__private_featureState), and the helpers it calls are all WIL internals:wil_details_GetCurrentFeatureEnabledState,g_wil_details_ensureSubscribedToFeatureConfigurationChanges,g_wil_details_subscribeFeatureStateCacheToConfigurationChanges. - Callers:
wil_details_AreDependenciesEnabled(0x140002C3C) andwil_details_IsEnabledFallback(0x1400033FC). Both are WIL feature-gate evaluation helpers invoked fromFeature_*__private_IsEnabled-style checks, not from any IRP dispatch or UNC path parser. - What changed: The patched build unconditionally sets bit 18 (value
0x40000) of the recomputed cache value at the top of each CAS iteration (bts eax, 12hat 0x1400031DC), whereas the unpatched build only carried that bit on the resolver-success merge branch. The conditional merge mask is correspondingly changed from& 0xFFFFF63Eto& 0xFFFBF63E | 0x40000, keeping bit 18 set on that path too, and a redundant early stack store is dropped. The net effect is that the recomputed WIL feature-cache value now always carries bit0x40000. This bit is internal to WIL's feature-state cache encoding and is consumed only by WIL's ownIsEnabledfast-path checks. - Security assessment: The state field is a per-feature compile-time gate, not an attacker-reachable object with a managed alloc/free lifetime. The
IsEnabledcache is a standard WIL pattern present across many Windows binaries; a refinement to how its cached value is marked is library servicing churn, not a memory-safety or race fix with security impact.
wil_details_RegisterFeatureUsageProvider @ 0x14001238C
- Nature: WIL feature-usage telemetry provider registration. Not security-relevant.
- What changed: The patched build adds two stack locals in the structure passed to
RtlRegisterFeatureUsageProvider(one initialized to1, one initialized to0). This adjusts the registration record for WIL's feature-usage reporting provider. It does not affect memory safety or any request-handling logic.
WPP_SF_D @ 0x140002510 (formerly WPP_SF_d)
- Nature: WPP (Windows software trace preprocessor) trace-stub symbol rename. Not security-relevant.
- What changed: The auto-generated trace-format stub's symbol changed case (
WPP_SF_d→WPP_SF_D). The function body is identical between builds; all other diff lines referencing this symbol are just the renamed call sites. This is tracing-infrastructure churn.
3. Pseudocode Diff
Decompiled body of wil_details_FeatureStateCache_ReevaluateCachedFeatureEnabledState @ 0x140003180. This is the only behavioral change of note, and it is confined to how the recomputed WIL feature-cache value is marked before the interlocked commit.
// --- UNPATCHED (relevant CAS-loop region) ---
v8 = v5;
for ( i = v5; ; i = v8 )
{
v10 = v8;
LODWORD(v13) = v8; // no 0x40000 forced here
if ( v12 != 0 )
{
LODWORD(v13) = v8;
if ( (i & 2) == 0 )
{
v10 = CurrentFeatureEnabledState & 0x9C1 | v8 & 0xFFFFF63E | 2;
LODWORD(v13) = v10;
}
}
if ( (v5 & 4) == 0 )
v10 = v10 & 0xFFFFFBFF | CurrentFeatureEnabledState & 0x400 | 4;
v8 = _InterlockedCompareExchange(a1, v10, v5);
if ( v5 == v8 ) break;
v5 = v8;
}
// --- PATCHED (relevant CAS-loop region) ---
v8 = v5;
for ( i = v5; ; i = v8 )
{
v10 = v8 | 0x40000; // bit 18 always set (bts eax, 12h)
LODWORD(v13) = v8 | 0x40000;
if ( v12 != 0 && (i & 2) == 0 )
{
v10 = CurrentFeatureEnabledState & 0x9C1 | v8 & 0xFFFBF63E | 0x40000 | 2;
LODWORD(v13) = v10;
}
if ( (v5 & 4) == 0 )
v10 = v10 & 0xFFFFFBFF | CurrentFeatureEnabledState & 0x400 | 4;
v8 = _InterlockedCompareExchange(a1, v10, v5);
if ( v5 == v8 ) break;
v5 = v8;
}
4. Assembly Analysis
Real disassembly of the changed region in wil_details_FeatureStateCache_ReevaluateCachedFeatureEnabledState @ 0x140003180. Addresses and mnemonics are copied verbatim from the two builds.
Unpatched
00000001400031D8 mov eax, edi
00000001400031DA mov ecx, edi
00000001400031DC cmp [rsp+48h+arg_0], 0
00000001400031E1 mov esi, eax
00000001400031E3 mov dword ptr [rsp+48h+arg_8], eax
00000001400031E7 jz short loc_140003208
00000001400031E9 mov dword ptr [rsp+48h+arg_8], eax ; redundant early store
00000001400031ED test cl, 2
00000001400031F0 jnz short loc_140003208
00000001400031F2 and esi, 0FFFFF63Eh
00000001400031F8 mov eax, ebx
00000001400031FA and eax, 9C1h
00000001400031FF or esi, eax
0000000140003201 or esi, 2
0000000140003204 mov dword ptr [rsp+48h+arg_8], esi
...
0000000140003227 mov eax, edi
0000000140003229 lock cmpxchg [r15], esi
000000014000322E jz short loc_140003236
0000000140003230 mov edi, eax
0000000140003232 mov ecx, eax
0000000140003234 jmp short loc_1400031DC ; retry loop
Patched
00000001400031D8 mov eax, edi
00000001400031DA mov ecx, edi
00000001400031DC bts eax, 12h ; NEW: force bit 0x40000 each iteration
00000001400031E0 cmp [rsp+48h+arg_0], 0
00000001400031E5 mov esi, eax
00000001400031E7 mov dword ptr [rsp+48h+arg_8], eax
00000001400031EB jz short loc_140003208
00000001400031ED test cl, 2 ; redundant early store removed
00000001400031F0 jnz short loc_140003208
00000001400031F2 and esi, 0FFFFF63Eh
00000001400031F8 mov eax, ebx
00000001400031FA and eax, 9C1h
00000001400031FF or esi, eax
0000000140003201 or esi, 2
0000000140003204 mov dword ptr [rsp+48h+arg_8], esi
...
0000000140003227 mov eax, edi
0000000140003229 lock cmpxchg [r15], esi
000000014000322E jz short loc_140003236
0000000140003230 mov edi, eax
0000000140003232 mov ecx, eax
0000000140003234 jmp short loc_1400031DC ; retry loop (bts re-runs each iteration)
The bts eax, 12h sets bit 18 (0x40000) of the working state value. Because the retry jmp targets loc_1400031DC, the bit is re-forced on every CAS iteration. This is the sole functional delta in this function.
5. Reachability
This function is not reachable from attacker-controlled input. It is a WIL feature-gate cache updater:
- It is called only by
wil_details_AreDependenciesEnabled(0x140002C3C) andwil_details_IsEnabledFallback(0x1400033FC). - Those callers evaluate compile-time WIL feature descriptors (e.g.
Feature_364057912__private_featureState,&wil_details_featureDescriptors_a), which are decided by feature-staging configuration, not by any field of an incoming IRP or UNC path. - There is no path from
IRP_MJ_CREATEon\Device\Mupor from a UNC path parser into this function. The0x40000bit is a WIL cache-encoding flag consumed only by WIL's ownIsEnabledchecks.
There is no UNC prefix cache, no per-request prefix-table entry, and no attacker-influenced state field involved.
6. Exploit Primitive
None. The change is a refinement of a statically-linked library's internal feature-state cache marking. The state field is a compile-time feature gate with no managed alloc/free object behind it, so there is no use-after-free, no pool corruption, and no privilege-escalation primitive. No heap grooming, no info-leak, and no token manipulation applies.
7. Verification Notes
To confirm the nature of the change against the binaries:
- The function at 0x140003180 is
wil_details_FeatureStateCache_ReevaluateCachedFeatureEnabledStatein both builds (identical prologue and identical set of WIL helper calls:wil_details_GetCurrentFeatureEnabledState,g_wil_details_ensureSubscribedToFeatureConfigurationChanges,g_wil_details_subscribeFeatureStateCacheToConfigurationChanges). - The only instruction-level delta is the added
bts eax, 12hat 0x1400031DC plus the removal of the redundant store previously at 0x1400031E9; the interlocked commit at 0x140003229 (lock cmpxchg [r15], esi) is unchanged. - The callers (0x140002C3C, 0x1400033FC) pass compile-time WIL feature descriptors, confirming the state field is a feature gate, not a UNC prefix entry.
8. Changed Functions — Full Triage
wil_details_FeatureStateCache_ReevaluateCachedFeatureEnabledState @ 0x140003180 (Non-Security)
- Similarity Score: 0.9887
- Change Type: Behavioral (WIL library), non-security.
- Notes: Unconditionally sets bit
0x40000in the recomputed WIL feature-enabled-state cache value before the interlocked commit, and drops a redundant early store. Feature-staging library servicing churn; not reachable from attacker-controlled input.
wil_details_RegisterFeatureUsageProvider @ 0x14001238C (Non-Security)
- Similarity Score: 0.976
- Change Type: Behavioral (WIL telemetry), non-security.
- Notes: Adds two stack locals (one set to
1, one set to0) to the record passed toRtlRegisterFeatureUsageProvider. WIL feature-usage provider registration; unrelated to memory safety or request handling.
WPP_SF_D @ 0x140002510 (Non-Security)
- Change Type: Trace-stub symbol rename (
WPP_SF_d→WPP_SF_D), identical body. - Notes: WPP tracing-infrastructure symbol case change. No behavioral effect.
9. Unmatched Functions
There are no added or removed functions between the unpatched and patched binaries.
10. Confidence & Caveats
- Confidence: High that this is not a security-relevant change. Both behavioral deltas are confined to statically-linked WIL feature-staging code, and the changed function is not reachable from attacker-controlled file I/O.
- Caveat: The exact semantic meaning of WIL feature-state cache bit
0x40000within the library's encoding was not decoded from the binary; the security assessment does not depend on it, because the state field is a compile-time feature gate rather than an attacker-reachable object.