Pipeline Stage 4

AAGGREGATOR
Attribute Collection

How engines deposit attributes for boolean evaluation

0PE Attributes (pea_*)
8API Functions
5Format Collections
2AAGG Sig Types

SIGNATURE_TYPE_AAGGREGATOR @ 0x10986B3C — SIGNATURE_TYPE_AAGGREGATOREX @ 0x10986E28

What Are Attributes?

Attributes are string-valued facts accumulated into a HashSet<String> on the ScanContext throughout the entire pipeline.

Key Insight

Stage 4 is not a single step — it is a continuous process that runs across all stages. Every engine deposits attributes as it fires. The attribute set only grows; it is never cleared during a file scan.

At the end (Stage 11), the AAGGREGATOR evaluates boolean expressions over the complete attribute set to produce compound detections.

// Attribute set on ScanContext struct ScanContext { attributes: HashSet<String>, namedattributes: HashMap<String, String>, sigattrevents: Vec<SigAttrEvent>, }

Attribute API Functions

set_mpattribute@ 0x1097EC28
set_mpattributeex@ 0x1097EC38
get_mpattribute@ 0x1097EBC8
get_mpattributevalue@ 0x1097EBD8
get_mpattributesubstring@ 0x1097EBF0
aggregate_mpattribute@ 0x1097EC60
clear_mpattribute@ 0x1097EC4C

Attribute Producers

Every major scan stage deposits attributes into the shared set

03 Static Engines PEHSTR → HSTR:Win32/xxx  |  KCRCE, NID, BM_STATIC → pattern attributes
04 PE Analysis 302 pea_* attributes: pea_packed, pea_isdll, pea_epscn_writable, ...
05 PE Emulation FOP:xxx opcode traces  |  TUNNEL:xxx patterns  |  THREAD:xxx behavior
09 BRUTE BRUTE:PDF:Feature:xxx polymorphic pattern attributes
10 Lua Scripts mp.set_mpattribute() / mp.set_mpattributeex() — arbitrary named attributes
* Infrastructure !-prefixed threat names: collected as attributes, never standalone detections

PE Attributes: 302 pea_* Flags

Structural properties extracted from PE header analysis, before emulation begins

Section Properties

pea_packed @ 0x10A10B1C pea_epscn_writable @ 0x10A10A30 pea_lastscn_writable @ 0x10A109EC pea_epscn_falign @ 0x10A10A1C pea_lastscn_falign @ 0x10A109D8 pea_epscn_islast @ 0x10A10A68 pea_secmissize @ 0x10A10B28 pea_secmisaligned @ 0x10A10B38 pea_firstsectwritable @ 0x10A10B04

Entry Point

pea_entrybyte55 @ 0x10A10BE0 ; push ebp pea_entrybyte90 @ 0x10A10BF0 ; nop pea_entrybyte60 @ 0x10A10C00 ; pushad pea_epcallnext @ 0x10A10ACC ; call $+5 pea_epatscnstart @ 0x10A10AB8 pea_epinfirstsect @ 0x10A10B58 pea_epoutofimage @ 0x10A10BD4

File Type

pea_isdll @ 0x10A10B4C pea_isexe @ 0x10A10BD4 pea_isdriver @ 0x10A10C24 pea_isdamaged @ 0x10A10C64 pea_no_relocs @ 0x10A10A44 pea_no_imports @ 0x10A10C34 pea_hasexports @ 0x10A10BAC pea_hasboundimports @ 0x10A10C10 pea_headerchecksum0 @ 0x10A10C50

Behavioral Hints

pea_hasstandardentry @ 0x10A10C74 pea_requires9x @ 0x10A10C8C pea_usesuninitializedregs @ 0x10A10C9C pea_hasappendeddata @ 0x10A10BBC pea_isreported @ 0x10A10CB8 pea_isgeneric @ 0x10A10CC8

Infrastructure Markers: The ! Prefix

Threat names starting with ! are deposited as attributes but never returned as detections

// Multi-signal detection example // Step 1: Static engine fires attributes.insert("HSTR:Win32/Emotet.A!dha"); // Step 2: PE analysis fires attributes.insert("pea_packed"); attributes.insert("pea_epscn_writable"); // Step 3: Emulation fires an infra marker // Deposited as attribute, NOT as a detection! attributes.insert("!InfraOnly:Trojan:Win32/DynUnpack"); // Step 4: AAGGREGATOR evaluates (Stage 11) // Rule: "HSTR:Win32/Emotet.A!dha // & pea_packed // & !InfraOnly:Trojan:Win32/DynUnpack" // // ALL present ==> detection fires: // "Trojan:Win32/Emotet.RPX!MTB"

