本文主要是介绍APC的内部实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
一个经典的投放apc结束线程是这样的
KeInitializeApc(exitAPC,ethread,OriginalApcEnvironment,KernelKillThreadRoutine,0,0,KernelMode,0);KeInsertQueueApc(exitAPC,exitAPC,NULL,2);
1.APC结构
typedef struct _KAPC {UCHAR Type;UCHAR SpareByte0;UCHAR Size;UCHAR SpareByte1;ULONG SpareLong0;struct _KTHREAD *Thread;LIST_ENTRY ApcListEntry; // 插入线程APC链表PKKERNEL_ROUTINE KernelRoutine; 内核模式中执行PKRUNDOWN_ROUTINE RundownRoutine; //线程终止时还有APC没执行会调用这个函数?
PKNORMAL_ROUTINE NormalRoutine; // 这个为0 表示是一个特殊内核APC,否则是一个普通的(又分为内核态的和用户态的)。特殊的位于链表前部,普通的位于后部。 普通的APC,normal和kernel例程都将被调用PVOID NormalContext;PVOID SystemArgument1;PVOID SystemArgument2;CCHAR ApcStateIndex; // APC环境状态KPROCESSOR_MODE ApcMode; //内核态or用户态BOOLEAN Inserted;
} KAPC, *PKAPC, *PRKAPC;
2.关于APC的环境
这个枚举指的是指示线程attach之后 再回来的情形
typedef enum _KAPC_ENVIRONMENT {OriginalApcEnvironment, //原始的进程环境AttachedApcEnvironment, //挂靠后的进程环境CurrentApcEnvironment, // 当前环境InsertApcEnvironment // 被插入时的环境
} KAPC_ENVIRONMENT;
typedef struct _KAPC_STATE {LIST_ENTRY ApcListHead[MaximumMode];//线程的apc链表 只有两个 内核态和用户态struct _KPROCESS *Process; // 线程 挂靠的进程 BOOLEAN KernelApcInProgress; // 线程正在处理APC对象BOOLEAN KernelApcPending; // 线程有内核apc等待交付BOOLEAN UserApcPending; // 有用户态的等待
} KAPC_STATE, *PKAPC_STATE, *PRKAPC_STATE;
KTHREAD 中的KAPC_STATE 中有两个 ApcState ,
ApcState和SaveApcState,
ApcStatePointer是个数组,ApcStateIndex是下标
这篇关于APC的内部实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!