Skip to content

Artifact Analysis: Process Injection Foundations

Before analyzing the mechanics of Process Injection, DFIR analysts must draw a strict boundary between two distinct evasion paradigms: Disk-based and Memory-based attacks.

While we previously covered DLL Hijacking and Sideloading, which manipulates how the Windows OS loads files from the disk at startup, Process Injection operates almost entirely in RAM during runtime.

  • DLL Sideloading (Disk/Loader): The attacker drops a physical file on the disk and tricks the Windows Loader (ntdll.dll) into importing it into a legitimate process when that process is initially launched.
  • Process Injection (Memory/Runtime): The attacker runs a malicious process (the injector) that aggressively opens a handle to a completely separate, already-running legitimate process (the target), and writes malicious code directly into its volatile memory.

Process Injection: Disk vs. Memory

  1. Stealth & Whitelisting Bypass: If a firewall or EDR is configured to only allow chrome.exe or explorer.exe to make outbound HTTP connections, malware can inject its C2 beacon into chrome.exe to inherit its trusted network permissions.
  2. Credential Theft: To steal passwords from browsers or extract hashes from the Local Security Authority Subsystem Service (lsass.exe), malware must inject code into those specific processes to access their isolated memory structures.
  3. Defense Evasion: Terminating the original malicious process leaves the payload running silently inside a benign host process, breaking the Process Lineage chain.

2. The Anatomy of Windows Memory & API Abuse

Section titled “2. The Anatomy of Windows Memory & API Abuse”

To understand how injections occur, analysts must first understand how Windows protects processes.

Modern Windows relies on Virtual Address Spaces (VAS). Every running process is isolated; it believes it possesses its own contiguous block of memory, and it cannot natively read or write to the memory of another process.

To break this isolation, an attacker’s injector process must abuse a sequence of legitimate Windows Application Programming Interfaces (APIs). The “Classic” Process Injection generally follows a strict, four-step API lifecycle:

  1. Targeting (OpenProcess): The malicious injector calls the OpenProcess API, requesting a “Handle” (an access ticket) to the target process (e.g., notepad.exe). It requests high privileges, specifically PROCESS_VM_WRITE and PROCESS_VM_OPERATION.
  2. Allocation (VirtualAllocEx): Once the handle is obtained, the injector calls VirtualAllocEx. This forces the target process to allocate a new, empty block of memory within its own address space. Crucially, the attacker often requests this new memory to be marked as PAGE_EXECUTE_READWRITE (RWX), meaning code can be written there and subsequently executed.
  3. Writing (WriteProcessMemory): The injector uses WriteProcessMemory to copy the malicious payload (shellcode or a DLL path) from its own memory into the newly allocated RWX space inside the target process.
  4. Execution (CreateRemoteThread): Finally, the injector calls CreateRemoteThread. This API forces the target process to spawn a new execution thread, pointing the instruction pointer directly at the malicious payload written in Step 3. The payload now executes under the guise of the legitimate process.

3. The “Classic Trinity” of Process Injection

Section titled “3. The “Classic Trinity” of Process Injection”

Over the past decade, malware developers have iterated on the base Windows APIs to create three foundational injection techniques. While modern EDRs catch these easily today, understanding them is a mandatory prerequisite for any DFIR analyst.

This is the oldest and simplest form of process injection. Instead of writing an entire payload into the target process, the attacker simply writes the file path of a malicious DLL (e.g., C:\Temp\evil.dll) into the target’s memory. The attacker then calls CreateRemoteThread and points it to a native Windows API called LoadLibraryA.

  • The Result: The target process is forced to load the malicious DLL from the disk, executing its DllMain function.
  • Forensic Weakness: It is incredibly noisy. The malicious DLL must physically exist on the disk, and it registers as a loaded module within the victim process (visible in tools like Process Explorer).

To overcome the limitations of Classic DLL Injection, attackers moved to “Fileless” execution. Pioneered by Stephen Fewer and heavily utilized by frameworks like Cobalt Strike and Metasploit, RDI bypasses the native Windows Loader entirely.

  • The Mechanism: The attacker allocates memory in the target process and copies the entire malicious DLL directly into RAM. Because the Windows LoadLibrary function only works with files on disk, the attacker injects a custom “Reflective Loader” function alongside the DLL. This custom loader manually maps the DLL into memory, resolves its imports, and executes it.
  • Forensic Weakness: Because the DLL was loaded manually by the malware and not by Windows, the memory pages containing the DLL are “unbacked” (they do not map to any legitimate file on the hard drive) and are typically marked as RWX.

Also known as “RunPE”, this technique doesn’t just inject code into a running process; it steals the identity of a legitimate binary to hide in plain sight.

  1. Creation: The malware spawns a legitimate Windows process (e.g., svchost.exe) in a SUSPENDED state.
  2. Hollowing: It uses the NtUnmapViewOfSection API to “hollow out” (unmap) the legitimate code of svchost.exe from its memory space.
  3. Replacement: The malware allocates new memory and writes its own malicious payload into the now-empty shell of the process.
  4. Resumption: The attacker alters the thread context (EIP/RIP registry) to point to the malicious payload and resumes the thread.
  • The Result: To the Task Manager or a junior analyst, the process looks exactly like a normal svchost.exe. However, the code executing inside memory belongs to the malware.
  • Forensic Weakness: There is a glaring discrepancy between the Process Environment Block (PEB) showing the path of the legitimate executable, and the actual memory mapping which contains unbacked, executable code.

Detecting foundational process injection relies on capturing the specific API calls used to cross process boundaries and analyzing memory anomalies.

Sysmon specifically designed Event ID 8 (CreateRemoteThread) to catch Classic and Reflective DLL injections. It triggers whenever a process creates a thread in another process.

hunt_remote_thread_injection.kql
// Detects processes injecting threads into critical system processes
DeviceEvents
| where ActionType == "CreateRemoteThreadApiCall"
// Focus on target processes commonly abused for injection/hollowing
| where FileName in~ ("svchost.exe", "explorer.exe", "lsass.exe", "winlogon.exe", "notepad.exe")
// Exclude known legitimate administrative tools to reduce noise
| where InitiatingProcessFileName !in~ ("csrss.exe", "wbemprox.exe", "taskmgr.exe")
| project TimeGenerated, DeviceName, InitiatingProcessFileName, FileName, ActionType
| sort by TimeGenerated desc

When analyzing a RAM dump, DFIR analysts hunt for the “RWX” and “Unbacked Memory” indicators left behind by Reflective DLL Injection and Process Hollowing. The windows.malfind.Malfind plugin in Volatility 3 is explicitly designed to scan memory spaces for VAD (Virtual Address Descriptor) tags marked as PAGE_EXECUTE_READWRITE that do not correlate to a mapped file on disk.

volatility_malfind.sh
# Execute malfind to identify injected, unbacked executable memory
python3 vol.py -f memory_dump.raw windows.malfind

The “Classic Trinity” of process injection techniques defined the malware landscape for a decade. However, modern Endpoint Detection and Response (EDR) solutions have adapted. By utilizing “User-Mode Hooking” (intercepting calls to ntdll.dll APIs like NtAllocateVirtualMemory and NtCreateThreadEx), EDRs can instantly block these foundational techniques.

To survive in 2026, Advanced Persistent Threats (APTs) have been forced to evolve, abandoning RWX memory and CreateRemoteThread in favor of hyper-stealthy techniques that manipulate deep kernel structures.

How do threat actors bypass modern EDR memory scanners using Module Stomping, Header Clearing, and Memory Mirroring?

👉 Read the advanced guide: Next-Gen Code Injection & EDR Evasion