APC Injection — Execution via Asynchronous Procedure Call Queues

What are APCs

An APC (Asynchronous Procedure Call) is a Windows mechanism that allows queuing a function to be executed in the context of a specific thread when that thread enters an alertable wait state — a wait that accepts the execution of pending procedures.

Windows uses APCs extensively internally: for asynchronous I/O operations, mutex notifications, and DLL loading. The Windows APC model has two types:

  • Kernel APC: Executed when the thread returns to user mode, by the kernel. Cannot be created by user code.

  • User APC: Queued via QueueUserAPC or NtQueueApcThread. Executed when the thread calls functions like SleepEx, WaitForSingleObjectEx, MsgWaitForMultipleObjectsEx with bAlertable = TRUE.

┌──────────────────────────────────────────────────────────────────────┐
│                    APC Execution Flow                                │
│                                                                      │
│  Target thread in normal state:                                       │
│  [normal execution] → [calls WaitForSingleObjectEx(bAlertable=TRUE)]│
│                                │                                     │
│                    Enters alertable wait                             │
│                                │                                     │
│  Attacker queues APC: ─────────▶ QueueUserAPC(shellcode, hThread)  │
│                                │                                     │
│                    Thread wakes up to execute APCs                   │
│                                │                                     │
│                    [executes shellcode in thread context]            │
│                                │                                     │
│                    Returns to thread's normal state                  │
└──────────────────────────────────────────────────────────────────────┘

Technique 1: Classic APC Injection

The basic technique: allocate shellcode in the target process, find threads in alertable wait, and queue the shellcode as an APC.

Critical limitation: The APC only executes when the thread enters an alertable wait. If threads of the target process never enter this state, the shellcode never executes. GUI applications frequently call MsgWaitForMultipleObjectsEx with alertable enabled, but not always.


Technique 2: Early Bird APC Injection

The Early Bird technique elegantly solves the alertable wait problem: it creates the target process in a suspended state (the main thread is suspended before executing any code), injects the shellcode via APC, and then resumes the thread.

When the suspended thread is resumed, Windows executes pending APCs before executing the process's normal initialization code — which is why the technique is called "Early Bird."


Technique 3: NtQueueApcThread — APC via Native API

To avoid hooks on QueueUserAPC (which goes through kernel32.dll), we can use NtQueueApcThread directly from ntdll.dll:


Technique 4: APC via NtQueueApcThreadEx (Special User APC — Windows 10+)

Windows 10 introduced NtQueueApcThreadEx with support for Special User APCs — a new type that executes regardless of the thread's alertable state. This resolves the main limitation of classic APC.


Variant Comparison


Detection

  • Sysmon Event ID 8 (CreateRemoteThread): Doesn't capture APC directly, but EDRs with kernel callbacks register QueueUserAPC via ETW.

  • CREATE_SUSPENDED + QueueUserAPC sequence: Characteristic pattern of Early Bird.

  • NtQueueApcThreadEx with special flag: Usage by legitimate applications is extremely rare — highly suspicious.

  • Memory scan: Shellcode in a private executable region is still detectable via memory scanning.


References

  • Tal Liberman, "Atombombing" — ensilo.com (2016)

  • ired.team, "APC Queue Code Injection" — ired.team/offensive-security/code-injection-process-injection/

  • Crow, "APC Injection Variants" — crow.rip (2019)

  • MITRE ATT&CK, "T1055.004 — Asynchronous Procedure Call" — attack.mitre.org

  • Windows Internals 7th Edition, "Chapter 3: System Mechanisms — APCs"

  • Elastic Security Labs, "Process Injection via APC" — elastic.co/security-labs

  • Sektor7, "Early Bird APC Code Injection" — sektor7.net

Last updated