Process Hollowing Defense: Memory Hardening Guide
Overview & Defensive Context: Neutralizing In-Memory Process Masquerading#
Harden Windows against Process Hollowing: enforce Arbitrary Code Guard, block unmapped executable memory via Exploit Guard, and audit ETW-Ti events.
In our morning threat architecture analysis, we dissected the mechanics of Process Hollowing (commonly known as RunPE, mapped to MITRE ATT&CK T1055.012: Process Injection: Process Hollowing and T1055: Process Injection). We analyzed how adversaries spawn legitimate, digitally signed operating system executables (such as svchost.exe, explorer.exe, or RuntimeBroker.exe) in a suspended state (CREATE_SUSPENDED), unmap their original image sections via ntdll!NtUnmapViewOfSection, allocate private replacement memory with PAGE_EXECUTE_READWRITE protections via VirtualAllocEx, inject an unpacked payload using WriteProcessMemory, and redirect the primary thread's execution context (SetThreadContext) before resuming execution. Because on-disk file scanners and standard process listings observe legitimate binary paths and valid digital signatures, Process Hollowing effectively blindfolds traditional endpoint defenses while executing unconstrained malicious code within memory.
For defensive architects, threat hunters, and Security Operations Center (SOC) engineers, defending Windows enterprise hosts against Process Hollowing exposes critical limitations in conventional endpoint security:
- The Impotence of Static File Reputation: Traditional signature-based antivirus solutions scan binaries when written to disk or loaded via standard Win32 execution paths. In a Process Hollowing intrusion, the binary on disk is authentic, Microsoft-signed, and completely unmodified. The malicious transformation occurs strictly within volatile RAM after the process object has already been instantiated.
- The Fragility of User-Space Hooking in Legacy EDRs: Earlier generation Endpoint Detection and Response (EDR) solutions relied heavily on user-space API hooking (injecting an EDR DLL into newly created processes to intercept NtUnmapViewOfSection or VirtualAllocEx). However, modern red teams easily bypass user-space hooks using direct system calls (Syswhispers/Hell's Gate) or unhooking ntdll.dll from a clean disk copy, rendering user-space EDR sensors completely ineffective.
- The Architectural Discrepancy Between PEB and VAD: Process Hollowing inherently produces an architectural anomaly within the operating system: the user-space Process Environment Block (PEB) maintains the illusion that the process is running from disk, but the kernel's Virtual Address Descriptor (VAD) tree records the primary executable memory region as private anonymous memory (Vad) without a backing FILE_OBJECT.
- The Multi-Tiered Defensive Blueprint: Completely immunizing enterprise endpoints against Process Hollowing requires defense-in-depth across five operational layers: enforcing Arbitrary Code Guard (ACG) via Windows Exploit Guard to block dynamic code creation, applying strict Process Mitigation Policies (restricting image unmapping and enforcing Microsoft-only signatures), utilizing Microsoft-Windows-Threat-Intelligence (ETW-Ti) kernel telemetry to intercept thread context hijacking, deploying real-time Sysmon Event ID 25 process tampering rules, and establishing rapid volatile memory triage playbooks.
Relying on command-line logging and disk file scanning will never detect Process Hollowing. Enforcing kernel-level process mitigation policies and memory integrity controls is mandatory.
⚔️ Exploitation Mechanics: For root-cause memory corruption analysis and attack flow, see our deep-dive: Deconstructing Breakdown.
Architecture Hardening: Five-Tier Defense-in-Depth Against Process Hollowing#
Preventing and detecting Process Hollowing across enterprise Windows endpoints requires deploying layered security controls across the Windows kernel memory manager, Exploit Guard policy engine, kernel ETW sensors, system monitoring event streams, and rapid memory forensics.
Defensive Architecture Flowchart#
flowchart TD
classDef client fill:#1e293b,stroke:#ef4444,stroke-width:2px,color:#f8fafc
classDef gate fill:#0f172a,stroke:#3b82f6,stroke-width:2px,color:#93c5fd
classDef secure fill:#064e3b,stroke:#10b981,stroke-width:2px,color:#6ee7b7
classDef audit fill:#4c1d95,stroke:#8b5cf6,stroke-width:2px,color:#ddd6fe
classDef drop fill:#450a0a,stroke:#dc2626,stroke-width:2px,color:#fca5a5
classDef pass fill:#065f46,stroke:#34d399,stroke-width:2px,color:#a7f3d0
Adversary[Adversary Process Spawns Suspended Target: svchost.exe]:::client --> ACGGate{Tier 1: Arbitrary Code Guard: ProhibitDynamicCode}:::gate
ACGGate -- Attacker Calls VirtualAllocEx with PAGE_EXECUTE_READWRITE --> BlockACG[Action: Kernel Returns STATUS_DYNAMIC_CODE_BLOCKED]:::drop
BlockACG --> AlertSIEM1[Generate Critical Exploit Guard Block Event]:::audit
ACGGate -- ACG Not Enforced on Target Binary --> UnmapGate{Tier 2: Code Integrity Guard & Unmap Protection}:::gate
UnmapGate -- Attacker Attempts NtUnmapViewOfSection on ImageBase --> BlockUnmap[Action: Kernel Denies Memory Section Removal]:::drop
BlockUnmap --> AlertSIEM2[Log Section Unmapping Violation in EDR]:::audit
UnmapGate -- Section Successfully Unmapped --> ETWGate{Tier 3: Kernel ETW-Ti Sensor Telemetry}:::gate
ETWGate -- Detects EtwTiLogSetThreadContext Across Process Boundary --> BlockThread[Action: EDR Driver Intercepts & Kills Suspicious Thread]:::drop
BlockThread --> AlertSOC1[Trigger Real-Time Process Injection Alert]:::audit
ETWGate -- Thread Context Hijacked --> SysmonGate{Tier 4: Sysmon Event ID 25 Process Tampering}:::gate
SysmonGate -- Detects Memory Image Replacement in svchost.exe --> AlertSysmon[Action: Emit Sysmon Event ID 25 Image is replaced]:::audit
AlertSysmon --> HostQuarantine[Trigger Automated Host Isolation via SOAR]:::drop
SysmonGate -- Telemetry Ingestion Complete --> ForensicGate{Tier 5: Memory Forensics & YARA Scanning}:::audit
ForensicGate -- Volatility malfind Flags Anonymous RWX MZ Header --> ConfirmBreach[Confirm Hollowing & Extract Injected Binary]:::secure
ForensicGate -- Clean Memory Baseline --> VerifiedOps[Operating System Validated Clean]:::secureTier 1: Arbitrary Code Guard (ACG) & Dynamic Code Prohibitions#
The most decisive preventative control against Process Hollowing is Arbitrary Code Guard (ACG), introduced in Windows 10 and Windows Server 2016. ACG mathematically breaks Stage 3 of the hollowing attack lifecycle by enforcing the W^X (Write XOR Execute) memory model directly within the kernel's virtual memory manager (ntoskrnl.exe). How ACG Prevents Process Hollowing Under standard Windows execution, an application can allocate private memory using VirtualAllocEx with PAGE_EXECUTE_READWRITE (0x40) or modify existing pages via VirtualProtectEx.
When Arbitrary Code Guard is enabled via the ProcessDynamicCodePolicy mitigation:
- No New Executable Memory: The kernel strictly blocks the creation of new executable memory backed by private, anonymous allocations (MEM_PRIVATE). Any call to VirtualAllocEx with PAGE_EXECUTE, PAGE_EXECUTE_READ, or PAGE_EXECUTE_READWRITE fails immediately with STATUS_DYNAMIC_CODE_BLOCKED (0xC0000454).
- No Modifying Existing Executable Memory: The kernel prohibits altering permissions on existing code pages. Calls to VirtualProtectEx attempting to make read-only code pages writable are rejected.
- Strict Image Mapping: Code can only be executed if it is mapped directly from a legitimate file on disk via a mapped image section (SEC_IMAGE).
Because Process Hollowing relies on allocating an unbacked memory block inside the target process to host the unpacked payload, enforcing ACG completely terminates the injection sequence before any malicious code can be written. Enforcing ACG via PowerShell Exploit Guard Administrators can enforce ACG on specific processes using the Set-ProcessMitigation cmdlet:
### 1. Enforce Arbitrary Code Guard on sacrificial host processes
Set-ProcessMitigation -Name svchost.exe -Enable ProhibitDynamicCode
Set-ProcessMitigation -Name dllhost.exe -Enable ProhibitDynamicCode
Set-ProcessMitigation -Name runtimebroker.exe -Enable ProhibitDynamicCode
# 2. Verify active mitigation policies for the target executable
Get-ProcessMitigation -Name svchost.exe | Select-Object -ExpandProperty DynamicCode
ACG cannot be applied globally to applications that utilize Just-In-Time (JIT) compilation (such as web browsers or .NET applications using the CLR), as JIT engines require dynamic code allocation. However, native Windows host binaries (svchost.exe, dllhost.exe, taskhostw.exe) never require dynamic code generation and can be hardened safely.
Tier 2: Microsoft Defender Exploit Guard Process Mitigation Policies#
Enterprise-wide enforcement of process mitigation policies is best achieved via centralized Group Policy Objects (GPOs) leveraging XML policy definitions. Enterprise Exploit Guard XML Configuration Create an XML configuration file (ProcessMitigations.xml) defining strict protections for high-risk system binaries commonly selected as targets for Process Hollowing:
Deploying Exploit Guard Policies via Group Policy#
To deploy this configuration across all domain-joined Windows endpoints:
- Open Group Policy Management Console (GPMC) and edit your default workstation/server baseline policy.
- Navigate to:
- Computer Configuration -> Administrative Templates -> Windows Components -> Windows Defender Exploit Guard -> Exploit Protection
- Enable the setting Use a common set of exploit protection settings.
- Specify the UNC path or local path to your hardened ProcessMitigations.xml file.
- Apply the policy and enforce immediate client refresh using gpupdate /force.
When an attacker attempts to spawn svchost.exe and execute NtUnmapViewOfSection followed by VirtualAllocEx, the Windows kernel blocks the allocation, writes an error event to the Microsoft-Windows-Security-Mitigations event log, and terminates the operation.
Tier 3: Kernel Telemetry & ETW Threat Intelligence (ETW-Ti)#
Modern enterprise EDR platforms (such as Microsoft Defender for Endpoint, SentinelOne, and CrowdStrike Falcon) no longer rely on fragile user-space hooks. Instead, they ingest kernel-level telemetry provided directly by the Windows kernel via the Microsoft-Windows-Threat-Intelligence event provider. The Mechanics of ETW-Ti Injection Detection ETW-Ti operates directly within ntoskrnl.exe. Because it executes in kernel mode (Ring 0), user-space malware cannot tamper with or unhook its telemetry generators.
When Process Hollowing is attempted, the kernel automatically generates two critical telemetry events:
- EtwTiLogSuspendResumeProcess: Fired when a process is spawned in a suspended state and subsequently resumed. The event records the calling process ID, target process ID, and thread IDs.
- EtwTiLogSetThreadContext: Fired when SetThreadContext modifies the execution context of a thread across process boundaries. The kernel captures:
- CallingProcess: The injector malware.
- TargetProcess: The sacrificial host (svchost.exe).
- OldRip / NewRip: The original instruction pointer versus the newly hijacked instruction pointer.
If EtwTiLogSetThreadContext detects that the target thread's new instruction pointer points to an unbacked private memory allocation (Vad rather than VadS), the EDR driver immediately identifies Process Hollowing, intercepts the ResumeThread call, and terminates both the host and the injector process.
Tier 4: Real-Time Detection Engineering: Sysmon and YARA Memory Rules#
Security Operations Centers (SOC) and threat hunting teams can achieve real-time visibility into Process Hollowing by monitoring dedicated Sysmon events and running in-memory YARA scans. Sysmon Event ID 25: Process Tampering Detection Sysmon version 13 introduced Event ID 25 (Process Tampering), engineered specifically to detect image hollowing and process modification techniques:
Configure /etc/sysmon/sysmonconfig.xml to capture all process tampering events:
Image is replaced
0x147A
\svchost.exe
Production Sigma Rule for Process Tampering and Cross-Process Thread Hijacking Deploy the following Sigma rule in your SIEM platform to detect Process Hollowing alerts forwarded from Windows endpoints:
title: Real-Time Process Hollowing and Image Replacement Detection
id: 6a3b9c1d-8e4f-4821-bc30-f92e01b45289
status: stable
description: Identifies process hollowing and image replacement techniques characteristic of MITRE ATT&CK T1055.012 where a trusted binary is hollowed out in memory.
references:
- https://attack.mitre.org/techniques/T1055/012/
- https://learn.microsoft.com/en-us/sysinternals/downloads/sysmon
tags:
- attack.defense_evasion
- attack.privilege_escalation
- attack.t1055.012
- attack.t1055
logsource:
product: windows
service: sysmon
detection:
selection_tampering:
EventID: 25
Type: 'Image is replaced'
selection_suspicious_targets:
Image|endswith:
- '\svchost.exe'
- '\explorer.exe'
- '\dllhost.exe'
- '\RuntimeBroker.exe'
- '\conhost.exe'
- '\taskhostw.exe'
- '\spoolsv.exe'
condition: selection_tampering and selection_suspicious_targets
fields:
- UtcTime
- ProcessId
- Image
- Type
falsepositives:
- None. Legitimate Windows system processes never experience in-memory image replacement during standard operations.
level: critical
YARA In-Memory Detection Rule for Unbacked Executable PEs Deploy the following YARA signature within your live-memory scanning pipeline (such as Velociraptor, Thor, or Microsoft Defender) to detect portable executables executing from private anonymous memory:
rule Memory_Detect_Hollowed_PE_In_Anonymous_VAD {
meta:
description = "Detects MZ and PE headers located within private anonymous memory allocations, indicative of Process Hollowing"
author = "Md Redwan Ahmed (Fast Cyber Defense)"
date = "2026-11-08"
mitre_technique = "T1055.012"
strings:
// Match MZ Header at offset 0
$mz = { 4D 5A }
// Match standard PE Header signature "PE\0\0"
$pe = { 50 45 00 00 }
// Match common DOS stub string
$dos_stub = "This program cannot be run in DOS mode" ascii
condition:
// Condition matches when an executable header is discovered in private memory
$mz at 0 and $pe at (uint32(0x3C)) and $dos_stub
}
Enterprise Mitigation Matrix: Comparing Strategic Controls The following matrix compares the implementation trade-offs, security efficacy, and operational impacts of different remediation strategies against Process Hollowing:
Defensive Layer Mitigation Strategy Implementation Complexity Performance Overhead Application Compatibility Risk Security Effectiveness Arbitrary Code Guard (ACG) Enforce ProhibitDynamicCode on sensitive Windows system binaries Low (PowerShell / GPO) Zero performance impact Medium (Must not be applied to JIT browsers/CLR) Critical (Mathematically Blocks Hollowing) Exploit Guard Policies Restrict child process spawning and enforce Microsoft signatures (CIG) Low to Medium Zero performance impact Low (Well-defined for standard OS binaries) High (Prevents Sacrificial Spawning) Kernel ETW-Ti Ingestion Deploy modern EDR utilizing EtwTiLogSetThreadContext Low (Sensor installation) Negligible (<1% CPU) None (Standard EDR runtime protection) High (Provides Real-Time Threat Interception) Sysmon Event ID 25 Configure Sysmon to alert on process tampering and image replacement Low (XML configuration) Negligible None (Passive event generation) High (Immediate High-Fidelity Alerting) Attack Surface Reduction (ASR) Enforce ASR rules blocking obfuscated scripts and process creation Low (GPO update) Zero performance impact Low (Requires standard baseline auditing) High (Breaks Initial Foothold Stages) Memory Forensics (Volatility 3) Post-incident memory triage using windows.malfind & vadinfo Medium (Dump acquisition) High during acquisition None (Post-incident response action) Maximum (Provides Ground-Truth Evidence) Incident Response & Verification Playbook When security alerts or threat hunting queries indicate potential Process Hollowing (such as a Sysmon Event ID 25 alert or an anomalous EtwTiLogSetThreadContext detection), incident responders must execute the following structured response playbook: Step-by-Step Response Checklist
Phase 1: Immediate Triage and Process Containment#
- Identify the suspicious process ID (PID), executable image path, and parent process ID from the SIEM or EDR alert.
- Isolate the affected endpoint from the corporate network immediately using your EDR network containment feature.
- Do not immediately reboot or power off the machine. Powering down flushes volatile RAM, destroying all unbacked memory artifacts.
- Suspend the suspicious process tree using PowerShell or Sysinternals Process Explorer:
Suspend-Process -Id
Phase 2: Volatile Memory Acquisition#
- Acquire a full raw physical memory dump using a trusted, kernel-based acquisition tool:
- For physical workstations/servers: Deploy WinPmem or AVML.
- For virtualized infrastructure (Hyper-V / VMware / AWS / Azure): Take a hypervisor snapshot or extract the .vmem / OS disk snapshot.
- Document the cryptographic hash (SHA-256) of the memory image immediately upon capture to maintain chain of custody.
Phase 3: Volatility 3 Memory Extraction and Analysis#
- Execute windows.malfind against the target PID to confirm unbacked PAGE_EXECUTE_READWRITE memory allocations:
vol -f memdump.raw windows.malfind --pid
- Run windows.vadinfo to verify the absence of an underlying _FILE_OBJECT and confirm Tag: Vad.
- Dump the injected executable using windows.dumpfiles:
vol -f memdump.raw -o ./artifacts windows.dumpfiles --pid --virtaddr
- Extract strings and command-and-control (C2) domains from the recovered PE binary.
Phase 4: Long-Term Hardening and Verification#
- Verify if the injector malware established persistence on disk (inspect Scheduled Tasks, Run keys, and WMI event consumers).
- Enforce Arbitrary Code Guard (ACG) across all standard system executables via Group Policy.
- Confirm that Sysmon Event ID 25 is actively logging on all enterprise endpoints.
- Execute the post-remediation verification commands below to confirm endpoint immunity before returning the workstation to production service.
Executive Takeaway Table: Threat Vectors, Telemetry Signals, and Primary Mitigations#
The following matrix consolidates the attack mechanisms, defensive telemetry signals, and required engineering controls for securing enterprise Windows environments against Process Hollowing:
Attack Vector / Technique
Primary Exploitation Mechanism
Telemetry & Detection Signal
Recommended Mitigation
Verification Command
Process Hollowing (T1055.012)
NtUnmapViewOfSection followed by VirtualAllocEx and SetThreadContext
Volatility 3: windows.malfind flags private RWX page with MZ header
Deploy Arbitrary Code Guard (ACG); block unmapped dynamic code execution
vol -f mem.raw windows.malfind --pid
Get-ProcessMitigation -Name svchost.exe
Process Tampering (Sysmon ID 25) Malware replaces the memory image of a suspended system binary Sysmon Event ID 25: Type = Image is replaced for critical system binaries Enable Sysmon Event ID 25 logging; forward immediately to SIEM
Get-WinEvent -FilterHashtable @{LogName='Microsoft-Windows-Sysmon/Operational'; Id=25}
Cross-Process Thread Hijack Attacker invokes SetThreadContext to redirect target thread's instruction pointer ETW-Ti telemetry: EtwTiLogSetThreadContext flagged by EDR driver Enable EDR kernel hooking and Credential Guard / Virtualization-Based Security Verify EDR ETW-Ti provider subscription status Parent Process Anomaly Sensitive system binary (svchost.exe) spawned by unapproved parent process Sysmon Event ID 1: ParentImage is non-standard (e.g., cmd.exe, powershell) Enforce Attack Surface Reduction (ASR) rule: Block child process spawning
Get-MpPreference | Select-Object -ExpandProperty AttackSurfaceReductionRules_Ids
Authoritative References & Standards#
- Microsoft Learn: Virtual Address Descriptor (VAD) Architecture and Memory Management — Windows Internals Documentation
- Microsoft Learn: Mitigate security vulnerabilities by using Windows 10 Exploit Protection — Microsoft Exploit Guard
- Volatility Foundation: Volatility 3 Framework Architecture and Malfind Implementation — Volatility 3 Documentation
- MITRE ATT&CK Framework: Technique T1055.012: Process Injection: Process Hollowing — MITRE ATT&CK
- Microsoft Sysinternals: System Monitor (Sysmon) Event ID Reference — Sysmon Documentation
Comments
Post a Comment