Welcome to Part 3 of our Advanced Malware Tactics – Process Injection blog series. In Part 1, we covered foundational Windows concepts. In Part 2, we introduced process injection as a technique used by attackers to hide code execution inside legitimate processes.

Now in Part 3, we’ll break down the three fundamental building blocks that power all process injection techniques — no matter how complex or stealthy they appear. Once you grasp these, you’ll be able to recognize and understand most injection mechanisms in malware analysis and red team operations.

The Core of All Process Injection

Every type of process injection follows the same fundamental sequence:

Each specific type of process injection may use these primitives in different ways or with different APIs, but the overall concept of injecting code typically follows this sequence.
  1. Allocation – Reserve memory in the target process
  2. Writing – Insert malicious code into the allocated memory
  3. Execution – Run the code within the context of the target process

This sequence doesn’t change, even if the APIs or methods used do.

Why Memory Injection Works in Windows

When you start an application, the operating system creates a process for it. This process has its own private virtual address space.

Normally, each Windows process operates in its own virtual address space. This isolation prevents interference and provides a secure memory boundary. However, Windows (and other OSes) allow interprocess communication (IPC) by design for legitimate use cases like:

legitimate scenarios where one process might need to interact with the memory space of another process
  • Debugging tools
  • Automation and testing
  • Software updates and patching

Attackers abuse this flexibility. By reverse engineering the operating system, they identify how to exploit these permissions and inject code into another process — all without triggering alarms.

Here’s the catch: these legitimate pathways can be a playground for attackers

Step 1 – Allocation (Using VirtualAllocEx)

Before an attacker can write code into another process’s memory, they must first allocate space in the target’s virtual address space. This is done using the API:

Allocation: Before you can write to another process’s memory, you need to allocate some space in that process’s address space. This can be done using functions like VirtualAllocEx, which reserves memory within the context of the target process.

VirtualAllocEx()

This function reserves memory in the context of a target process from user mode. It’s frequently used in legitimate apps — making it a perfect stealth candidate.

Step 2 – Writing (Using WriteProcessMemory)

Once memory has been allocated, the attacker copies their malicious payload into that space using:

Write: WriteProcessMemory() can copy data from the source process to the allocated space in the target process.

WriteProcessMemory()

This function allows one process to write data directly into another process’s memory. Again, it’s a legitimate API — often used in automation and debugging — which makes it harder to flag automatically.

Step 3 – Execution (Using CreateRemoteThread, SetWindowsHookEx, etc.)

This is where things get more diverse. The attacker now needs to run the payload within the target process. There are several APIs for this step, such as:

Execution: Run the program using Windows APIs or System calls.The CreateRemoteThread function, SetWindowsHookEx, and QueueUserAPC are all mechanisms that can be used to execute code in the context of another process or thread in Window
  • CreateRemoteThread() – Launches a new thread in the target process pointing to the injected code
  • SetWindowsHookEx() – Hooks into window message processing
  • QueueUserAPC() – Injects into thread execution flows

The most commonly used and straightforward method is:

CreateRemoteThread: This function creates a thread that runs in the virtual address space of another process. It’s often used in conjunction with WriteProcessMemory to run code in the context of another process. Once CreateRemoteThread is called, the new thread begins execution at the address specified in the call.

CreateRemoteThread()

This API creates a new thread (or “worker”) within the target process, tasked with executing the attacker’s code.

Real-World Example: Why Attackers Use This

Let’s say an attacker targets explorer.exe — a trusted Windows process. By injecting code and executing it from explorer.exe’s context, all the attacker’s activity appears to originate from a legitimate, signed Microsoft binary.

This evades behavioral detection, antivirus scanners, and many EDR solutions — making process injection a powerful post-exploitation tactic.

Because this technique is direct, easy and extensively used over the years, many EDR tools have become capable of detecting and stopping them.

More advanced malware uses alternative APIs or even exploits kernel-level routines (as we’ll see in Part 5).

What to Expect Next

In Part 4, we’ll examine specific types of process injection, such as:

  • DLL Injection
  • Process Hollowing
  • Shim Injection
  • PE Injection

We’ll also look at a real-world Qakbot malware script that performs DLL injection using PowerShell.

Want to follow this series in video format with slides and quizzes?
You can join the free Udemy course here: Advanced Malware Tactics: Process Injection in Windows

Part 4 – Real-World Process Injection: DLL Injection & Qakbot Malware

Leave a comment

Trending