Skip to content

TTP Analysis: Next-Gen Code Injection & EDR Evasion

1. Introduction: The Death of CreateRemoteThread

Section titled “1. Introduction: The Death of CreateRemoteThread”

As established in our Process Injection Foundations guide, legacy injection relies on a highly predictable API chain: OpenProcessVirtualAllocExWriteProcessMemoryCreateRemoteThread.

In 2026, relying on this chain is operational suicide for a threat actor. Modern EDRs neutralize this through two primary mechanisms:

  1. User-Mode Hooking (API Detouring): EDR agents inject their own DLLs into every user-space process. They place inline hooks on low-level NTAPI functions inside ntdll.dll (e.g., NtAllocateVirtualMemory, NtWriteVirtualMemory, NtCreateThreadEx). Before the Windows kernel executes the attacker’s request, the EDR inspects the arguments.
  2. The RWX Stigma: EDRs heavily scrutinize memory pages allocated with PAGE_EXECUTE_READWRITE (RWX) protections. If an EDR detects WriteProcessMemory pushing data into an RWX-marked memory segment of a remote process, the action is blocked, and an alert is generated.

To bypass these defenses, threat actors must achieve two goals: allocate memory without triggering behavioral hooks, and ensure the payload executes without relying on anomalous RWX memory regions.

2. Evading Memory Scanners: Header Clearing & Mirroring

Section titled “2. Evading Memory Scanners: Header Clearing & Mirroring”

Once a payload is injected, it faces a second formidable enemy: the EDR’s continuous memory scanner. EDRs periodically sweep the RAM of running processes, utilizing YARA rules to hunt for malicious byte sequences or orphaned Portable Executable (PE) structures.

Adversaries employ advanced memory manipulation to blind these scanners.

When a payload (such as a Cobalt Strike beacon) is reflectively loaded into memory, its structural headers (the MZ magic bytes, the DOS stub, and the PE/COFF headers) are mapped into RAM along with the executable code.

Memory scanners and DFIR tools (like Volatility’s malfind plugin) explicitly hunt for these MZ (0x4D5A) headers residing in “unbacked” memory regions (memory not mapped to a legitimate file on disk).

The Evasion Technique: To defeat this, advanced loaders utilize a technique known as Header Clearing. Once the payload has been successfully mapped into memory and its imports resolved, the loader dynamically overwrites its own PE headers with null bytes (0x00) or randomized garbage data. To an EDR memory scanner relying on structural signatures, the malicious memory region now appears as a block of unstructured, ambiguous data, severely reducing the detection rate.

Next-Gen Code Injection & EDR Evasion: Header Clearing

B. Memory Mirroring (Section Object Mapping)

Section titled “B. Memory Mirroring (Section Object Mapping)”

To avoid the highly monitored WriteProcessMemory API, threat actors pivoted to a native Windows inter-process communication (IPC) mechanism: Section Objects. This technique is often referred to as “Memory Mirroring” or “Mapping Injection.”

Instead of forcing data into a remote process, the attacker creates a shared memory bridge.

  1. Section Creation: The malicious injector process calls NtCreateSection to create a memory section object backed by the page file.
  2. Local Mapping (RW): The injector maps a view of this section into its own address space using NtMapViewOfSection with PAGE_READWRITE (RW) permissions.
  3. Payload Copy: The injector writes the malicious shellcode into this local view. Because the injector is modifying its own memory, EDR cross-process write hooks are not triggered.
  4. Remote Mapping (RX): The injector calls NtMapViewOfSection a second time, but this time it maps the same section object into the address space of the target victim process, requesting PAGE_EXECUTE_READ (RX) permissions.

The Forensic Result: The malicious payload magically appears in the target process’s memory space. Because the attacker separated the “Write” phase (RW) from the “Execute” phase (RX), the memory is never marked as the highly suspicious RWX. Furthermore, because the payload was shared via the kernel’s memory manager rather than explicitly written via WriteProcessMemory, traditional user-mode EDR hooks are completely bypassed.

While Memory Mirroring avoids RWX permissions, it still leaves behind “unbacked” memory—executable memory regions that do not correspond to a physical file on the hard drive. Advanced memory scanners heavily scrutinize unbacked executable pages.

To achieve the ultimate stealth, adversaries use a technique called Module Overwriting, also known as Module Stomping or DLL Hollowing. The goal is to hide the malicious payload inside a memory region that is legitimately “backed” by a highly trusted, digitally signed Microsoft DLL.

Instead of allocating new memory, the attacker repurposes existing memory.

  1. Force a Library Load: The malicious injector forces the target process to load a legitimate, rarely used Microsoft DLL (e.g., xpsprint.dll or amsi.dll) using LoadLibrary or NtLoadDriver.
  2. Permission Modification: The injector locates the .text section (the executable code segment) of this newly loaded DLL in memory. It uses VirtualProtectEx to temporarily change the memory permissions from RX (Read-Execute) to RW or RWX.
  3. The Stomp (Overwrite): The injector writes its malicious payload directly over the legitimate, signed Microsoft code.
  4. Restoration: The injector calls VirtualProtectEx again to restore the memory permissions back to RX.
  5. Execution: The payload is executed.

The Forensic Result: If an EDR or a memory scanner examines the victim process, it sees a memory page marked RX (normal) that points directly to C:\Windows\System32\xpsprint.dll on disk (backed and highly trusted). The scanner assumes the memory contains the legitimate Microsoft code and moves on. The malware operates in complete stealth.

Once the malicious code is securely hidden in memory (via Stomping or Mirroring), the attacker must execute it. As established, calling CreateRemoteThread generates highly visible telemetry (Sysmon Event ID 8). Adversaries bypass this by hijacking threads that already exist.

