In red teaming, stealth is everything. The moment your tools are caught, your operation is over. Red teamers don’t just launch malware – they blend into trusted processes, borrow privileges, and move silently. One of the most effective ways to do this is DLL injection.

This guide covers what DLL injection is, how it works, why it’s valuable to red teamers, and how to evade modern defenses while using it.


What is DLL Injection?

DLL injection is a technique that forces a legitimate, already-running process to load a DLL (Dynamic Link Library) that you control. Once loaded, your code runs inside that trusted process’s memory space.

This is not the same as DLL sideloading, which tricks a process into loading a malicious DLL during startup. DLL injection happens at runtime and is typically used after you already have code execution on the target system.


Why Red Teamers Use DLL Injection

  • Stealth: Running inside a trusted process like explorer.exe or svchost.exe helps avoid detection.
  • Persistence: Many target processes are long-lived or automatically restarted by the system.
  • Privilege Inheritance: Injecting into a high-privileged process lets your code run with elevated rights.
  • EDR Evasion: Well-crafted injection can bypass endpoint detection tools, especially when used with in-memory execution and custom loaders.

How DLL Injection Works – Step by Step

Let’s walk through how the classic LoadLibrary DLL injection technique works, and more importantly – why the injected code actually runs.

  1. Choose a Target Process
    Select a legitimate process that’s already running. This could be something like notepad.exe, explorer.exe, or a system process like svchost.exe.
  2. Open a Handle to the Process
    Use the OpenProcess() API to obtain access to the process. You’ll need permissions like PROCESS_VM_WRITE and PROCESS_CREATE_THREAD to write to its memory and start a new thread.
  3. Allocate Memory in the Target Process
    Call VirtualAllocEx() to reserve memory inside the target process. This is where you’ll store the full path to your malicious DLL.
  4. Write the DLL Path into Memory
    Use WriteProcessMemory() to write the string (e.g., "C:\\Users\\Public\\evil.dll") into the allocated memory inside the target.
  5. Create a Remote Thread to Load the DLL
    This is the critical part. You now create a remote thread inside the target process using CreateRemoteThread(), and set it to run LoadLibraryA(), passing it the pointer to the DLL path you just wrote.

So, why does the DLL actually run?

Because calling LoadLibraryA() causes the operating system to do two things:

  • Load your DLL into the process’s memory space.
  • Automatically execute its entry point: the DllMain() function.

Inside DllMain(), you typically write code that spawns a new thread or runs your payload directly. For example:

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) {
    if (fdwReason == DLL_PROCESS_ATTACH) {
        CreateThread(NULL, 0, MyPayload, NULL, 0, NULL);
    }
    return TRUE;
}

As soon as LoadLibraryA is called, your DllMain() is invoked with DLL_PROCESS_ATTACH, and your payload thread is created. This is how your code is actually executed – not by the victim process choosing to run it, but because you forced it through the injection mechanism.


Other DLL Injection Techniques

While LoadLibraryA injection is the classic method, many variants exist:

  • Reflective DLL Injection: Loads a DLL entirely from memory without using LoadLibrary, ideal for fileless attacks.
  • Manual Mapping: Re-implements the Windows loader manually to avoid detection by user-mode API hooks.
  • APC Injection: Queues code into a thread’s Asynchronous Procedure Call (APC) queue to execute at the next opportunity.
  • Thread Hijacking: Suspends an existing thread, modifies its context to point to your shellcode, and resumes it.

Each technique has different stealth properties and evasion benefits.


You’ve Probably Used DLL Injection Without Realizing It

If you’ve ever used tools like Mimikatz or Metasploit’s Meterpreter, chances are you’ve already used DLL injection, even if you didn’t know it at the time.

Example 1: Mimikatz and LSASS

When you run this Mimikatz command: sekurlsa::logonpasswords

You’re asking Mimikatz to dump credentials stored in memory by LSASS (lsass.exe) – a process that holds sensitive data like password hashes and Kerberos tickets.

