Credit to repnz for the article on User-APC!

APC Series: User APC API

https://learn.microsoft.com/en-us/windows/win32/sync/asynchronous-procedure-calls

Book ref : windows Internal Part 1: Chapter 6, Windows Internal Part 2 : Chapter 8

Types of User-Mode APCs

First. QueueUserAPC and NtQueueAPCThread

I have not personally verified it. Just to take notes as I go

  1. User-Mode APC queued to alertable thread by using QueueUserAPC.
    1. Under the hood, QueueUserAPC: KernelBase.dll is a wrapper for NtQueueApcThread which is used to create contextRecord and setup the actual APC routine to thread.

Second. NtQueueAPCThreadEx - Special User APC

  1. Memory Reserve Objecj It allows to reserve memory for certain objects in kernel mode and later when the object is freed use the same memory area to store another objects
  2. NtQueueApcThreadEx to support special user APCs by turning the MemoryReserveHandle into a union:
typedef enum _QUEUE_USER_APC_FLAGS {
	QueueUserApcFlagsNone,
	QueueUserApcFlagsSpecialUserApc,
	QueueUserApcFlagsMaxValue
} QUEUE_USER_APC_FLAGS;

typedef union _USER_APC_OPTION {
	ULONG_PTR UserApcFlags; // this is QUEUE_USER_APC_FLAGS struct.
	HANDLE MemoryReserveHandle;
} USER_APC_OPTION, *PUSER_APC_OPTION;

NTSTATUS
NtQueueApcThreadEx(
	IN HANDLE ThreadHandle,
	IN USER_APC_OPTION UserApcOption,
	IN PPS_APC_ROUTINE ApcRoutine,
	IN PVOID SystemArgument1 OPTIONAL,
	IN PVOID SystemArgument2 OPTIONAL,
	IN PVOID SystemArgument3 OPTIONAL
	);

  1. NtQueueApcThreadEx2 QueueUserAPC2 wrapper function for NtQueueApcThreadEx2

NtTestAlert

cause execution of any pending APCs the thread has.

Side Quest