相关定义
下面两个函数kernel导出了,但是没有声明,需要声明下才能用
typedef enum _KAPC_ENVIRONMENT {
OriginalApcEnvironment,
AttachedApcEnvironment,
CurrentApcEnvironment
} KAPC_ENVIRONMENT;
VOID __stdcall KeInitializeApc(
IN PRKAPC Apc,
IN PKTHREAD Thread,
IN KAPC_ENVIRONMENT Environment,
IN PKKERNEL_ROUTINE KernelRoutine,
IN PKRUNDOWN_ROUTINE RundownRoutine OPTIONAL,
IN PKNORMAL_ROUTINE NormalRoutine OPTIONAL,
IN KPROCESSOR_MODE ApcMode,
IN PVOID NormalContext
);
BOOLEAN __stdcall KeInsertQueueApc(
IN PRKAPC Apc,
IN PVOID SystemArgument1,
IN PVOID SystemArgument2,
IN KPRIORITY Increment
);
KAPC在wdm.h中定义了,如下
typedef struct _KAPC {
UCHAR Type;
UCHAR SpareByte0;
UCHAR Size;
UCHAR SpareByte1;
ULONG SpareLong0;
struct _KTHREAD *Thread;
LIST_ENTRY ApcListEntry;
PKKERNEL_ROUTINE KernelRoutine;
PKRUNDOWN_ROUTINE RundownRoutine;
PKNORMAL_ROUTINE NormalRoutine;
PVOID NormalContext;
//
// N.B. The following two members MUST be together.
//
PVOID SystemArgument1;
PVOID SystemArgument2;
CCHAR ApcStateIndex;
KPROCESSOR_MODE ApcMode;
BOOLEAN Inserted;
} KAPC, *PKAPC, *PRKAPC;
APC说明
APC提供了一个在特定线程环境中执行代码的方法,每个线程维护自己的APC队列,它们分为UserMode和KernelMode,由两个单独的队列管理。KernelMode APC又分为Normal和Special,Special APC在Normal APC之前分发。
(由于线程可以attach到另一个进程,所以APC队列有两份,它们在attach和detach的时候切换)
在KAPC中,KernelMode APC和UserMode APC是通过ApcMode区分的;Normal和Special是通过NormalRoutine区分的,为NULL则为Special。
KernelRoutine/RundownRoutine在APC IRQL执行;NormalRoutine在Passive IRQL执行。
APC与代码充入
线程的正常执行流可能会被APC打断,这在内核驱动IRP处理中可能会导致死锁,可以同过KeEnterCriticalRegion禁用Normal APC分发,KeEnterGuardedRegion则会禁用所有APC分发。
使用APC
在用户态可以使用QueueUserAPC,它需要目标线程进入可唤醒的等待(Alertable)。
最上面列的两个函数是核心态中调用,这个不是公开的,但可以使用(从2000到WIN7都可以);驱动可以通过它们和用户态控制程序做交互,直接在用户态执行代码(NormalRoutine)
浙公网安备 33010602011771号