Difficulty: Beginner

Module 2: PE Tampering Techniques Overview

The evolution of PE image tampering — from Process Hollowing to Ghosting, each technique exploiting a different gap in the process creation chain.

Module Objective

Survey the four major PE tampering techniques — Process Hollowing, Process Doppelgänging, Process Herpaderping, and Process Ghosting — understanding how each one manipulates a different stage of the file → section → process pipeline, what weaknesses each addresses, and the evolutionary progression that led to Ghosting.

1. The Core Problem All Techniques Share

All PE tampering techniques try to solve the same problem: execute malicious code in a process that appears legitimate to security tools. The Windows process creation chain (file → section → process → thread) gives security tools multiple inspection points. Each tampering technique targets a different gap between these inspection points.

Inspection Points in Process Creation

File Written
AV scans file
Section Created
Kernel callback
First Thread Inserted
PsSetCreateProcessNotifyRoutineEx fires
Thread Starts
Execution begins

The trick is to ensure that at each inspection point, security tools either see a clean file, see no file at all, or cannot access the file to scan it.

2. Process Hollowing (2004+)

Process Hollowing is the oldest and most well-known technique. It creates a legitimate process in a suspended state, then replaces its memory contents with malicious code before resuming.

Hollowing Flow

  1. Create a legitimate process (e.g., svchost.exe) in a suspended state using CreateProcessW with CREATE_SUSPENDED
  2. Unmap the original executable image using NtUnmapViewOfSection
  3. Allocate new memory in the target process with VirtualAllocEx
  4. Write the malicious PE into the allocated memory with WriteProcessMemory
  5. Update the PEB image base and thread context (entry point in EAX/RCX) to point to the new image
  6. Resume the main thread with ResumeThread
// Simplified Process Hollowing pseudocode
CreateProcessW(L"svchost.exe", ..., CREATE_SUSPENDED, ..., &pi);

// Unmap the original image
NtUnmapViewOfSection(pi.hProcess, pImageBase);

