Pipeline Stage 10

Lua Script Execution Engine

59,415 programmable detection scripts powered by Lua 5.1

0Lua Scripts
0mp.* API Functions
0MpCommon.* Functions
5.1Lua Version

From reverse engineering mpengine.dll — "Lua 5.1" @ 0x1098C124

Why Embedded Lua?

When byte-pattern signatures are not enough, Lua provides full programmability

Lua scripts can implement multi-step decision trees, cross-reference attributes from all prior stages, parse file structures programmatically, and apply heuristic scoring — all delivered via VDM updates without engine binary changes.

The Lua 5.1 runtime is compiled directly into mpengine.dll (not a separate DLL). Each script runs in an isolated lua_State with strict resource limits.

-- Example: Check PE entropy + imports + signing local pe = mp.getpeheader() if pe and pe.entropy > 7.5 then if not mp.issignedfile() then mp.setattribute("HighEntropyUnsigned") end end

Script Capabilities

File I/ORead raw bytes, check size, get filename
PE AnalysisSections, imports, headers, entropy
SignaturesVerify digital signatures, check trust
AttributesGet/set scan attributes for AAGGREGATOR
DetectionFire threats, set lowfi markers, create VFOs
JSON/CryptoParse JSON, regex, hash computation

LuaRunner Architecture

Each script gets an isolated Lua 5.1 state with registered engine APIs

// LuaRunner per-script execution context Registry Keys (in lua_State): LuaRunnerPanicsRegistryName @ 0x10B6B414 LuaRunnerScriptNameRegistryName @ 0x10B6B430 LuaRunnerInstructionsCountRegistryName @ 0x10B6B478 Instruction Limit: SetLuaInstrLimit @ 0x10B6B4D0 "exceeded the limit." @ 0x10B6B3EC ETW Trace: Engine.Scan.LuaExecute @ 0x10A33930
Lua 5.1 State Isolated lua_State* per script. Lightweight (~40KB RAM).
mp.* API (106 functions) Registered into global table. Bridge to engine internals.
MpCommonLua Library "MpCommonLua" @ 0x10B6E2CC — 14 higher-level functions.
Resource Limits 12 configurable limits: instructions, memory, I/O, VFOs, JSON.
Panic Handler "LuaRunnerPanicsRegistryName" @ 0x10B6B414 — crash recovery.

CLuaStandaloneLibrary Templates

9+ C++ template instantiations provide native functions to Lua scripts

LsaMpCommonLib @ 0x10C781D8 — MpCommon API access
LsaVersioning @ 0x10C78294 — Version info access
LsaSysIoLib @ 0x10C78490 — System I/O operations
LsaCrypto @ 0x10C784E0 — Cryptographic ops
LuaHipsLib @ 0x10C887A0 — Host Intrusion Prevention
LsaMpDetectionLib @ 0x10C92478 — Detection management
CLsaFfrLib @ 0x10C926AC — File/folder remediation
CLsaRemediationLib @ 0x10C926FC — Remediation actions
LsaImageConfig @ 0x10C9275C — Image configuration

All RTTI type descriptors extracted from .data section

Sandbox & Resource Limits

Every resource a Lua script can consume is hard-limited and configurable via DBVAR

InstructionsSetLuaInstrLimit
@ 0x10B6B4D0
Buffer SizeMpLuaMaxBufferSize
@ 0x10B4B768
File ReadsMpLuaMaxFileReadTotalSize
@ 0x10B4B734
AttributesMpLuaMaxAttributesCount
@ 0x10B4B704
VFO CountMpLuaMaxVfoCount
@ 0x10B4B7E4
Table SizeMpLuaMaxTableElements
@ 0x10B4B898

JSON Parsing Limits

MpLuaJsonMaxNestingDepth @ 0x10B6B230 MpLuaJsonMaxDataSize @ 0x10B6B264 MpLuaJsonMaxElementsPerLevel @ 0x10B6B290

Performance Thresholds

MpExpensiveSignatureThresholdLua @ 0x10B4B688 MpExpensiveSignatureThresholdIoBytesLua @ 0x10B4B5E0 MpExpensiveSignatureThresholdTotalTimeLua @ 0x10B4B630

Scripts exceeding thresholds are flagged for performance telemetry, enabling Microsoft to optimize slow scripts in VDM updates.

The mp.* API Surface

~106 functions bridging Lua scripts to mpengine.dll internals

