Chapter 26 Β· Concepts

Memory Injection β€” Concepts

Injection technique comparison, the DLL injection API sequence, memory protection mechanisms, and the fileless attack chain.

Injection Technique Comparison

Different injection techniques vary in stealth, required artifacts, and detection approach. Understanding the trade-offs helps defenders prioritize detection rules and understand why attackers choose specific techniques.

TechniqueDisk Artifact?Key APIs / MechanismDetection Method
DLL InjectionYes β€” DLL file on diskVirtualAllocEx, WriteProcessMemory, CreateRemoteThread, LoadLibraryAFile scan for DLL + behavioral EDR on API sequence targeting another process
Reflective DLL InjectionNo β€” DLL image in memory onlyCustom in-memory PE loader; no LoadLibrary callMemory scan for PE headers in non-module-backed regions; RWX memory anomalies; behavioral EDR
Process HollowingNo β€” on-disk file untouched; only in-memory copy replacedCreateProcess(CREATE_SUSPENDED), NtUnmapViewOfSection, WriteProcessMemory, SetThreadContext, ResumeThreadCompare in-memory code sections to on-disk executable hash; parent-process anomaly detection
Thread HijackingNoOpenThread, SuspendThread, GetThreadContext, SetThreadContext, ResumeThreadThread context monitoring; EDR rules on SetThreadContext targeting threads in other processes
Shellcode InjectionNoVirtualAlloc (RWX), WriteProcessMemory, CreateThread or APC queueMemory scan for shellcode byte patterns; detection of RWX memory regions with no module backing; APC queue monitoring

The DLL Injection Step-by-Step

Classic DLL injection uses six steps, each corresponding to a specific Windows API call. Understanding the sequence helps defenders recognize it in EDR telemetry and API monitoring logs.

1
OpenProcess(target PID) β†’ get handle to target
The attacker's process calls OpenProcess with PROCESS_ALL_ACCESS or PROCESS_VM_WRITE | PROCESS_CREATE_THREAD permissions targeting the victim process's PID. This returns a handle that authorizes subsequent operations. Legitimate callers: debuggers, security tools. Suspicious: any non-debugger process opening handles to svchost.exe, explorer.exe, or lsass.exe.
2
VirtualAllocEx(handle, size) β†’ allocate memory in target
Allocates a region of memory inside the target process's virtual address space β€” large enough to hold the DLL file path string. The returned address is a pointer within the target's address space. This memory region is owned by the target process, not the attacker's process.
3
WriteProcessMemory(handle, address, DLL path) β†’ write DLL path into target
Writes the full file system path of the malicious DLL (e.g., "C:\Users\Public\evil.dll") into the memory region allocated in step 2. After this call, the target process's memory contains the DLL path β€” the target doesn't know it yet; nothing has executed.
4
GetProcAddress(kernel32, "LoadLibraryA") β†’ find LoadLibrary address
The attacker's code looks up the address of LoadLibraryA in kernel32.dll. Because ASLR randomizes DLL base addresses per-boot but all processes share the same DLL bases within a given boot, the address of LoadLibraryA in the attacker's process is the same as in the target process β€” a key property that makes this step work.
5
CreateRemoteThread(handle, LoadLibraryA, DLL path address) β†’ create thread that calls LoadLibrary
Creates a new thread inside the target process. The thread's start address is LoadLibraryA, and its parameter (the argument to LoadLibrary) is the address written in step 2 β€” the DLL path. From the OS's perspective, this is a normal LoadLibrary call originating from the target process.
6
DLL loads into target process β†’ DllMain executes
Windows' own loader loads the DLL from disk into the target process's address space, resolves its imports, and calls DllMain with DLL_PROCESS_ATTACH. The malicious DLL's initialization code runs entirely inside the target process. From this point, the DLL can spawn threads, make network connections, access memory β€” all under the target process's identity.

Memory Protections β€” How They Help

Four key memory protections each address a different aspect of the injection attack surface. None is sufficient alone; together they create a significantly higher bar for attackers.

DEP / NX (Data Execution Prevention)

What it does: Marks data memory regions (stack, heap, data segments) as non-executable. The CPU's NX (No-Execute) bit enforces this in hardware β€” an attempt to execute code from a non-executable page triggers a hardware exception.

What it stops: Simple shellcode injection into stack or heap memory. Attacker can write shellcode to these regions but cannot execute it there.

How attackers defeat it: ROP (Return-Oriented Programming) β€” chains of small "gadgets" (sequences of existing instructions ending in RET) from legitimate, already-executable DLL code. The attacker doesn't inject new code; they chain existing code in executable memory to achieve arbitrary computation. No new executable code is needed, so DEP is bypassed.

Exam note: DEP alone is not sufficient. DEP + ASLR together are the baseline β€” ASLR defeats ROP by randomizing gadget addresses.

ASLR (Address Space Layout Randomization)

