Defender Scan Pipeline — Stage 8

Script Deobfuscation

NScript: Multi-pass fixed-point iteration across 4 scripting languages

4Languages
0Transforms
32Max Passes
0Lines of Logic

NScript:ForceTypePS @ 0x10A7813C • NScript:ForceTypeVBS @ 0x10A781C8 • mpengine.dll

The Four Language Engines

PowerShell 394 transforms • 22,856 lines
"PowerShell_" @ 0x109C6794 "NScript:ForceTypePS" @ 0x10A7813C "MpIsPowerShellAMSIScan" @ 0x10A783A8
JScript 359 transforms • 20,671 lines
"JScript" @ 0x109C6760 "NScript:ForceTypeJS" @ 0x10A781F8 "NScript:JSEnableEmulation" @ 0x10A783C0
VBScript 340 transforms • 17,869 lines
"VBScript" @ 0x109C6778 "NScript:ForceTypeVBS" @ 0x10A781C8
Batch 265 transforms • 13,908 lines
"NScript:ForceTypeBAT" @ 0x10A78168 // + Python support: "NScript:ForceTypePY" @ 0x10A783F4

Multi-Pass Fixed-Point Iteration

Keep deobfuscating until no more changes occur (or 32 passes)

Pass 1: Base64 decode, alias resolution
↓ scan intermediate ↓
Pass 2: String concat, replace operations
↓ scan intermediate ↓
Pass 3: Variable substitution, IEX unwrap
↓ hash unchanged = fixed point ↓
DONE: Normalized script output
// Fixed-point algorithm for pass in 0..32 { prev_hash = crc32(script); script = apply_transforms( script, language); // Scan each intermediate form scan_intermediate(script); // - Static sigs (Stage 3) // - BRUTE match (Stage 9) // - Lua scripts (Stage 10) if crc32(script) == prev_hash { break; // fixed point } } // Queue final normalized form // "NScript:ForceQueueNormalizedVFO" // @ 0x10A78630 vfo_add_buffer(normalized);

PowerShell Deobfuscation

The largest engine: 22,856 lines handling 15+ obfuscation categories

Common Transform Patterns

// Base64 Encoded Command IN: powershell -enc SQBuAHYAbwBr... OUT: Invoke-Expression "hello" // Format String (-f operator) IN: '{2}{0}{1}' -f 'oke-','Expr','Inv' OUT: 'Invoke-Expression' // Character Array IN: [char[]]@(73,110,118) -join '' OUT: 'Inv' // Backtick Removal IN: I`nv`o`ke-E`xp`ression OUT: Invoke-Expression // Alias Resolution IN: iex (gc C:\payload.txt) OUT: Invoke-Expression (Get-Content ...)

Also Handles

String concatenation folding ('hel'+'lo')
Replace() chain evaluation
DeflateStream decompression
SecureString decryption
Environment variable expansion
IEX / Invoke-Expression unwrapping
MpIsPowerShellAMSIScan @ 0x10A783A8 AMSI provides pre-parsed AST with runtime variable values

VBScript & JScript Engines

VBScript (17,869 lines)

// Chr() concatenation IN: Execute(Chr(73) & Chr(110) & Chr(118)) OUT: Execute("Inv") // StrReverse IN: Execute(StrReverse("ekovnI")) OUT: Execute("Invoke") // Hex literals IN: x = &H49 & &H6E & &H76 OUT: x = "Inv"
Replace, Mid/Left/Right, Split/Join, WScript.Shell extraction

JScript (20,671 lines)

// String.fromCharCode IN: eval(String.fromCharCode(73,110,118)) OUT: eval("Inv") // Hex/Unicode escapes IN: eval("\x49\x6e\x76\x6f\x6b\x65") OUT: eval("Invoke") // JScript.Encode decoding IN: #@~^AAAA==...^#~@ OUT: (decoded plain JScript)
eval, unescape, Array.join, ActiveXObject tracking
NScript:JSEnableEmulation @ 0x10A783C0 Lightweight JS interpreter for sandboxed execution

Batch Engine & Force Type Controls

Batch Deobfuscation (13,908 lines)