File I/O (~12) mp.readfile()
mp.getfilesize()
mp.getfilename()
PE Analysis (~15) mp.getpesection()
mp.getpeheader()
mp.getimports()
Attributes (~8) mp.setattribute()
mp.getattribute()
mp.hasattribute()
Hashing (~6) mp.gethash()
mp.getsha256()
mp.getmd5()
Signatures (~8) mp.issignedfile()
mp.isknownfriendly()
mp.checkcert()
Detection (~8) mp.fire()
mp.setlowfi()
mp.adddetection()
VFO (~8) mp.createvfo()
mp.writevfo()
mp.closevfo()
Bitwise (~6) mp.bitor()
mp.bitand()
mp.bitxor()
// Error strings confirm API existence: "mp.readfile(): MpLuaMaxFileReadTotalSize(%lld) reached" @ 0x10B4C050 "mp.readfile(): MpLuaMaxBufferSize(%lld) reached" @ 0x10B4C088 "Lua IsSignedFile(%ls, CheckTrust: %ls, ...)" @ 0x10B4CEA0 "Lua IsKnownFriendly(%ls, UseCache: %ls, ...)" @ 0x10B4D9A8

MpCommon.* Library

"MpCommonLua" @ 0x10B6E2CC — 14 higher-level functions for advanced operations

Key Functions

BinaryRegExpSearch Binary regex pattern matching over raw file bytes
ReportFilelessResource Report memory/UEFI/BITSjob fileless attack resources
AddBlockingFirewallRule Add Windows Firewall rules for remediation
GetIisInstallPaths Enumerate IIS installation paths for web shell detection
// Error strings from MpCommon.ReportFilelessResource: "...GetResourceBuffer() failed" @ 0x10B6DD3C "...CreateTrackingId() failed" @ 0x10B6DD7C "...no global callback" @ 0x10B6DDD8 "...only bitsjob and uefi based" @ 0x10B6E268

Fileless Detection

Lua scripts can detect and report threats found in:

Process Memory
UEFI Firmware
BITS Transfer Jobs

LsaMpCommonLib.EnumerateFirmwareEnvironmentVariables @ 0x10B6E0B0

BM Lua: Behavioral Monitoring

Separate Lua execution path for real-time behavioral event analysis

Real-time BM Event
(process create, file write, registry mod)
BMLua Dispatch
"BMLua" @ 0x10A35A10
BM Lua Script Execution
matched via sigattr
Engine.Det.BMLuaSigattr
@ 0x10A49468

BM Lua Strings

"BMLua" @ 0x10A35A10 "Engine.Det.BMLuaSigattr" @ 0x10A49468 "!#AsimovBMLuaCall_" @ 0x10A49480 "LuaCallSigattrBM" @ 0x10A494B0 "ERROR: BM Lua calling a SCAN_REPLY dependent API" @ 0x10B4BCBB "HIPS Lua function type %d should not return a path" @ 0x10A4A144

BM Lua scripts cannot call SCAN_REPLY dependent APIs — they operate in a restricted execution context.

Execution Flow

How a Lua script is loaded, executed, and its results collected

fn LuaExecute(ctx: &ScanContext) { // ETW: "Engine.Scan.LuaExecute" @ 0x10A33930 let scripts = get_triggered_scripts(ctx); for script in scripts { let L = luaL_newstate(); // Register panic handler ("LuaRunnerPanicsRegistryName") set_registry(L, "panics", panic_handler); // Set instruction limit ("SetLuaInstrLimit" @ 0x10B6B4D0) set_instr_limit(L, ctx.limit); // Register 106 mp.* API functions register_mp_api(L, ctx); // Load MpCommon ("MpCommonLua" @ 0x10B6E2CC) load_mpcommon(L); // Execute script match lua_pcall(L) { Ok(()) => collect_results(L, ctx), Err(e) => trace("Engine.Lua.ScriptError", e), // @ 0x10B4B8C8 } lua_close(L); } }

Stage 10 Outputs

What Lua scripts produce and where it flows next

Attributes

mp.setattribute()

Stage 11 AAGGREGATOR

Detections

mp.fire()

Stage 13 Verdict

Lowfi Markers

mp.setlowfi()

Stage 12 MAPS Cloud

VFOs

mp.createvfo()

Recursive Stage 2-13
Stage 9 BRUTE
Stage 10 LUA
Stage 11 AAGG
Stage 12 MAPS
Verdict

Key Takeaways

Programmable Detection

59,415 Lua scripts provide detection logic too complex for byte-pattern signatures. Scripts are delivered via VDM updates.

Sandboxed Execution

12 configurable resource limits prevent runaway scripts. Instruction counting via debug hooks. Custom allocator for memory control.

Rich API Surface

106 mp.* functions + 14 MpCommon.* functions cover file I/O, PE analysis, crypto, signatures, detection, and remediation.

Multi-Path Output

Scripts produce attributes (Stage 11), direct detections (Stage 13), lowfi markers (Stage 12 cloud), and VFOs (recursive scan).

All data from reverse engineering mpengine.dll v1.1.24120.x