Why Infrastructure?

Infrastructure markers let Defender build compound detections that require evidence from multiple engines.

A single !-prefixed match is never enough for a detection. It must be combined with other attributes via AAGGREGATOR boolean expressions.

! Prefix means "infrastructure only"
& Combined via boolean AND/OR/NOT

Format-Specific Attribute Collections

Separate attribute namespaces for each binary format

peattributes PE analysis flags @ 0x1097DC7C
elfattributes ELF analysis flags @ 0x109E2378
machoattributes Mach-O analysis flags @ 0x109E25F4
namedattributes Engine-set named attrs @ 0x109E2690
variableattributes Runtime-computed values @ 0x109EC714
attributelist Master attribute index @ 0x109E03C4

Signature Attribute Log (sigattr)

Chronological record of attribute deposit events — head (first N) and tail (last N)

// sigattr log structure "sigattr_head" @ 0x1097D710 "sigattr_tail" @ 0x1097D720 "this_sigattrlog" @ 0x1097D74C "get_sigattr_event_count" @ 0x1097F37C "sigattrevents" @ 0x109E27B0 // Post-emulation log access "get_postemu_sigattr_log_head" @ 0x10981A28 "get_postemu_sigattr_log_head_size" @ 0x10981A04 "get_postemu_sigattr_log_tail" @ 0x10981A6C "get_postemu_sigattr_log_tail_size" @ 0x10981A48

Error Strings

"sigattrlog: head is empty" @ 0x10B4F7C8 "sigattrlog: tail is empty" @ 0x10B4F774 "Invalid index in sigattr log: %d" @ 0x10B4F6F8 "Invalid index (0) in sigattr log" @ 0x10B4F7E4 "sigattrlog not available" @ 0x10B4F808 "this_sigattrlog not available" @ 0x10B4F71C "Invalid sigattr_head index" @ 0x10B5214C
9 Error handling paths in sigattr subsystem

Lua Attribute API

59,415 Lua scripts can read and write attributes via the mp.* API

Write Operations

-- Set boolean attribute mp.set_mpattribute("my_indicator") -- Set key=value attribute mp.set_mpattributeex("entropy", "7.92") -- Bulk deposit from detection mp.aggregate_mpattribute(result)

Read Operations

-- Check existence local packed = mp.get_mpattribute("pea_packed") -- Get value local val = mp.get_mpattributevalue("entropy") -- Substring search local m = mp.get_mpattributesubstring("HSTR:") -- Enumerate matching mp.enum_mpattributesubstring("pea_", function(attr) -- callback for each match end)

Error Handling

// aggregate errors "lua_mp_aggregateattribute failed to get max MP attributes total size DC" @ 0x10B4BD60 "lua_mp_aggregateattribute failed to get max MP attributes count DC" @ 0x10B4BDA8 // sigattr alias errors "this_sigattrlog[\"alias\"].%s failed with 0x%x!" @ 0x10B4F558 "...only available in BM sigattr or invalid field name!" @ 0x10B4F588
Lowfi Suppression "Supressed lowfi per named attribute" @ 0x10A53FE8

Attribute Flow: Producers → Consumers

From engine deposits to AAGGREGATOR evaluation

Static (HSTR:)
PE Analysis (pea_*)
Emulation (FOP:/TUNNEL:)
BRUTE (BRUTE:)
Lua (custom)
Infra (!prefix)
HashSet<String> — Attribute Set Monotonically growing, never cleared during scan
AAGGREGATOR Stage 11: Boolean eval
Lua Scripts Stage 10: Read attrs
MAPS Cloud Stage 12: Serialize

Serialization & Cloud Delivery

Attributes are serialized for internal logging and MAPS cloud queries

Serialization Format Strings

"MpInternal_sigattrevents=" @ 0x10B76A58 "sigattrevents=" @ 0x10A545FC "namedattributes=" @ 0x10A54580 "machoattributes=%s" @ 0x10A54448 "elfattributes=" @ 0x10A2EC9C "machoattributes=" @ 0x10A2DA08

Log Files

attributes.log @ 0x109C5F88 (UTF-16)
attributes-%d.log @ 0x109C5F64 (UTF-16)
lowfis.log @ 0x109C5F4C (UTF-16)
lowfis-%d.log @ 0x109C5F30 (UTF-16)

Stage 4 Summary

0pea_* Attributes
8API Functions
5Format Collections
2AAGG Sig Types
6+Attribute Prefixes
9Sigattr Error Paths
0Lua Scripts (consumers)
0Signature Types

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

← Stage 3 Static Engine Cascade
Stage 5 → PE Emulation
Stage 11 → AAGGREGATOR Evaluation