Stage 01 — Reverse Engineering Deep Dive

Entry Point & Command Dispatch

How scan requests enter mpengine.dll

0DLL Exports
2Dispatchers
0Command Codes
5Global State Vars

From RE of mpengine.dll v1.1.24120.x

What This Stage Does

Every scan request — real-time protection, scheduled scan, AMSI, or command-line — enters through one of two dispatcher exports.

The dispatcher validates engine state, selects a handler based on a command code integer, and routes to the appropriate scan pipeline entry.

Three commands get fast-path treatment in __rsignal: BOOT (0x4003), SCAN (0x400B), and AMSI (0x4019). All others go through a secondary switch table.

A distinctive self-pointer sentinel pattern guards against use-before-init: the global context pointer initially points to its own address.

rsignalOuter dispatcher
__rsignalInner dispatcher
MpBootStrapEngine init
GetSigFilesVDM enumeration

Export Table — Key Entries

90 total exports. These are the ones relevant to scan pipeline entry.

83 __rsignal 0x10133CD0 — Inner command router, fast-path for BOOT/SCAN/AMSI
88 rsignal 0x102BF000 — Outer dispatcher, handles init check + delegates to __rsignal
69 MpBootStrap 0x102BD660 — Engine init: load VDM signatures, allocate context
68 GetSigFiles 0x102BEE10 — Enumerate VDM signature database files
77 MpContainerOpen 0x102BCF00 — Open archive/container for child extraction
70 MpContainerAnalyze 0x102BCB80 — Scan container contents recursively

Command Code Table

Extracted from the comparison chains in __rsignal and rsignal disassembly

Fast-Path Commands (__rsignal)

0x4003 BOOT_ENGINE // Init + load sigs 0x400B SCAN_BUFFER // Primary scan 0x4019 SCAN_AMSI // Script content

Extended Commands (rsignal)

0x4004 UNLOAD_ENGINE // Teardown 0x400A SHUTDOWN // Full shutdown 0x4036 SCAN_FILE // File scan (new) 0x4052 SCAN_DISPATCH // Direct dispatch 0x4059 SCAN_EXTENDED // Extra params 0x4069 SCAN_ASYNC // Async submit 0x4074 SCAN_NETWORK // Network scan 0x4075 SCAN_NOTIFY // Notification 0x4090 SCAN_RUNTIME // BM runtime

Dispatch Logic

; rsignal comparison chain ; @ 0x102BF05A mov eax, 0x4059 cmp esi, eax jg check_higher je dispatch_common mov eax, esi sub eax, 0x4004 ; UNLOAD? je dispatch_common sub eax, 0x32 ; +0x32=SCAN_FILE je dispatch_common sub eax, 0x1C ; +0x1C=SCAN_DISPATCH je boot_first
Subtraction Chain Each sub tests a new command code without resetting eax

__rsignal Disassembly

The inner dispatcher at 0x10133CD0

; __rsignal @ 0x10133CD0 push ebp mov ebp, esp and esp, 0xFFFFFFF8 ; 8-byte align mov eax, [ebp+0xC] ; eax = cmd code cmp eax, 0x4003 ; BOOT_ENGINE? je handler_common cmp eax, 0x400B ; SCAN_BUFFER? je handler_common cmp eax, 0x4019 ; SCAN_AMSI? je handler_common ; non-fast-path: delegate push [ebp+0x14] call 0x10133D35 ; sub_dispatch jmp epilogue handler_common: mov ecx, [0x10C707B0] ; g_engine_ctx cmp ecx, 0x10C707B0 ; sentinel? je return_error test byte [ecx+0x1C], 1 ; ENGINE_READY? je return_error ; ... dispatch to handler ... return_error: mov eax, 0x800E ; INVALID_STATE ret

Key Observations

Stack Alignment
8-byte align for SSE in scan routines
Sentinel Pattern
Self-pointer at 0x10C707B0 means "not init"
Fast-Path
3 commands skip the full switch table
Error Code
0x800E = engine not ready

Global State Variables

