Process Hollowing — Gutting Legitimate Processes

Concept and Motivation

Process Hollowing (also called RunPE or Process Replacement) is a code injection technique that subverts the identity of a legitimate process to execute malicious code. The core idea: we create a trusted host process (such as svchost.exe, explorer.exe, or notepad.exe) in a suspended state, evict its memory contents, and replace them with our malicious payload.

From the perspective of the operating system and many security tools, the process remains svchost.exe — with its PID, name, and legitimate access tokens. The code executing, however, is ours.

┌──────────────────────────────────────────────────────────────────────┐
│                    Process Hollowing Anatomy                          │
│                                                                      │
│  STEP 1: Create process suspended                                    │
│  ┌─────────────────────────────────────────────────────────────┐    │
│  │  svchost.exe (SUSPENDED)                                    │    │
│  │  ┌──────────────────────────────────────────────────────┐   │    │
│  │  │  .text section: [legitimate svchost code]            │   │    │
│  │  │  Entry Point: 0x00401000 → svchost code              │   │    │
│  │  └──────────────────────────────────────────────────────┘   │    │
│  └─────────────────────────────────────────────────────────────┘    │
│                                                                      │
│  STEP 2: Unmap + Inject payload                                      │
│  ┌─────────────────────────────────────────────────────────────┐    │
│  │  svchost.exe (SUSPENDED) — Hollowed                         │    │
│  │  ┌──────────────────────────────────────────────────────┐   │    │
│  │  │  .text section: [malicious payload]                  │   │    │
│  │  │  Entry Point: → malicious code                       │   │    │
│  │  └──────────────────────────────────────────────────────┘   │    │
│  └─────────────────────────────────────────────────────────────┘    │
│                                                                      │
│  STEP 3: ResumeThread → payload executes as "svchost.exe"           │
└──────────────────────────────────────────────────────────────────────┘

Prerequisites and Relevant Structures

To implement process hollowing, we need to understand a few Windows structures:

PEB (Process Environment Block): Structure containing information about the process, including the base address of the loaded image (PEB.ImageBaseAddress). After hollowing, we update this field to the new base address.

CONTEXT: Structure that holds the complete register state of a thread. The RCX register (on x64) points to the PEB of the main thread when it is created.


Full Implementation

Step 1: Create the Target Process in Suspended State

Step 2: Get the Host Process Image Base

We need the address where the legitimate image was loaded in order to unmap it:

Step 3: Unmap the Original Image

Step 4: Map the Payload into the Host Process

Step 5: Apply Relocations (if necessary)

If the payload could not be loaded at its preferred base address, we need to apply relocations:

Step 6: Update Entry Point and Resume Thread

Putting It All Together


Detection and Countermeasures

Evasive Variants

To reduce detectability, modern variants of process hollowing use:

  • Transacted Hollowing: Uses TxF (Transactional NTFS) to create a memory section backed by a file that is never committed to disk.

  • Process Doppelgänging: Creates the process directly from an uncommitted transaction.

  • Module Overwriting / Stomping: Instead of unmap + relocation, overwrites an already-loaded module (see dedicated article).


References

  • Tal Liberman & Eugene Kogan, "Process Doppelgänging" — Black Hat Europe 2017

  • ired.team, "Process Hollowing and Portable Executable Relocations" — ired.team

  • Endgame (now Elastic), "Ten Process Injection Techniques" — elastic.co (2017)

  • Crow, "Understanding Process Injection" — crow.rip (2019)

  • MITRE ATT&CK, "Process Hollowing (T1055.012)" — attack.mitre.org

  • hasherezade, "PE-sieve" — github.com/hasherezade/pe-sieve

Last updated