// Allocate and write malicious PE
LPVOID pNewBase = VirtualAllocEx(pi.hProcess,
    pPreferredBase, imageSize,
    MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(pi.hProcess, pNewBase, maliciousPE, imageSize, NULL);

// Fix up PEB and thread context
// ... update ImageBaseAddress in PEB ...
// ... set thread context RCX to new entry point ...

ResumeThread(pi.hThread);

Why Hollowing Is Detected

3. Process Doppelgänging (2017)

Presented by Tal Liberman and Eugene Kogan of enSilo at Black Hat Europe 2017, Process Doppelgänging uses NTFS transactions (TxF) to create a process from a file that never actually exists on disk in its malicious form.

Doppelgänging Flow

  1. Create an NTFS transaction using NtCreateTransaction
  2. Open a file within the transaction using NtCreateFile — this file is transacted, meaning changes are only visible within the transaction context
  3. Write the malicious PE content to the transacted file
  4. Create a SEC_IMAGE section from the transacted file handle using NtCreateSection
  5. Rollback the transaction using NtRollbackTransaction — the file reverts to its original state (or never existed), but the section object persists
  6. Create a process from the section using NtCreateProcessEx
// Process Doppelganging key steps
HANDLE hTransaction, hFile, hSection;

// 1. Create NTFS transaction
NtCreateTransaction(&hTransaction, ...);

// 2. Create file within transaction
NtCreateFile(&hFile, ...,
    hTransaction,  // transacted operation
    FILE_SUPERSEDE, ...);

// 3. Write malicious PE to transacted file
NtWriteFile(hFile, ..., maliciousPE, peSize, ...);

// 4. Create image section from transacted file
NtCreateSection(&hSection, ..., SEC_IMAGE, hFile);

// 5. Rollback - file disappears, section remains
NtRollbackTransaction(hTransaction, TRUE);

// 6. Create process from the persisted section
NtCreateProcessEx(&hProcess, ..., hSection, ...);

Doppelgänging Advantages

Doppelgänging Limitations

4. Process Herpaderping (2020)

Created by Johnny Shaw (jxy-s), Process Herpaderping exploits the gap between when the section is created from a file and when AV/EDR gets around to scanning that file in response to process creation notifications.

Herpaderping Flow

  1. Create a new file on disk using NtCreateFile
  2. Write the malicious PE content to the file
  3. Create a SEC_IMAGE section from the file using NtCreateSection — the section now contains the malicious image
  4. Overwrite the file on disk with benign content (e.g., a clean copy of notepad.exe)
  5. Close the file handle
  6. Create a process from the section — process runs malicious code, but the file on disk is now benign
// Process Herpaderping key steps
HANDLE hFile, hSection;

// 1. Create file, write malicious PE
NtCreateFile(&hFile, ..., FILE_SUPERSEDE, ...);
NtWriteFile(hFile, ..., maliciousPE, peSize, ...);

// 2. Create section while file has malicious content
NtCreateSection(&hSection, ..., SEC_IMAGE, hFile);

// 3. Overwrite file with benign content AFTER section creation
SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
NtWriteFile(hFile, ..., benignPE, benignSize, ...);

// 4. Close file - on-disk content is now benign
NtClose(hFile);

// 5. Process runs from the malicious section
NtCreateProcessEx(&hProcess, ..., hSection, ...);

The key insight is that the section captures the file’s content at creation time. Modifying the file afterward does not change the section. When AV scans the file in response to the process creation callback, it sees benign content.

Herpaderping Limitations

5. Process Ghosting (2021)

Process Ghosting, discovered by Gabriel Landau of Elastic Security and implemented as a proof-of-concept by hasherezade (process_ghosting on GitHub), takes the evolution one step further. Instead of modifying the file after section creation (Herpaderping), it deletes the file entirely. The process runs from a section whose backing file no longer exists.

Ghosting Flow

  1. Create a new file on disk using NtCreateFile
  2. Put the file into the delete-pending state using NtSetInformationFile with FileDispositionInformation
  3. Write the malicious PE content to the file (the file is delete-pending but the handle is still valid for writes)
  4. Create a SEC_IMAGE section from the delete-pending file handle
  5. Close the file handle — the file is deleted from disk because it was marked delete-pending
  6. Create a process from the section using NtCreateProcessEx

Why Ghosting Beats Herpaderping

In Herpaderping, the file on disk still exists (with benign content). A sophisticated scanner could notice the discrepancy between the section’s content and the file, or flag the overwrite pattern. In Ghosting, there is no file on disk at all. When AV tries to open the file for scanning, it either gets STATUS_FILE_DELETED (if the delete has completed) or STATUS_DELETE_PENDING (if the file is still in the delete-pending state). Either way, the scan cannot proceed.

6. Evolution Comparison

TechniqueYearFile State at Process CreationWhat AV SeesKey Weakness
Hollowing~2004Original file intact on diskMemory/file mismatchUnmapped sections, PEB mods, RWX
Doppelgänging2017Transaction rolled back; file revertedClean file (original or non-existent)TxF deprecated, driver conflicts
Herpaderping2020File overwritten with benign contentBenign file contentFile still exists, overwrite detectable
Ghosting2021File deleted (or delete-pending)No file to scan at allDelete-pending state detectable by kernel drivers

7. The Technique Family Tree

Each technique builds on the lessons of the previous one:

Evolutionary Progression

ProblemSolutionNext Problem
Need to run malicious code in a processHollowing: Replace process memoryMemory/file mismatch is obvious
File and memory must matchDoppelgänging: Use TxF so file never commitsTxF is deprecated, driver issues
Need non-TxF approachHerpaderping: Overwrite file after section creationFile still on disk, overwrite detectable
File on disk is still evidenceGhosting: Delete file after section creationDelete-pending state can be detected at kernel level

8. What They All Have in Common

Despite their differences, all four techniques share core principles:

Process Ghosting represents the current state of the art in this family, eliminating the backing file entirely rather than modifying it.

Knowledge Check

Q1: Which technique uses NTFS transactions (TxF) to create a process from a file that was never committed to disk?

A) Process Hollowing
B) Process Herpaderping
C) Process Ghosting
D) Process Doppelgänging

Q2: What is the key difference between Herpaderping and Ghosting?

A) Herpaderping uses NtCreateSection while Ghosting does not
B) Herpaderping overwrites the file with benign content; Ghosting deletes the file entirely
C) Herpaderping works on Windows 10; Ghosting only works on Windows 7
D) Herpaderping modifies the section; Ghosting modifies the process

Q3: What is the main weakness of Process Hollowing that all later techniques sought to address?

A) It requires administrator privileges
B) It only works with 32-bit processes
C) The in-memory image does not match the file on disk, making the mismatch easily detectable
D) It requires a kernel driver to function