Process Hollowing Forensics: PEB & VAD Memory Guide

Process Hollowing Forensics: PEB & VAD Memory Guide

Overview & Threat Landscape: The Deceptive Illusion of Legitimate Processes#

Detect Process Hollowing via memory forensics: inspect PEB and VAD mismatches, flag unbacked executable pages, and monitor thread context updates.

In the discipline of Digital Forensics and Incident Response (DFIR), the ability to uncover hidden execution contexts within volatile system memory is often the deciding factor between containing an enterprise intrusion and suffering catastrophic domain compromise. As modern Endpoint Detection and Response (EDR) sensors and Antivirus (AV) engines have matured in scanning files written to disk, sophisticated threat actors—spanning nation-state advanced persistent threat (APT) groups and prominent ransomware syndicates (such as LockBit, BlackCat, and Conti)—have transitioned almost exclusively to in-memory evasion techniques. Chief among these is Process Hollowing (commonly referred to as RunPE, classified under MITRE ATT&CK T1055.012: Process Injection: Process Hollowing and T1055: Process Injection).

Process Hollowing enables adversaries to execute arbitrary, unverified code under the guise of legitimate, trusted, and cryptographically signed operating system executables (such as svchost.exe, explorer.exe, dllhost.exe, or RuntimeBroker.exe). By creating a legitimate process in a suspended state, carving out its original executable sections, writing malicious code into the vacated virtual memory address space, and redirecting the primary thread's execution pointer, the malware blends completely with standard Windows system operations. Standard live-triage utilities and security analysts inspecting task managers or process listings observe legitimate binary paths, genuine digital signatures on disk, and standard command-line parameters.

The architectural factors that make Process Hollowing an essential subject for digital forensics and threat architecture analysis include:

  • The Subversion of Disk-Centric Triage: Traditional incident response protocols that rely on querying file system artifacts (such as Master File Table records, ShimCache, or Amcache) are completely bypassed. The file residing on disk at C:\Windows\System32\svchost.exe is completely benign; the malicious payload exists exclusively within the volatile memory space of the running process.

  • The Failure of Basic Process Lineage Heuristics: While simple process injection (such as CreateRemoteThread) leaves anomalous cross-process handles and foreign thread start addresses, Process Hollowing hijacks the process from its very inception. The process appears to have been started normally by a parent process, retaining legitimate Environment Blocks and initial thread IDs.

  • The Structural Memory Discrepancies Left Behind: While Process Hollowing successfully tricks user-space inspection tools, it fundamentally disrupts the internal memory structures maintained by the Windows NT kernel. Crucially, it creates an irreconcilable discrepancy between the Process Environment Block (PEB) residing in user space and the Virtual Address Descriptor (VAD) tree managed by the kernel's memory manager (ntoskrnl.exe).

  • The Imperative for Volatile Memory Forensics: Uncovering hollowed processes requires deep memory forensics using tools such as Volatility 3 and kernel telemetry via Event Tracing for Windows Threat Intelligence (ETW-Ti). By analyzing VAD allocation protections, detecting unbacked executable memory (PAGE_EXECUTE_READWRITE), and verifying entry point integrity, forensicators can decisively extract the hidden payload and establish the adversary's initial execution timeline.

Warning

Inspecting disk binaries and command lines is insufficient to rule out malware execution. When analyzing compromised endpoints, memory forensics must be performed to verify the structural integrity of running processes.

Vulnerability & Attack Root-Cause Analysis#

: The Win32 and NT Subsystem Injection Mechanics To understand how Process Hollowing operates and why it leaves detectable memory artifacts, forensicators must deconstruct the Win32 and native NT system call sequence utilized to hollow a target process. The Standard Windows Process Loading Architecture Under normal operating conditions, when a process is spawned via CreateProcessW:

  • The Windows executive allocates kernel structures (EPROCESS, KPROCESS).

  • The kernel creates an initial section mapping the target executable from disk into virtual memory, assigning it a Virtual Address Descriptor (VAD) node tagged as VadS (a mapped image section backed by an underlying FILE_OBJECT).

  • The kernel allocates the Process Environment Block (PEB) in user-space memory, populating PEB->ImageBaseAddress with the base address of the mapped executable.

  • The loader (ntdll.dll) maps necessary runtime DLLs, binds the Import Address Table (IAT), and points the primary thread's instruction pointer (RIP/EIP) to the AddressOfEntryPoint defined in the PE optional header. The Five-Stage Process Hollowing Execution Sequence Process Hollowing systematically dismantles this legitimate architecture through five distinct operational phases:

PYTHON
/* Win32 / NT API Sequence for Process Hollowing */
#include <windows.h>
#include <winternl.h>
#include <stdio.h>
typedef NTSTATUS(NTAPI *pfnNtUnmapViewOfSection)(
    HANDLE ProcessHandle,
    PVOID BaseAddress
);
void ExecuteProcessHollowing() {
    STARTUPINFO si = { sizeof(STARTUPINFO) };
    PROCESS_INFORMATION pi = { 0 };
    CONTEXT ctx = { 0 };
    ctx.ContextFlags = CONTEXT_FULL;
    /* Phase 1: Spawn the legitimate target process in a SUSPENDED state /
    / CREATE_SUSPENDED = 0x00000004 prevents the process from executing */
    CreateProcessW(
        L"C:\Windows\System32\svchost.exe",
        NULL, NULL, NULL, FALSE,
        CREATE_SUSPENDED,
        NULL, NULL, &si, &pi
    );
    /* Phase 2: Unmap the original executable image from virtual memory /
    / Locate native API ntdll!NtUnmapViewOfSection */
    HMODULE hNtdll = GetModuleHandleA("ntdll.dll");
    pfnNtUnmapViewOfSection NtUnmapViewOfSection = 
        (pfnNtUnmapViewOfSection)GetProcAddress(hNtdll, "NtUnmapViewOfSection");
    /* Obtain target process ImageBase from PEB and hollow it out /
    PVOID targetBaseAddress = (PVOID)0x0000000140000000; / Example x64 ImageBase */
    NtUnmapViewOfSection(pi.hProcess, targetBaseAddress);
    /* Phase 3: Allocate replacement virtual memory with RWX permissions /
    / Note: VirtualAllocEx creates a PRIVATE memory allocation, NOT a mapped file! /
    SIZE_T payloadSize = 0x50000;
    PVOID newBase = VirtualAllocEx(
        pi.hProcess,
        targetBaseAddress,
        payloadSize,
        MEM_COMMIT | MEM_RESERVE,
        PAGE_EXECUTE_READWRITE / 0x40 - Major Forensic Artifact! */
    );
    /* Phase 4: Write the malicious PE headers and sections into the target /
    PVOID maliciousPayloadBuffer = / ... loaded payload buffer ... */;
    WriteProcessMemory(pi.hProcess, newBase, maliciousPayloadBuffer, payloadSize, NULL);
    /* Phase 5: Hijack the thread context and point instruction pointer to payload */
    GetThreadContext(pi.hThread, &ctx);
    /* On x64, update RCX (entrypoint) or RIP; on x86, update EAX /
    DWORD64 newEntryPoint = (DWORD64)newBase + 0x1234; / Payload AddressOfEntryPoint */
    ctx.Rcx = newEntryPoint;
    SetThreadContext(pi.hThread, &ctx);
    /* Resume execution: The CPU now executes the hollowed malicious payload */
    ResumeThread(pi.hThread);
}