What it does: Randomizes the base addresses of loaded DLLs, the stack, and the heap at each boot (and optionally at each load). An attacker cannot hardcode memory addresses because they are different on every machine and every boot.

What it stops: Hardcoded-address exploits (classic buffer overflows, return-to-libc), ROP chains that depend on fixed gadget addresses, shellcode that hardcodes API function addresses.

How attackers defeat it: Information-leak vulnerabilities β€” bugs that cause a program to reveal its own memory addresses to the attacker, allowing them to calculate the actual base addresses at runtime. High-Entropy ASLR (64-bit) significantly increases the randomization space, making brute-force guessing impractical.

Exam note: All DLLs in a process must be ASLR-aware (compiled with /DYNAMICBASE) for ASLR to protect them fully. A single non-ASLR DLL in the process can give attackers a fixed address foothold.

CFG (Control Flow Guard)

What it does: At compile time, Microsoft's compiler builds a bitmap of all valid targets for indirect function calls. At runtime, every indirect call is validated against this bitmap before the call executes. If the target is not in the valid-target bitmap, the process terminates.

What it stops: Function pointer hijacking, vtable corruption, callback overwriting β€” any technique that redirects control flow through an indirect call to an attacker-controlled address.

How attackers defeat it: Direct calls (not covered by CFG), calls to valid targets that then chain to attacker-controlled code (if a valid target itself has exploitable behavior), and JIT code regions that may not be covered. CFG is not a complete solution but significantly limits the attacker's control-flow options.

Exam note: CFG requires both compiler support (Visual Studio with /guard:cf) and OS support. Older or third-party DLLs compiled without CFG support break the protection for that code path.

Credential Guard (VBS / VSM)

What it does: Moves LSASS credential storage into a separate lightweight VM running at VTL1 (Virtual Trust Level 1) β€” a higher privilege level than the normal OS kernel (VTL0). Communication between the normal OS and the credential-holding component is through a secure channel; the credential material itself never exists in VTL0 memory.

What it stops: Mimikatz and all other tools that read directly from LSASS memory to extract NTLM hashes, Kerberos tickets, or cleartext credentials. Even with SYSTEM privileges or a kernel exploit in VTL0, the credential material is inaccessible.

Limitations: Protects credentials at rest in LSASS. Does not protect credentials during active authentication operations (brief window). Does not protect credentials stored in other locations (SAM, DPAPI, browser stores). Does not prevent pass-the-hash with credentials stolen before Credential Guard was enabled.

Exam note: Credential Guard requires Windows 10/11 Enterprise, UEFI with Secure Boot, and hardware virtualization (Intel VT-x / AMD-V). Not available on Home or Pro editions without specific configuration.

The Fileless Attack Chain

Modern fileless attacks chain multiple techniques together. Each step avoids writing files to disk. The complete chain from initial access to domain compromise can occur entirely in memory.

1
Phishing email with macro
A malicious Office document arrives via email. The document contains a VBA macro. When the user enables macros, the macro executes β€” entirely within the Office process's memory. No file is written. The macro's payload is the next stage.
2
Macro runs PowerShell in memory
The macro calls PowerShell with an encoded command (base64-encoded to evade basic string matching). The PowerShell command is an in-memory download cradle β€” it fetches content from the internet and executes it entirely in memory using IEX (Invoke-Expression), never writing the downloaded content to disk.
3
PowerShell downloads shellcode (no file written)
The download cradle retrieves shellcode or a reflective DLL from an attacker-controlled URL over HTTPS. The content is stored in a PowerShell byte array variable in memory β€” never written to the filesystem. Standard web proxies may not flag the download because it uses HTTPS to a domain with a clean reputation (often a compromised legitimate site or a cloud service).
4
Shellcode injects into svchost.exe
The PowerShell process uses the VirtualAllocEx / WriteProcessMemory / CreateRemoteThread triad (or a variation) to inject the shellcode or reflective DLL into svchost.exe. The PowerShell process may then exit, leaving no running attacker-owned process.
5
C2 channel established
The injected code β€” now running inside svchost.exe β€” establishes a command-and-control (C2) connection to an attacker-controlled server over HTTPS (port 443), blending with normal web traffic. The beacon sends periodic check-ins; the attacker issues commands through this channel. EDR may flag svchost.exe making unusual external HTTPS connections.
6
Credential dump from LSASS
Via the C2 channel, the attacker injects a credential-harvesting module into a process with SYSTEM privileges. The module reads NTLM hashes and Kerberos tickets from LSASS memory. These credentials enable lateral movement. On systems with Credential Guard, this step fails β€” the credential material is in VTL1 and inaccessible.
7
Lateral movement β€” all without a malicious file on disk
Using harvested NTLM hashes (pass-the-hash) or Kerberos tickets (pass-the-ticket), the attacker authenticates to other machines using legitimate credentials. Remote execution via built-in Windows tools (PsExec, WMI, scheduled tasks) β€” all legitimate. The attack propagates across the network. Zero malicious files written to disk at any stage.