Instead of creating a new thread, the attacker parasitically takes over an existing, benign thread within the target process.

  1. Targeting: The injector enumerates the threads running inside the victim process and selects one (preferably a sleeping or inactive thread) using OpenThread.
  2. Suspension: The attacker halts the thread’s execution using SuspendThread.
  3. Context Manipulation: The attacker retrieves the thread’s execution context using GetThreadContext. Crucially, they modify the Instruction Pointer registry (the RIP register on x64 systems) to point to the memory address where the malicious payload was injected.
  4. Resumption: The attacker applies the modified context using SetThreadContext and wakes the thread up with ResumeThread.

Because no new thread was created, API hooks monitoring thread creation remain entirely silent, blinding the SOC to the execution.

Next-Gen Code Injection & EDR Evasion: Thread Execution Hijacking

B. PEB Masquerading (The Art of Lying to Task Manager)

Section titled “B. PEB Masquerading (The Art of Lying to Task Manager)”

To further deceive analysts and basic EDR agents, threat actors manipulate the Process Environment Block (PEB).

The PEB is a user-mode data structure in Windows that contains critical information about a process, including its loaded modules, process name, and command-line arguments. Because it resides in user space, it is entirely readable and writable by the process itself (or an injected payload).

Attackers modify the RTL_USER_PROCESS_PARAMETERS structure within the PEB. For example, a malicious process could rewrite its ImagePathName and CommandLine fields in the PEB to mimic C:\Windows\System32\svchost.exe -k netsvcs.

If a junior analyst uses Task Manager or Process Explorer, the tool reads the PEB and displays the fake, benign name and command line.

Next-Gen Code Injection & EDR Evasion: PEB Masquerading

5. Advanced Forensic Investigation (Hunting the Ghosts)

Section titled “5. Advanced Forensic Investigation (Hunting the Ghosts)”

When threat actors bypass user-mode EDR hooks, utilize memory mirroring to avoid RWX pages, and stomp legitimate modules to ensure memory remains backed, traditional live triage tools become blind. DFIR analysts must descend into deep memory forensics and kernel-level telemetry to hunt these “ghosts.”

In standard memory analysis, the Volatility 3 windows.malfind plugin is the go-to tool. It scans the Virtual Address Descriptor (VAD) tree for memory regions that are executable but unbacked. However, against Module Stomping, malfind will likely fail because the stomped memory page is backed by a legitimate DLL on disk.

To detect advanced injection, analysts must scrutinize the VAD tree using windows.vadinfo and perform cross-verifications:

  1. Private vs. Mapped Memory: Investigate memory sections that are backed by a file but have been modified. When an attacker stomps a module, the OS performs a “Copy-on-Write” (CoW), changing the memory type from MEM_MAPPED to MEM_PRIVATE. A signed Microsoft DLL residing in MEM_PRIVATE executable memory is a massive red flag.
  2. Memory-to-Disk Hash Comparison: Extract the in-memory .text section of the suspected DLL and hash it. Extract the physical DLL from the disk and hash its .text section. A mismatch confirms the module was stomped or patched at runtime.
  3. Thread Analysis: Use the windows.pslist and windows.threads plugins. Look for threads whose start address points to an unusual offset within a module, or threads executing completely outside of known mapped modules.

As attackers mastered “Unhooking” (unmapping the EDR’s user-mode hooks in ntdll.dll and reloading a fresh, unhooked copy from disk), Microsoft introduced a game-changing telemetry source: Event Tracing for Windows - Threat Intelligence (ETW-Ti).

Unlike user-mode hooks, ETW-Ti operates entirely within the Windows Kernel (ntoskrnl.exe). Threat actors operating in user-space (Ring 3) cannot unhook or bypass ETW-Ti sensors without first deploying a vulnerable kernel driver (BYOVD) to elevate to Ring 0.

ETW-Ti provides EDRs with raw, unadulterated visibility into the exact APIs used in advanced injections, such as:

  • NtAllocateVirtualMemory (Cross-process allocations)
  • NtWriteVirtualMemory (Cross-process writes)
  • NtSetContextThread (Thread Hijacking)

When hunting for Next-Gen injection techniques in a SIEM, analysts must pivot from looking at process creation (Event 4688) to cross-process memory access and thread manipulation API calls generated by ETW-Ti (often surfaced in Defender XDR or Sysmon Event 10).

hunt_thread_hijacking.kql
// Detects Thread Context Manipulation (Thread Hijacking) via ETW-Ti telemetry
DeviceEvents
| where ActionType in~ ("SetThreadContextApiCall", "QueueUserApcApiCall")
// Filter out same-process modifications (attackers usually target a remote process)
| where InitiatingProcessId != TargetProcessId
// Focus on target processes commonly abused to hide malicious threads
| where TargetProcessName in~ ("svchost.exe", "explorer.exe", "spoolsv.exe", "lsass.exe", "winlogon.exe")
| project TimeGenerated, DeviceName, InitiatingProcessFileName, TargetProcessName, ActionType, InitiatingProcessCommandLine
| sort by TimeGenerated desc

The arms race between threat actors and Endpoint Detection and Response platforms has pushed Process Injection from simple, noisy disk-based payloads into a realm of extreme, in-memory sophistication.

By mastering Memory Mirroring, Header Clearing, Module Stomping, and Thread Hijacking, adversaries can successfully evade the vast majority of user-space security controls. For Incident Responders and Threat Hunters, relying solely on EDR alerts is no longer sufficient. Securing the modern enterprise requires a profound understanding of Windows memory architecture, proficiency in raw memory forensics (Volatility), and the ingestion of kernel-level telemetry (ETW-Ti) to hunt the ghosts hiding in the machine.