mrxsmb.sys — SMB-over-QUIC compression transform header recognition staged behind a WIL feature flag
KB5083769
1. Overview
- Unpatched Binary:
mrxsmb_unpatched.sys - Patched Binary:
mrxsmb_patched.sys - Overall Similarity Score: 0.9919
- Diff Statistics: A single function changes in a behavior-affecting way (
SmbQuicReceiveEvent), accompanied by a newly emitted helper (SmbQuicIsIndicationTransformedMessage) and the associated auto-generated WIL feature-flag stubs. All other apparent differences are relocation/layout noise. - Verdict: No delivered security-relevant change. The patch replaces an inline 4-byte magic check in the SMB-over-QUIC receive-indication parser with a helper that, only when a WIL feature flag (
Feature_Servicing_SmbCompressionOverQuicFix) is enabled, additionally recognizes the SMB compressed transform header magic (0x424d53fc/\xFC SMB) alongside the encrypted transform header magic (0x424d53fd/\xFD SMB). When the flag is disabled — the default state for a staged rollout — the parser accepts only0x424d53fd, exactly as the unpatched build does. No memory-corruption or code-execution primitive is demonstrable in either build.
2. Change Summary
- Severity: None (feature staging).
- Change Class: SMB-over-QUIC compressed transform header recognition gated behind a WIL (Windows Implementation Library) feature flag.
- Affected Function:
SmbQuicReceiveEvent(unpatched0x140050EA4, patched0x140050F54). - New Helper:
SmbQuicIsIndicationTransformedMessage(0x140050C80, patched build only).
What actually changed:
In the unpatched SmbQuicReceiveEvent, the parser reads 4 bytes from the received QUIC indication into a stack buffer and compares them inline against the single constant 0x424d53fd (encrypted transform header). On a match it branches to the transform-handling path; otherwise it treats the bytes as the start of a normal SMB message and continues.
The patched SmbQuicReceiveEvent replaces that inline read-and-compare with a call to the new helper SmbQuicIsIndicationTransformedMessage. The helper performs the same 4-byte read, then calls the WIL feature-flag stub Feature_Servicing_SmbCompressionOverQuicFix__private_IsEnabledDeviceUsageNoInline:
- If the feature is not enabled, the helper returns true only for 0x424d53fd — identical to the unpatched behavior.
- If the feature is enabled, the helper also accepts 0x424d53fc (compressed transform header) using the arithmetic range test (magic + 0xbdb2ac04) <= 1, which is true for 0x424d53fc (result 0) and 0x424d53fd (result 1).
Because the compressed-header branch is gated behind a feature flag that is off pending graduation, the observable behavior of the patched binary is the same as the unpatched binary in the default configuration. This is feature staging for SMB compression over QUIC, not a delivered fix.
Note on the WIL flag: Feature_Servicing_SmbCompressionOverQuicFix__private_IsEnabledDeviceUsageNoInline at 0x14004F73C is an auto-generated WIL feature-state stub: it reads Feature_Servicing_SmbCompressionOverQuicFix__private_featureState, tests bit 0x10, and otherwise falls back to wil_details_IsEnabledFallback with the feature descriptor. It is a global feature-enablement check, not a per-connection compression-negotiation check. At the same address 0x14004F73C the unpatched build hosts a different WIL stub (Feature_servicing_SmbQuicCertRevocationCheckFollowup), so this slot was repurposed for the new feature.
3. Pseudocode Diff
// === UNPATCHED SmbQuicReceiveEvent @ 0x140050EA4 ===
// Reads 4 bytes from the QUIC indication, checks ONLY the encrypted magic.
Mdl_buf = 0;
SmbQuicCopyIndicationToBufferEx(arg2, &Mdl_buf, r14 /*offset*/, 4, nullptr);
if (Mdl_buf == 0x424d53fd) // encrypted transform header only
goto transform_handler; // loc_140051371 (alloc + SmbQuicReceive)
// Otherwise: treat the bytes as a normal SMB message and copy the
// remaining r13 bytes (bounded) into [rdi+0x88], then continue parsing.
rbx_1 = *(rdi + 0x88);
SmbQuicCopyIndicationToBufferEx(arg2, rbx_1, r14, r13 /*bounded*/, nullptr);
// === PATCHED SmbQuicReceiveEvent @ 0x140050F54 ===
if (SmbQuicIsIndicationTransformedMessage(arg2, r14 /*offset*/))
goto transform_handler; // loc_140051409
rbx_1 = *(rdi + 0x88);
SmbQuicCopyIndicationToBufferEx(arg2, rbx_1, r14, r13, nullptr);
// === PATCHED SmbQuicIsIndicationTransformedMessage @ 0x140050C80 (new) ===
magic = 0;
SmbQuicCopyIndicationToBufferEx(arg1, &magic, arg2 /*offset*/, 4, nullptr);
if (Feature_Servicing_SmbCompressionOverQuicFix__IsEnabled() == 0)
return magic == 0x424d53fd; // encrypted only (== unpatched behavior)
// feature enabled: also accept the compressed transform header
return (magic + 0xbdb2ac04) <= 1; // 0x424d53fc (compressed) or 0x424d53fd
4. Assembly Analysis
Unpatched inline check (SmbQuicReceiveEvent, 0x140051204–0x14005122A)
0000000140051204 mov rcx, [rbp+57h+arg_8] ; indication context
0000000140051208 lea rdx, [rbp+57h+Mdl] ; 4-byte stack buffer
000000014005120C and dword ptr [rbp+57h+Mdl], r15d ; zero buffer
0000000140051210 mov r9d, 4 ; read 4 bytes
0000000140051216 and [rsp+0F0h+Irp], r15
000000014005121B mov r8d, r14d ; stream offset
000000014005121E call SmbQuicCopyIndicationToBufferEx
0000000140051223 cmp dword ptr [rbp+57h+Mdl], 424D53FDh ; ONLY encrypted magic
000000014005122A jz loc_140051371 ; match -> transform handler
0000000140051230 mov rbx, [rdi+88h] ; else: raw-message copy target
0000000140051237 mov r9d, r13d ; r13d bounded (<= ebx, >= 4)
000000014005123E mov rdx, rbx
0000000140051249 call SmbQuicCopyIndicationToBufferEx
Patched replacement (SmbQuicReceiveEvent, 0x1400512B4–0x1400512C8)
00000001400512B4 mov rcx, [rbp+57h+arg_8] ; indication context
00000001400512B8 mov edx, r14d ; stream offset
00000001400512BB call SmbQuicIsIndicationTransformedMessage
00000001400512C0 test al, al
00000001400512C2 jnz loc_140051409 ; true -> transform handler
00000001400512C8 mov rbx, [rdi+88h] ; else: raw-message copy target
New helper (SmbQuicIsIndicationTransformedMessage, 0x140050C80)
0000000140050C80 sub rsp, 38h
0000000140050C84 and [rsp+38h+arg_10], 0 ; init 4-byte buffer
0000000140050C89 mov r8d, edx ; stream offset
0000000140050C8C and [rsp+38h+var_18], 0
0000000140050C92 lea rdx, [rsp+38h+arg_10]
0000000140050C97 mov r9d, 4 ; read 4 bytes
0000000140050C9D call SmbQuicCopyIndicationToBufferEx
0000000140050CA2 call Feature_Servicing_SmbCompressionOverQuicFix__private_IsEnabledDeviceUsageNoInline
0000000140050CA7 test eax, eax
0000000140050CA9 jz short loc_140050CBC ; feature off -> encrypted-only check
0000000140050CAB mov eax, [rsp+38h+arg_10]
0000000140050CAF add eax, 0BDB2AC04h ; 0x424d53fc -> 0, 0x424d53fd -> 1
0000000140050CB4 cmp eax, 1 ; accept 0x424d53fc OR 0x424d53fd
0000000140050CB7 setbe al
0000000140050CBA jmp short loc_140050CC7
0000000140050CBC cmp [rsp+38h+arg_10], 424D53FDh ; feature off: encrypted only
0000000140050CC4 setz al
0000000140050CC7 add rsp, 38h
0000000140050CCB retn
Transform handler (loc_140051371, unpatched) — identical in both builds
0000000140051371 mov edx, esi ; esi = message length (see below)
0000000140051373 mov ecx, 42h ; pool flags
0000000140051378 mov r8d, 66426D53h ; pool tag
000000014005137E call cs:__imp_ExAllocatePool2
...
00000001400513B2 call cs:__imp_IoAllocateMdl
00000001400513EE call cs:__imp_MmBuildMdlForNonPagedPool
This allocation/MDL path is reached only when the magic matches and exists byte-for-byte in both builds. esi is the SMB message length taken from [rdi+0x80] (byte-swapped at 0x140051059/0x14005106D) and is bounds-checked at 0x1400510B4 (cmp esi, [rdi+158h]+0x34; jnb ...) before use. It is not a field newly introduced or newly controlled by the changed code.
5. Direction and Reachability
- Direction: The patched build is not stricter on the default path. When the feature flag is disabled, both builds accept only
0x424d53fdand route everything else to the normal-message path. When the flag is enabled, the patched build accepts an additional magic (0x424d53fc) and routes it to the pre-existing transform handler. The change therefore widens what reaches the allocation/MDL path rather than restricting it. The report's earlier framing — that the unpatched build routed compressed headers into an undersized allocation — is not supported: in the unpatched build a0x424d53fcheader does not match and falls through to a boundedSmbQuicCopyIndicationToBufferExcopy ofr13bytes (capped atebx, required>= 4) into[rdi+0x88]; it never reachesExAllocatePool2. - Reachability: The path is on the SMB-over-QUIC receive-indication callback (
SmbQuic*), which requires a negotiated SMB-over-QUIC transport. It is not the TCP/445 receive path.
6. Impact Assessment
No memory-corruption, out-of-bounds, or code-execution primitive is demonstrable in either build: - The allocation size on the transform path derives from a bounds-checked message-length field, and that path is unchanged between builds. - The fall-through path performs a length-bounded copy into an existing buffer. - The only behavioral delta is the recognition of an additional, well-formed transform-header magic, and only when a WIL feature flag is enabled.
There is no verifiable evidence for pool grooming, MDL write primitives, control-flow hijack, token theft, or any bypass of KASLR/SMEP/SMAP/HVCI/CFG. Any such claim would be speculative and is not included.
7. Analyst Notes
For anyone inspecting this on the SMB-over-QUIC receive path:
- SmbQuicReceiveEvent (0x140050EA4 unpatched / 0x140050F54 patched): the indication parser that reads the 4-byte transform magic and dispatches on it.
- SmbQuicIsIndicationTransformedMessage (0x140050C80, patched only): the new magic-recognition helper; its return value gates the branch to the transform handler.
- Feature_Servicing_SmbCompressionOverQuicFix__private_IsEnabledDeviceUsageNoInline (0x14004F73C, patched): the WIL feature-state check that determines whether 0x424d53fc is accepted. This flag governs whether the new behavior is active at all.
- Transform handler entry loc_140051371 (0x14005137E = ExAllocatePool2): unchanged between builds; reached only on a magic match.
8. Changed Functions — Full Triage
SmbQuicReceiveEvent(unpatched0x140050EA4→ patched0x140050F54, Change Type: feature staging, not security-relevant)- Key Change: The inline 4-byte read plus single hardcoded comparison against
0x424d53fdwas extracted into the new helperSmbQuicIsIndicationTransformedMessage, which additionally recognizes the compressed transform magic0x424d53fcwhen the WIL feature flagFeature_Servicing_SmbCompressionOverQuicFixis enabled. - Behavioral Note: With the feature flag off (default), the behavior is identical to the unpatched build.
SmbQuicIsIndicationTransformedMessage(0x140050C80, added): the new helper described above.- WIL stubs (
Feature_Servicing_SmbCompressionOverQuicFix__private_IsEnabledDeviceUsageNoInline/__private_IsEnabledFallback): auto-generated feature-state accessors.
9. Independent Diff Confirmation
An independent, content-based comparison of the two builds (matching functions by name across relocations and comparing instruction sequences) confirms exactly one behavior-affecting change: SmbQuicReceiveEvent, together with the newly emitted helper SmbQuicIsIndicationTransformedMessage and its WIL feature-flag stubs. All other functions differ only in relocated addresses/data references (layout shift), with identical instruction structure. No additional security-relevant change was found that this report omits.
10. Confidence & Caveats
- Confidence Level: High that this is SMB-over-QUIC compression-header recognition staged behind a WIL feature flag, and that no security-relevant behavior is delivered by default.
- Basis: Function symbols (
SmbQuicReceiveEvent,SmbQuicIsIndicationTransformedMessage,SmbQuicCopyIndicationToBufferEx), the WIL feature-state stub structure, the feature-gated acceptance of0x424d53fc, and the byte-for-byte identical transform/allocation path in both builds. - Caveat: If the feature flag is force-enabled, the patched build routes compressed transform headers to the existing transform handler; this changes which messages are processed as transformed but does not, on the evidence here, introduce a memory-safety primitive.