// Caret escape removal IN: s^e^t x=h^e^l^l^o OUT: set x=hello // Variable substring extraction IN: set x=abcdefg && echo %x:~2,3% OUT: echo cde // Variable substitution IN: echo %x:world=earth% OUT: echo hello earth // Delayed expansion IN: cmd /v:on /c "set x=hi & echo !x!" OUT: echo hi // Environment variable expansion IN: %COMSPEC% /c echo test OUT: C:\Windows\...\cmd.exe /c echo test

NScript:ForceType* Controls

ForceTypePS @ 0x10A7813C
ForceTypeVBS @ 0x10A781C8
ForceTypeJS @ 0x10A781F8
ForceTypeBAT @ 0x10A78168
ForceTypePY @ 0x10A783F4
ForceTypeIRC @ 0x10A78198
SkipTypeID @ 0x10A78388
NoParsingLimits @ 0x10A78370

JScript Feature Extraction

20+ structural features extracted and evaluated by the SigTree ML decision tree ensemble (SS14) to produce !ml and !MTB detections

js_hasBigString @ 0x109324B4 — Long encoded payloads
js_hasSelfModification @ 0x109324CC — eval()-based codegen
js_triggersNormalization @ 0x109324EC — Needs deobfuscation
js_hasStringFuncs @ 0x10932510 — String manipulation
js_manySmallComments @ 0x109323B0 — Comment obfuscation
js_75percentOfFileComments @ 0x10932490 — Stego in comments
js_75percentOfFileSpaceRuns @ 0x10A786AC — Whitespace encoding
js_manyIdenticalLengthComments @ 0x10A787E4 — Stego pattern

What These Detect

Encoded Payloads Very long strings = Base64 or hex-encoded malware payloads
Comment Steganography Identical-length comments hide encoded data in comment blocks
Whitespace Encoding Executable code hidden in whitespace patterns (space/tab encoding)
Self-Modification eval()/Function() generating code at runtime to evade static scan

Each Layer Is Scanned

Every intermediate deobfuscation result goes through multiple detection engines

Obfuscated Input
Pass 1 Output
Static Sigs
+
BRUTE
+
Lua
Pass 2...
Fixed Point
Static Cascade All 11 static engines scan each intermediate form
NSCRIPT_BRUTE @ 0x10986AB0 — Raw pattern matching on deobfuscated text
Lua Scripts GetNormalizedScript() @ 0x1097F1E4 for custom analysis

AMSI Integration

Real-time script content from the OS Antimalware Scan Interface

AMSI Providers

PowerShell Primary AMSI source. Pre-parsed AST with runtime variables
VBScript/JScript Via Windows Script Host integration
.NET Runtime Assembly.Load() buffer scanning
VBA Macros Office macro content via AMSI

AMSI Advantages

Runtime Context Variable values resolved by the language runtime
Pre-Parsed AST PowerShell provides the abstract syntax tree directly
Process Context Knows which process submitted the content
"MpIsPowerShellAMSIScan" @ 0x10A783A8 "MpMaxScriptParseLength" @ 0x1097E8BC (UTF-16) "MpMinScriptNormalization" @ 0x1097E6D8 (UTF-16)

Script Signature Types

Dedicated signature types for NScript content

NSCRIPT_BRUTE @ 0x10986AB0

BRUTE matching specifically on deobfuscated script text

NSCRIPT_SP @ 0x10986328

NScript signature pack for script-specific patterns

NSCRIPT_CURE @ 0x10986F5C

Remediation signatures for cleaning detected scripts

Feature Extraction for BRUTE

"BRUTE:VBS:Feature:" @ 0x10A54D08 "BRUTE:JS:Feature:" @ 0x10A54D1C "BRUTE:PDF:Feature:" @ 0x10A54CC8

Lua API Access

GetNormalizedScript @ 0x1097F1E4 // Lua scripts analyze deobfuscated text // mp.GetNormalizedScript()

Script Deobfuscation: Summary

22,856PowerShell Lines
20,671JScript Lines
17,869VBScript Lines
13,908Batch Lines
0Total Transforms
32Max Passes
20+JS Features
6Language Types
Dynamic Deobfuscation pwsh + node interpreters with 30-second timeouts for execution-based deobfuscation
Crypto Support AES-128/256-CBC with PKCS7 padding for encrypted payload deobfuscation
Size Gate: 1 MB Scripts > 1MB skip deobfuscation. MpMaxScriptParseLength configurable via DBVAR

PS:394 + VBS:340 + JS:359 + Batch:265 = 1,358 transforms • 75,304 lines • mpengine.dll