学习Windows进程,APC肯定少不了啦。
PS:由于本人才疏智浅,本文仅为个人学习笔记,如有错误,希望大牛不吝赐教。
下面是我学习APC的一点笔记。
1、什么是APC
APC就是异步过程调用的所写。据说PE格式DLL映像的装入和动态连接就是由ntdll.dll中的函数LdrInitializeThunk作为APC函数执行完成的(这个还没具体研究)。
2、QueueUserAPC():
Win32API提供了一个函数,用于应用层的APC插入。
DWORD WINAPI QueueUserAPC(
__in PAPCFUNC pfnAPC,
__in HANDLE hThread,
__in ULONG_PTR dwData
);
该API下面会调用NtQueueApcThread()系统调用,参考ReactOS源代码调用如下:
DWORD WINAPI QueueUserAPC(__in PAPCFUNC pfnAPC, __in HANDLE hThread, __in ULONG_PTR dwData)
{
NTSTAUS Status;
Status = NtQueueApcThread(hThread, IntCallUserApc, pfnAPC, (PVOID)dwData, NULL);
if(Status)
...;
return NT_SUCCESS(Status);
}
其中pfnAPC为用户插入的APC,IntCallUserApc是kernel32.dll内部的一个函数,是APC的统一调度接口,后面会详细介绍。
3、APC结构:
APC是针对具体线程的,要求有具体线程执行的。有KTHREAD结构可以看出线程的APC队列;参考WRK的KTHREAD定义
typedef struct _KTHREAD {
...
union {
KAPC_STATE ApcState; //当前线程在当前进程上下文下的APC队列
struct {
UCHAR ApcStateFill[KAPC_STATE_ACTUAL_LENGTH];
BOOLEAN ApcQueueable;
volatile UCHAR NextProcessor;
volatile UCHAR DeferredProcessor;
UCHAR AdjustR