0x10C707B0 g_engine_context Pointer to ENGINE_CONTEXT. Self-pointer when uninitialized (sentinel pattern).
0x10CA5654 g_engine_initialized Byte flag. Set to 1 after BOOT_ENGINE completes successfully.
0x10CA564C g_boot_attempted Byte flag. Set to 1 on first boot attempt. Prevents double-init.
0x10CA5650 g_engine_handle Opaque engine handle. Cleared to 0 on SHUTDOWN (cmd 0x400A).
0x10C6F880 g_stack_cookie Stack canary value (observed: 0xBB40E64E). Protects sub_dispatch frame.
+0x1C engine->flags Bit 0 = ENGINE_READY, Bit 3 = LOGGING_ENABLED. Checked at every dispatch.

Self-Pointer Sentinel Pattern

A distinctive initialization guard found throughout the engine

// Before MpBootStrap: // [0x10C707B0] == 0x10C707B0 (points to self) // This means: "not initialized" mov ecx, [0x10C707B0] ; load ptr cmp ecx, 0x10C707B0 ; self? je not_initialized // After MpBootStrap succeeds: // [0x10C707B0] == 0x0B1234A0 (heap alloc) // Now the sentinel check passes test byte [ecx+0x1C], 1 ; flags check je not_ready
Before Boot
[0x10C707B0] → 0x10C707B0
Self-pointer = uninitialized
MpBootStrap @ 0x102BD660
Load VDM, alloc context, set flags
After Boot
[0x10C707B0] → heap_alloc
Real context = operational

rsignal Dispatch Flow

Full path from caller to pipeline entry

Caller
rsignal
0x102BF000
Init Check
0x10CA5654
__rsignal
0x10133CD0
Cmd Check
cmp eax, 0x40xx
Context Valid?
0x10C707B0
Flags OK?
[ecx+0x1C] & 1
Handler
0x800EReturned if context invalid
0x8001Returned for SCAN_DISPATCH fail
0x0000Success / scan initiated

MpBootStrap — Engine Initialization

Called once at service startup to load VDM signatures and allocate the engine context

; MpBootStrap @ 0x102BD660 push 0x0C ; SEH frame mov eax, 0x108D60DF ; SEH handler call 0x10268FD1 ; __SEH_prolog mov edx, [ebp+0xC] ; output ptr mov ecx, [ebp+0x8] ; config ptr call 0x10322CAA ; inner_bootstrap mov esi, eax ; HRESULT test esi, esi jns success ; Failure: log via engine context mov eax, [0x10C707B0] ; g_engine_ctx cmp eax, 0x10C707B0 ; sentinel? je skip_log test byte [eax+0x1C], 1 je skip_log push esi ; error code mov edx, 0x109C35F8 ; format str

Boot Sequence

1. Set up SEH frame (handler @ 0x108D60DF)
2. Call inner_bootstrap @ 0x10322CAA
3. Load VDM files, parse TLV records
4. Compile sig database into lookup structures
5. Allocate ENGINE_CONTEXT, write to 0x10C707B0
6. Set g_initialized = 1 (@ 0x10CA5654)

ETW Trace Events

Strings embedded in the binary for event tracing

5710 Engine.Scan.AsyncStats 0x109C3D94
5909 Engine.Scan.Unpacker 0x109C6068
7465 Engine.Scan.QuickScanStarted 0x109D4BE0
7468 Engine.Scan.QuickScanEnded 0x109D4C14
7470 Engine.Scan.FullScanStarted 0x109D4C38
7480 Engine.Scan.ScanAborted 0x109D4CF4
14678 Engine.Scan.FileScan 0x10A33C0C

Stage 01 Summary

Two-Layer Dispatch

rsignal (outer) validates init state and delegates to __rsignal (inner) which routes by command code.

Sentinel Guard

Global context at 0x10C707B0 uses self-pointer as uninitialized sentinel. Checked on every dispatch.

Auto-Boot Path

Certain commands (SCAN_FILE, SCAN_DISPATCH) trigger automatic boot if not yet initialized.

Next: FRIENDLY_FILE

After dispatch selects a scan handler, the first pipeline check is the SHA-256 whitelist (Stage 02).

All addresses from RE of mpengine.dll v1.1.24120.x