无论是正常状态还是挂靠状态,都有两个APC队列,一个内核队列,一个用户队列。
每当要挂入一个APC函数时,不管是内核APC还是用户APC,内核都要准备一个KAPC的数据结构,并且将这个KAPC结构挂到相应的APC队列中。
kd> dt _kapc
nt!_KAPC
+0x000 Type //类型APC类型为0x12
+0x002 Size //本结构体的大小0x30
+0x004 Spare0 //未使用
+0x008 Thread //目标线程
+0x00c ApcListEntry //APC队列挂的位置
+0x014 KernelRoutine //指向一个函数(调用ExFreePoolWithTag释放APC)
+0x018 RundownRoutine //未使用
+0x01c NormalRoutine //用户APC总入口或者真正的内核apc函数
+0x020 NormalContext //内核APC: NULL用户APC:真正的APC函数
+0x024 SystemArgument1 //APC函数的参数
+0x028 SystemArgument2 //APC函数的参数
+0x02c ApcStateIndex //挂哪个队列,有四个值: 0 1 2 3
+0x02d ApcMode //内核APC用户APC
+0x02e Inserted //表示本apc是否已挂入队列挂入前: 0挂入后1
+0x000 Type
APC的类型为0x12,windows下任何一