相关定义

下面两个函数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)

posted on 2010-11-22 22:30  某某人  阅读(560)  评论(0)    收藏  举报