mrxsmb.sys — WIL feature-flag graduation in SMB negotiate
KB5077181
1. Overview
| Field | Value |
|---|---|
| Unpatched Binary | mrxsmb_unpatched.sys |
| Patched Binary | mrxsmb_patched.sys |
| Overall Similarity | 0.9917 |
| Matched Functions | 1228 |
| Changed Functions | 2 |
| Identical Functions | 1226 |
| Unmatched (Unpatched) | 0 |
| Unmatched (Patched) | 0 |
Verdict: The patch graduates a WIL/Velocity feature-staging flag (Feature_2990496056) to permanently enabled in two SMB negotiate functions and removes the now-dead feature helper functions. This is staged-rollout churn: the feature-off code path is deleted and the feature-on behavior becomes unconditional. The observable SMB negotiation outcome is unchanged, and the removed check is a Microsoft-managed feature flag, not an attacker- or admin-controllable policy. No security-relevant behavior change and no exploitable primitive are present.
2. Change Summary
Finding 1 — WIL feature-flag graduation in SmbNegotiate_Start and SmbNegotiate_Continue
- Severity: None (no security-relevant change)
- Nature: Feature-staging graduation (WIL
Feature_*__private_IsEnabled*) - Affected Functions:
SmbNegotiate_Start(0x140038400) andSmbNegotiate_Continue(0x14008E800)
What changed:
In the unpatched driver both functions call Feature_2990496056__private_IsEnabledDeviceUsageNoInline before deciding how to set two fields on the SMB negotiation context: a byte at server-extension +0x26F and a security-mode word at +0x5C4. That helper is a standard Windows Implementation Library (WIL) feature check: it reads the cached Feature_2990496056__private_featureState global and, on a cache miss (test al, 0x10 clear), delegates to wil_details_IsEnabledFallback with Feature_2990496056__private_descriptor. This is Microsoft's feature-rollout ("Velocity") mechanism, not a registry value or Group Policy setting.
The patch:
- Removes the
Feature_2990496056call from both functions. - Keeps only the feature-on behavior (in
SmbNegotiate_Continuethe feature-off branch is deleted; inSmbNegotiate_Startthe+0x26Fwrite is no longer gated). - Strips the two now-unreferenced feature helper functions (
Feature_2990496056__private_IsEnabledDeviceUsageNoInlineat0x1400490ECandFeature_2990496056__private_IsEnabledFallbackat0x140049124).
Why this is not a security fix:
In every combination of feature states the negotiated security-mode word at +0x5C4 is set to 2 (encrypted) exactly when the per-server instance configuration byte at MRxSmbGetInstanceConfigurationBlock()+0x38 requires encryption, and to 1 otherwise. The feature only changes whether the intermediate byte at +0x26F is written by these functions and which field feeds the security-mode word. There is no code path in either build where the server configuration requires encryption but the negotiated security mode is left at plaintext, so no downgrade is demonstrable. The removed check is a feature flag controlled by Microsoft's feature-management system, not by an attacker or administrator.
A separate, unchanged feature:
Both builds also call Feature_Servicing_SMBFixS2DAccessDeniedIssues__private_IsEnabledDeviceUsageNoInline, an unrelated WIL feature. It is present and behaviorally unchanged in both builds and was only relocated (from 0x140049140 to 0x1400490DC). It is not part of this change.
3. Pseudocode Diff
SmbNegotiate_Start (0x140038400)
// UNPATCHED
if (MRxSmbCopyCipherSuiteInfoFromGlobalConfig(rcx+0x18, 4, rcx+0x28) >= 0)
{
if (Feature_2990496056__private_IsEnabledDeviceUsageNoInline()) // WIL feature check
{
if (*(MRxSmbGetInstanceConfigurationBlock(*(rbx+0x18)) + 0x38))
*(*(*(arg1+0x60)+0x188) + 0x26f) = 1; // encryption byte
}
}
// PATCHED (feature check removed; config-driven write unchanged)
if (MRxSmbCopyCipherSuiteInfoFromGlobalConfig(rcx+0x18, 4, rcx+0x28) >= 0)
{
if (*(MRxSmbGetInstanceConfigurationBlock(*(rbx+0x18)) + 0x38))
*(*(*(arg1+0x60)+0x188) + 0x26f) = 1;
}
SmbNegotiate_Continue (0x14008E800)
// UNPATCHED (feature-on and feature-off paths both present)
if (Feature_2990496056__private_IsEnabledDeviceUsageNoInline())
{
// feature-on: security mode derived from the already-set +0x26f byte
*(rdi+0x5c4) = (*(rsi+0x26f) != 0) ? 2 : 1;
}
else
{
// feature-off: security mode derived directly from server config byte
if (*(MRxSmbGetInstanceConfigurationBlock(r15) + 0x38)) {
*(rdi+0x5c4) = 2;
*(rsi+0x26f) = 1;
} else {
*(rdi+0x5c4) = 1;
}
}
// PATCHED (feature-off path deleted; feature-on behavior kept unconditionally)
*(rdi+0x5c4) = (*(rsi+0x26f) != 0) ? 2 : 1;
WIL feature helper Feature_2990496056__private_IsEnabledDeviceUsageNoInline (0x1400490EC, removed in patch)
eax = Feature_2990496056__private_featureState; // WIL cached feature state
if ((eax & 0x10) == 0)
return Feature_2990496056__private_IsEnabledFallback(); // -> wil_details_IsEnabledFallback
return eax & 1; // cached enabled bit
4. Assembly Analysis
SmbNegotiate_Start — the removed gate
; ---- UNPATCHED (0x140038400) ----
000000014003844C call Feature_2990496056__private_IsEnabledDeviceUsageNoInline
0000000140038451 test eax, eax
0000000140038453 jz short loc_140038477 ; skip +0x26F write when feature disabled
0000000140038455 mov rcx, [rbx+18h]
0000000140038459 call MRxSmbGetInstanceConfigurationBlock
000000014003845E mov al, [rax+38h] ; server encryption-required byte
0000000140038461 test al, al
0000000140038463 jz short loc_140038477
0000000140038465 mov rax, [rdi+60h]
0000000140038469 mov rcx, [rax+188h]
0000000140038470 mov byte ptr [rcx+26Fh], 1
; ---- PATCHED (0x140038400) ----
000000014003844C mov rcx, [rbx+18h] ; feature check gone; config-driven write kept
0000000140038450 call MRxSmbGetInstanceConfigurationBlock
0000000140038455 mov al, [rax+38h]
0000000140038458 test al, al
000000014003845A jz short loc_14003846E
000000014003845C mov rax, [rdi+60h]
0000000140038460 mov rcx, [rax+188h]
0000000140038467 mov byte ptr [rcx+26Fh], 1
SmbNegotiate_Continue — the removed feature-off path
; ---- UNPATCHED (0x14008E800) ----
000000014008EA88 call Feature_2990496056__private_IsEnabledDeviceUsageNoInline
000000014008EA8D test eax, eax
000000014008EA8F jnz short loc_14008EABB ; feature-on path
; feature-off path:
000000014008EA91 mov rcx, r15
000000014008EA94 call MRxSmbGetInstanceConfigurationBlock
000000014008EA99 movzx eax, byte ptr [rax+38h] ; server encryption-required byte
000000014008EA9D test al, al
000000014008EA9F jz short loc_14008EAB1
000000014008EAA1 mov [rdi+5C4h], bx ; security mode = 2
000000014008EAA8 mov [rsi+26Fh], r14b ; encryption byte = 1
000000014008EAAF jmp short loc_14008EAD0
000000014008EAB1 mov [rdi+5C4h], r14w ; security mode = 1
; feature-on path:
000000014008EABB xor eax, eax
000000014008EABD cmp [rsi+26Fh], al
000000014008EAC3 setnz al
000000014008EAC6 inc ax
000000014008EAC9 mov [rdi+5C4h], ax ; security mode = (26F!=0)?2:1
; ---- PATCHED (0x14008E800) ----
000000014008EA86 xor ebp, ebp ; feature-off path deleted
000000014008EA88 cmp [rsi+26Fh], bpl
000000014008EA8F mov eax, ebp
000000014008EA91 setnz al
000000014008EA94 inc ax
000000014008EA97 mov [rdi+5C4h], ax ; security mode = (26F!=0)?2:1
WIL feature helpers (unpatched, both removed in patch)
; ---- Feature_2990496056__private_IsEnabledDeviceUsageNoInline @ 0x1400490EC ----
00000001400490EC sub rsp, 28h
00000001400490F0 and [rsp+28h+arg_0], 0
00000001400490F6 mov eax, cs:Feature_2990496056__private_featureState
00000001400490FC mov dword ptr [rsp+28h+arg_0], eax
0000000140049100 test al, 10h ; WIL cached-state check
0000000140049102 jz short loc_140049109
0000000140049104 and eax, 1
0000000140049107 jmp short loc_140049118
0000000140049109 mov rcx, [rsp+28h+arg_0]
000000014004910E mov edx, 3
0000000140049113 call Feature_2990496056__private_IsEnabledFallback
0000000140049118 add rsp, 28h
000000014004911C retn
; ---- Feature_2990496056__private_IsEnabledFallback @ 0x140049124 ----
0000000140049124 sub rsp, 28h
0000000140049128 lea r8, Feature_2990496056__private_descriptor
000000014004912F call wil_details_IsEnabledFallback
0000000140049134 add rsp, 28h
0000000140049138 retn
Annotation summary:
0x14003844C/0x14008EA88— the two removed feature-flag call sites.0x1400490F6— read ofFeature_2990496056__private_featureState(the WIL cached feature state; not a registry value).0x14004912F— delegation towil_details_IsEnabledFallbackwith the feature descriptor, confirming the WIL feature-management pattern.- In
SmbNegotiate_Continue,bx/r14whold the constants2and1; the security-mode word at[rdi+0x5C4]ends up2when the server config byte[config+0x38]requires encryption in every path.
5. Direction and Behavior Check
- Direction: The patched build removes a feature check and makes the feature-on behavior permanent. This is the stricter/simpler direction (fewer branches), consistent with graduating a feature that had been staged.
- Both-build behavior: Across feature-on, feature-off, and the separate
Feature_Servicing_SMBFixS2DAccessDeniedIssuesbranch, the negotiated security-mode word[rdi+0x5C4]is2exactly when[MRxSmbGetInstanceConfigurationBlock()+0x38]requires encryption. The observable negotiation result is identical in both builds. - Attacker control: None.
Feature_2990496056__private_featureStateis populated by Windows feature management; it is not derived from an SMB packet, a registry parameter, or Group Policy.
6. Impact Assessment
No exploitable primitive is present. The change does not add or remove a bounds check, a pointer validation, a lifetime/free, or a size computation. It does not alter what encryption the client negotiates as a function of the server's requirement. The only functional difference is which internal code path computes the same security-mode value, gated by a Microsoft-managed feature flag.
Because the negotiated security mode tracks the server configuration byte in both builds, the previously suggested "silent plaintext downgrade to an encryption-requiring server" is not supported by the code and is withdrawn. There is no man-in-the-middle, credential-capture, or downgrade primitive attributable to this diff.
7. Changed Functions — Full Triage
SmbNegotiate_Continue (0x14008E800, similarity 0.9528)
- Removed the call to
Feature_2990496056__private_IsEnabledDeviceUsageNoInline()at0x14008EA88. - Deleted the feature-off branch that set
[rdi+0x5C4]from the server config byte and set[rsi+0x26F]=1; kept the feature-on branch ([rdi+0x5C4] = (byte[rsi+0x26F]!=0)?2:1) unconditionally. - Register reallocation only (the constant
2moves frombxtor14d;1becomes an immediate). - The separate
Feature_Servicing_SMBFixS2DAccessDeniedIssuescheck earlier in the function is unchanged in both builds. - Impact: None; feature-staging graduation.
SmbNegotiate_Start (0x140038400, similarity 0.9722)
- Removed the call to
Feature_2990496056__private_IsEnabledDeviceUsageNoInline()at0x14003844C. - The
[rcx+0x26F]=1write is now reached whenever[MRxSmbGetInstanceConfigurationBlock()+0x38]is non-zero, without the feature check. The config-driven write itself is byte-for-byte identical in both builds. - Impact: None; feature-staging graduation.
Relocation-only differences (not logic changes)
A raw instruction diff flags roughly 180 additional functions, but each differs only in relocated code/data addresses caused by stripping the two Feature_2990496056 helpers: locret_* label targets, .data symbol addresses (e.g. byte_1400722EB -> byte_1400722CB), and string-literal addresses (e.g. asc_140066AA4 -> asc_140066A74). None contain a control-flow or operation change. These are not security-relevant.
8. Unmatched Functions
| Direction | Functions | Notes |
|---|---|---|
| Removed (in unpatched, absent in patched) | Feature_2990496056__private_IsEnabledDeviceUsageNoInline (0x1400490EC), Feature_2990496056__private_IsEnabledFallback (0x140049124) |
Dead after both call sites removed; stripped by the linker. |
| Added (in patched, absent in unpatched) | none | — |
9. Confidence & Caveats
Confidence: HIGH that this is a feature-staging graduation with no security-relevant behavior change. The removed helper is unambiguously a WIL feature check (Feature_2990496056__private_featureState + wil_details_IsEnabledFallback + Feature_2990496056__private_descriptor). Both call sites are removed, the feature helpers are stripped, and the negotiated security mode tracks the server configuration byte identically in both builds.
Caveats:
- The exact policy meaning of
Feature_2990496056(an unnamed numeric velocity feature) and the default rollout state ofFeature_2990496056__private_featureStateare not recoverable from these binaries; they are managed outside the driver by Windows feature management. This does not affect the conclusion, because the observable negotiation result is the same regardless of the feature's state. - The semantic labels for the touched fields (server-extension
+0x26F, security-mode word+0x5C4, instance-config byte+0x38) are inferred from their1/2value pattern and their role in negotiate setup; the field addresses and constants themselves are taken directly from the disassembly.