The Architectural Root Cause: Decoupled Memory Metadata & The VAD Tree The fundamental flaw that enables Process Hollowing—and simultaneously guarantees its forensic detectability—is the architectural decoupling between user-space process metadata and kernel-level memory management:

  • The Kernel VAD Tree (_MMVAD): The Windows memory manager organizes every process's virtual memory allocations into a self-balancing AVL binary search tree called the Virtual Address Descriptor (VAD) tree. Each node (_MMVAD or _MMVAD_SHORT) represents a contiguous range of committed pages, recording allocation flags (VadFlags), memory protections (Read/Write/Execute), and private versus mapped status.

  • NtUnmapViewOfSection Erases the Backing File: When the original executable section is unmapped, the kernel removes the VadS node that linked the virtual address range to the disk file (svchost.exe).

  • VirtualAllocEx Allocates Private Anonymous Memory: When the attacker allocates replacement memory to host the injected payload, the kernel assigns it a standard private allocation VAD node (tagged simply as Vad). The node's internal bitfield records VadFlags.PrivateMemory = 1 and VadFlags.Protection = MM_EXECUTE_READWRITE (0x40). Crucially, the VAD node completely lacks a pointer to a kernel _FILE_OBJECT structure.

  • The PEB Remains Unsynchronized: The user-space Process Environment Block (PEB) continues to retain its original ProcessParameters pointing to C:\Windows\System32\svchost.exe, and often retains the original ImageBaseAddress.

  • Thread Context Redirection Dynamics: On modern 64-bit Windows architectures, when a thread initializes in a suspended state, ntdll!RtlUserThreadStart expects the target EntryPoint to be loaded into the RCX register, with RDX holding the PEB address. Attackers modifying the thread context via SetThreadContext update ctx.Rcx (or ctx.Rip), redirecting the CPU immediately upon ResumeThread().

  • Contrasting with Other Image Modification Techniques: Process Hollowing is distinct from sibling evasion techniques:

  • Process Doppelgänging: Utilizes NTFS Transactional Resource Manager (TxF) transactions to modify an executable in memory before process creation, avoiding NtUnmapViewOfSection.
    • Process Herpaderping: Spawns a process from a file on disk, replaces the on-disk file bytes before the process initializes, and resumes execution to confuse disk-based scanners.

    • Process Ghosting: Deletes a payload file prior to section creation using pending-delete status. Process Hollowing remains unique in its distinct reliance on explicit section unmapping followed by private anonymous memory allocation.

    Exploit Architecture#

    : Sequence of Execution and Kernel Memory State Flowchart The following sequence diagram illustrates the chronological execution flow of Process Hollowing, highlighting the exact moments where kernel memory states transition from legitimate mapped sections to compromised private anonymous allocations.

  • sequenceDiagram
        autonumber
        actor Attacker as Malware / Injector Process
        participant Kernel as Windows NT Kernel (ntoskrnl.exe)
        participant Host as Target Process (svchost.exe - Suspended)
        participant VAD as Virtual Address Descriptor (VAD Tree)
        participant PEB as Process Environment Block (PEB)
        actor Forensic as DFIR Analyst (Volatility 3 / EDR)
        Note over Attacker: 1. Spawn legitimate sacrificial process
        Attacker->>Kernel: CreateProcessW(svchost.exe, CREATE_SUSPENDED)
        Kernel->>Host: Create process & suspended primary thread
        Kernel->>VAD: Create VadS node (Mapped image backed by svchost.exe)
        Kernel->>PEB: Initialize PEB->ImageBaseAddress = 0x140000000
        Note over Attacker: 2. Hollow out target memory
        Attacker->>Kernel: NtUnmapViewOfSection(Host, 0x140000000)
        Kernel->>VAD: Destroy VadS node (svchost.exe section unmapped!)
        Note over Host: Target process memory space is now empty (Hollowed)
        Note over Attacker: 3. Allocate private unbacked memory
        Attacker->>Kernel: VirtualAllocEx(Host, 0x140000000, RWX)
        Kernel->>VAD: Create Vad node (Private Anonymous Memory, NO file backing)
        Note over Attacker: 4. Write payload & redirect entrypoint
        Attacker->>Host: WriteProcessMemory(Host, Injected PE Headers & Code)
        Attacker->>Host: SetThreadContext(pi.hThread, Context.Rcx = InjectedEntryPoint)
        Attacker->>Kernel: ResumeThread(pi.hThread)
        Note over Host: Process executes malicious payload under svchost.exe identity!
        Note over Forensic: 5. DFIR volatile memory triage
        Forensic->>VAD: Audit VAD nodes via windows.malfind & windows.vadinfo
        VAD-->>Forensic: Discrepancy Found! Anonymous Vad with PAGE_EXECUTE_READWRITE & MZ header
        Forensic->>PEB: Compare PEB->ImagePath with VAD memory backing
        Note over Forensic: Process Hollowing confirmed! Dump payload for reverse engineering

    Attack Path Step-by-Step: Forensic Dissection with Volatility 3 and HollowFind#

    When an incident response team acquires a raw physical memory dump from a compromised endpoint, detecting Process Hollowing requires systematic memory dissection. The following walkthrough demonstrates the forensic methodology utilized to detect and extract hollowed processes using Volatility 3.

    Phase 1: Identifying Process Hierarchy Anomalies#

    Analysts begin by auditing the overall process tree using windows.pslist and windows.pstree:

    POWERSHELL
    ### 1. Inspect running process tree from memory dump

    vol -f memory_dump.raw windows.pstree

    In a compromised dump, an analyst identifies an anomalous svchost.exe instance:

    Spawned by an unusual parent process (e.g., cmd.exe, powershell.exe, or a user-space executable in C:\Users...\AppData) rather than services.exe.

    Executing without the standard -k service group parameters (e.g., svchost.exe -k netsvcs).

    Phase 2: Detecting Unbacked Executable Memory via windows.malfind#

    The primary Volatility 3 plugin for identifying injected code is windows.malfind. The plugin scans every process's VAD tree, identifying memory pages marked with write and execute permissions (PAGE_EXECUTE_READWRITE) that are not backed by a mapped file on disk:

    POWERSHELL
    ### 2. Run malfind against the suspicious process ID

    vol -f memory_dump.raw windows.malfind --pid 4112

    The output reveals the hollowed memory segment:

    PID Process Start End Protection Commit Tag

    4112 svchost.exe 0x140000000 0x140050000 PAGE_EXECUTE_READWRITE 1 Vad

    0x140000000: 4d 5a 90 00 03 00 00 00 04 00 00 00 ff ff 00 00 MZ..............

    0x140000010: b8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 ........@.......

    0x140000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................

    0x140000030: 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 00 ................

    0x140000040: 0e 1f ba 0e 00 b4 09 cd 21 b8 01 4c cd 21 54 68 ........!..L.!Th

    0x140000050: 69 73 20 70 72 6f 67 72 61 6d 20 63 61 6e 6e 6f is program canno

    0x140000060: 74 20 62 65 20 72 75 6e 20 69 6e 20 44 4f 53 20 t be run in DOS

    Forensic Indicators Confirmed:#

    • The MZ Header (4D 5A): The start of the memory region begins with the unmistakable magic bytes of a Portable Executable file (MZ), followed by the standard DOS stub string "This program cannot be run in DOS mode".

    • PAGE_EXECUTE_READWRITE Protection: The memory protection is explicitly set to 0x40. Legitimate executables mapped from disk are mapped as PAGE_EXECUTE_READ for code and PAGE_READONLY for headers.

    • VAD Tag Vad: The tag indicates a private memory allocation (MEM_PRIVATE). If svchost.exe were genuinely executing from disk, the tag would be VadS (MEM_IMAGE) with a direct reference to \Device\HarddiskVolume3\Windows\System32\svchost.exe.

    Phase 3: Inspecting VAD Metadata via windows.vadinfo#

    To confirm that the section lacks an underlying file object, the analyst inspects the detailed VAD node flags:

    POWERSHELL
    ### 3. Query VAD descriptor details for the hollowed address range

    vol -f memory_dump.raw windows.vadinfo --pid 4112 --address 0x140000000

    PID Process Start End Tag File Object Flags

    4112 svchost.exe 0x140000000 0x140050000 Vad None PrivateMemory: 1, Protection: 6

    The descriptor explicitly reports File Object: None and PrivateMemory: 1. This conclusively establishes that the executable image executing at the base address has no relationship to any binary on disk.

    Phase 4: Extracting and Dumping the Injected Executable#

    With the memory boundaries established (0x140000000 to 0x140050000), the analyst dumps the memory range directly to disk to recover the unpacked malware binary for static analysis and reverse engineering:

    POWERSHELL
    ### 4. Dump the hollowed memory segment to disk

    vol -f memory_dump.raw -o ./recovered_artifacts windows.dumpfiles --pid 4112 --virtaddr 0x140000000

    POWERSHELL
    ### 5. Calculate cryptographic hashes of the recovered payload
    
    sha256sum ./recovered_artifacts/file.4112.0x140000000.dmp

    The extracted file represents the fully unpacked payload. Analysts can now submit the hash to threat intelligence feeds or load the binary into IDA Pro or Ghidra for disassembly and C2 infrastructure extraction.

    Actionable Detection Rule: Production Sigma Rule for Process Hollowing Telemetry#

    While memory forensics provides post-incident ground truth, Security Operations Centers (SOC) require real-time detection telemetry. The following Sigma rule detects Process Hollowing by monitoring Sysmon Event ID 25 (Process Tampering - Image is replaced) and cross-process thread context manipulation:

    YAML
    title: Potential Process Hollowing Detected via Process Tampering Telemetry
    id: 4e8a1c2b-9f3d-4812-bc30-f92e01b45289
    status: stable
    description: Detects 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_target_images:
            Image|endswith:
                - '\svchost.exe'
                - '\explorer.exe'
                - '\dllhost.exe'
                - '\RuntimeBroker.exe'
                - '\conhost.exe'
                - '\taskhostw.exe'
        condition: selection_tampering and selection_target_images
    fields:
        - UtcTime
        - ProcessId
        - Image
        - Type
    falsepositives:
        - Rare third-party security agents performing binary instrumentation (require strict code signing and hash whitelisting)
    level: critical

    Additionally, EDR platforms instrumenting Microsoft-Windows-Threat-Intelligence (ETW-Ti) can monitor the kernel event EtwTiLogSetThreadContext, flagging any instance where SetThreadContext is called across process boundaries on a thread belonging to a suspended process whose image base was previously modified.

    Fast Cyber Defense Morning Takeaways: Bridging to Evening Hardening#

    Process Hollowing exposes the fundamental limitation of inspecting processes through the lens of static on-disk files. When an adversary operates entirely within volatile memory, disk-level indicators of compromise (IOCs) are nonexistent.

    Key strategic takeaways from this morning's forensic analysis include:

    • The VAD Tree Is the Single Source of Truth: The Process Environment Block (PEB) can be manipulated, spoofed, or desynchronized by user-space code. The kernel Virtual Address Descriptor (VAD) tree, maintained within ntoskrnl.exe, cannot be modified from user space without kernel-level code execution.

    • Unbacked RWX Pages Are Hostile by Default: Legitimate Windows system binaries never execute code from unbacked private memory marked PAGE_EXECUTE_READWRITE. Automated memory scanners flagging RWX memory with MZ headers reliably isolate hollowed processes.

    • The Bridge to Evening Hardening: Completely preventing Process Hollowing requires proactive OS mitigation: deploying Arbitrary Code Guard (ACG), enforcing Process Mitigation Policies (disallowing non-system fonts and blocking unmapped executable pages via SetProcessMitigationPolicy), and configuring Windows Defender Exploit Guard.

    🛡️ Blue Team Defense: For detection rules, Sysmon event IDs, and hardening configurations, see our companion guide: Hardening Guide.

    Executive Takeaway Table: Attack Vectors, Telemetry Signals, and Primary Mitigations#

    The following matrix provides digital forensics specialists and Windows system architects with an executive overview of the Process Hollowing attack surface, memory artifacts, and defense engineering controls:

    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 VAD / PEB Desynchronization PEB references legitimate disk path while VAD confirms anonymous private memory Volatility 3: windows.vadinfo displays Tag: Vad with File Object: None Enforce Microsoft Defender Exploit Guard Process Mitigation Policies

    POWERSHELL
    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

    POWERSHELL
    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

    POWERSHELL
    Get-MpPreference | Select-Object -ExpandProperty AttackSurfaceReductionRules_Ids

    Authoritative References & Standards#

    • Microsoft Learn: Virtual Address Descriptor (VAD) Architecture and Memory Management — Windows Internals Documentation

    • 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

    • SANS Institute Information Security Reading Room: Detecting Deceptive Process Hollowing Techniques via Memory Forensics — SANS Reading Room

    • Microsoft Sysinternals: System Monitor (Sysmon) Event ID Reference — Sysmon Documentation

    Comments