But LSASS won’t just hand that information over. So Mimikatz:

  1. Opens a handle to the LSASS process.
  2. Writes a small chunk of code (a DLL or shellcode) into LSASS’s memory.
  3. Creates a thread inside LSASS that runs that code.
  4. Extracts the secrets directly from memory.

That’s DLL injection: code is inserted into another process and executed from within.

Example 2: Meterpreter’s migrate Command

If you’ve ever used the command: migrate <PID> in a Meterpreter session, you’ve used DLL injection.

Here’s what’s really happening:

  1. You exploit a process – let’s say you get a shell inside word.exe.
  2. But you want to move your implant into a more stable or trusted process, like explorer.exe.
  3. So you tell Meterpreter to migrate.
  4. Meterpreter:
    • Opens a handle to explorer.exe.
    • Injects a small DLL or reflective payload into it.
    • Creates a thread to execute it.
    • Shuts down the original session.

From that point on, your session is now running inside explorer.exe.

Why? Because explorer.exe:

  • Runs continuously (even if Word closes),
  • Has more privileges,
  • Looks less suspicious to defenders.

Again, this is DLL injection in action – it just happens automatically behind the scenes.


By recognizing that these tools rely on injection, you not only understand what’s really happening but also become better at:

  • Evading detection,
  • Writing custom payloads,
  • Explaining your techniques in reports or interviews.

If you’ve ever dumped creds or migrated sessions – you’ve injected a DLL. Now you just know the anatomy of how it works.


EDR Detection and Evasion

Modern EDRs watch for common injection patterns, including:

  • Calls to WriteProcessMemory or CreateRemoteThread
  • Use of suspicious APIs like VirtualAllocEx
  • Unusual memory allocation behavior
  • Processes loading unexpected DLLs
  • Inconsistent parent-child relationships (e.g., winword.exe spawning rundll32.exe)

To evade detection, advanced red teamers use strategies like:

  • Direct System Calls: Bypass user-mode API hooks by invoking syscalls directly.
  • Syscall Stubs: Use obfuscated or randomized syscall wrappers to avoid behavioral signatures.
  • Encrypted Shellcode: Store payloads in encrypted form and decrypt only in memory before execution.
  • Custom Loaders: Avoid GitHub tools or known frameworks. Write your own loader in C, Rust, or Nim.
  • Signed Binary Abuse: Use trusted system tools (like rundll32.exe or regsvr32.exe) to execute malicious code.
  • Parent Process Spoofing: Forge the parent process of your injected code to mimic normal behavior.

Real-World Red Team Scenario

Let’s say you successfully phish a user and land a shell on their workstation.

Rather than drop an EXE and risk detection, you:

  1. Generate shellcode for your C2 beacon (e.g., Cobalt Strike).
  2. Wrap it in a small custom loader that injects into a target process.
  3. Choose explorer.exe as the host – a common, long-running process.
  4. Use reflective injection to load the beacon entirely in memory.
  5. Set a long sleep interval and jitter to reduce beaconing noise.

The result: a stealthy, persistent implant that lives inside a trusted Windows process, largely invisible to detection tools.


Defensive Insight

For blue teams, detecting DLL injection requires multiple layers of visibility:

  • Monitor suspicious API usage (e.g., CreateRemoteThread, LoadLibrary, VirtualAllocEx)
  • Correlate unusual thread starts with foreign DLL loads
  • Watch for mismatched parent-child process trees
  • Detect memory regions with executable permissions and no backing file (common for injected shellcode)
  • Use Sysmon or ETW for fine-grained telemetry on memory operations and thread injection

Final Thoughts

DLL injection is a foundational red team technique – simple in principle, but powerful in practice. It allows operators to run code inside trusted processes, hide in plain sight, and avoid common detection mechanisms.

Understanding how DLL injection really works – especially how LoadLibraryA triggers execution via DllMain() – is key to using it effectively and stealthily. Paired with custom loaders and evasive methods, it remains one of the most flexible tools in a red teamer’s arsenal.

Leave a comment

Your email address will not be published. Required fields are marked *