逆向KeInitializeApc KiInsertQueueApc
作者:互联网
逆向:
KiDeliverApc:派发APC
ApcEnvironment:APC环境
KeInitialiZeApc:初始化APC
KiDeliverApc:派发APC
ApcEnvironment:APC环境
0.无论挂靠不挂靠都插入到原始环境
1.无论挂靠不挂靠都插入到挂靠环境
2.选择插入,初始化APC函数中判断一下当前是挂靠还是不挂靠环境
如果线程ApcStateIndex=0,插入到原始环境,否则插入到挂靠环境
3.选择插入,初始化函数不插入,插入APC函数的时候再选择插入
switch(ApcEnvironment)
{
case 0.无论挂靠不挂靠都插入到原始环境
break;
case 1.无论挂靠不挂靠都插入到挂靠环境
break;
case 2.选择插入,初始化APC函数中判断一下当前是挂靠还是不挂靠环境
如果线程ApcStateIndex=0,插入到原始环境,否则插入到挂靠环境
break;
case 3.选择插入,初始化函数不插入,插入APC函数的时候再选择插入
break;
}
_KAPC_STATE
+0x000 ApcListHead : [2] _LIST_ENTRY // APC队列,两个双向链表,分别指向用户与内核结构的APC
+0x010 Process : Ptr32 _KPROCESS // 线程所属的进程或者挂靠的进程
+0x014 KernelApcInProgress : UChar // 表示当前内核中的APC程序是否正在执行
+0x015 KernelApcPending : UChar // 表示APC队列中是否有内核APC函数,如果有为1,否则为0.
+0x016 UserApcPending : UChar // 表示APC队列中是否用用户APC函数,如果有为1,否则为0.
struct _KAPC
{
UCHAR Type; //0x0
UCHAR SpareByte0; //0x1
UCHAR Size; //0x2
UCHAR SpareByte1; //0x3
ULONG SpareLong0; //0x4
struct _KTHREAD* Thread; //0x8
struct _LIST_ENTRY ApcListEntry; //0xc
VOID (KernelRoutine) 内核函数 //0x14
VOID (RundownRoutine) 特殊函数暂时未知 //0x18
VOID (NormalRoutine)(VOID arg1, VOID arg2, VOID arg3); 如果是用户APC必写 //0x1c
VOID* NormalContext; ;参数 //0x20
VOID* SystemArgument1; ;参数 //0x24
VOID* SystemArgument2; ;参数 //0x28
CHAR ApcStateIndex; //0x2c
CHAR ApcMode; ==0内核APC结构,==1用户APC结构 //0x2d
UCHAR Inserted; ;这里插入完之后就变成1 变成1后就不能再被插入了 //0x2e
};
APC初始化:手动还原的
NTKERNELAPI
VOID
KeInitializeApc (
__out PRKAPC Apc,
__in PRKTHREAD Thread,
__in KAPC_ENVIRONMENT Environment,
__in PKKERNEL_ROUTINE KernelRoutine,
__in_opt PKRUNDOWN_ROUTINE RundownRoutine,
__in_opt PKNORMAL_ROUTINE NormalRoutine,
__in_opt KPROCESSOR_MODE ProcessorMode,
__in_opt PVOID NormalContext
);
{
Apc.Type=0x12;
Apc.Size=0x30;
//判断APC环境
if(Environment==2)
{
Apc.ApcStateIndex=Thread->ApcStateIndex;
}
else
{
Apc.ApcStateIndex=Environment;
}
Apc.Thread=Thread;
Apc.KernelRoutine=KernelRoutine;
Apc.RundownRoutine=OPTIONAL
Apc.NormalRoutine=OPTIONAL1
if(OPTIONAL1!=0)
{
Apc.ApcMode=OPETIONAL2;
Apc.NormalContext=OPETIONAL3;
}
else
{
Apc.ApcMode=0;
Apc.NormalContext=0;
}
Apc.Inseted=0;
return ;
}
直接从WRK扣的
APC派发:
VOID
FASTCALL
KiInsertQueueApc (
IN PKAPC Apc,
IN KPRIORITY Increment
)
{
KPROCESSOR_MODE ApcMode;
PKAPC ApcEntry;
PKAPC_STATE ApcState;
PKGATE GateObject;
PLIST_ENTRY ListEntry;
PKQUEUE Queue;
BOOLEAN RequestInterrupt;
PKTHREAD Thread;
KTHREAD_STATE ThreadState;
Thread = Apc->Thread;
if (Apc->ApcStateIndex == InsertApcEnvironment) {
Apc->ApcStateIndex = Thread->ApcStateIndex;
}
ApcState = Thread->ApcStatePointer[Apc->ApcStateIndex];
ApcMode = Apc->ApcMode;
ASSERT (Apc->Inserted == TRUE);
if (Apc->NormalRoutine != NULL) {
if ((ApcMode != KernelMode) && (Apc->KernelRoutine == PsExitSpecialApc)) {
Thread->ApcState.UserApcPending = TRUE;
InsertHeadList(&ApcState->ApcListHead[ApcMode],
&Apc->ApcListEntry);
} else {
InsertTailList(&ApcState->ApcListHead[ApcMode],
&Apc->ApcListEntry);
}
} else {
ListEntry = ApcState->ApcListHead[ApcMode].Blink;
while (ListEntry != &ApcState->ApcListHead[ApcMode]) {
ApcEntry = CONTAINING_RECORD(ListEntry, KAPC, ApcListEntry);
if (ApcEntry->NormalRoutine == NULL) {
break;
}
ListEntry = ListEntry->Blink;
}
InsertHeadList(ListEntry, &Apc->ApcListEntry);
}
if (Apc->ApcStateIndex == Thread->ApcStateIndex) {
if (Thread == KeGetCurrentThread()) {
ASSERT(Thread->State == Running);
if (ApcMode == KernelMode) {
Thread->ApcState.KernelApcPending = TRUE;
if (Thread->SpecialApcDisable == 0) {
KiRequestSoftwareInterrupt(APC_LEVEL);
}
}
return;
}
RequestInterrupt = FALSE;
KiLockDispatcherDatabaseAtSynchLevel();
if (ApcMode == KernelMode) {
Thread->ApcState.KernelApcPending = TRUE;
KeMemoryBarrier();
ThreadState = Thread->State;
if (ThreadState == Running) {
RequestInterrupt = TRUE;
} else if ((ThreadState == Waiting) &&
(Thread->WaitIrql == 0) &&
(Thread->SpecialApcDisable == 0) &&
((Apc->NormalRoutine == NULL) ||
((Thread->KernelApcDisable == 0) &&
(Thread->ApcState.KernelApcInProgress == FALSE)))) {
KiUnwaitThread(Thread, STATUS_KERNEL_APC, Increment);
} else if (Thread->State == GateWait) {
KiAcquireThreadLock(Thread);
if ((Thread->State == GateWait) &&
(Thread->WaitIrql == 0) &&
(Thread->SpecialApcDisable == 0) &&
((Apc->NormalRoutine == NULL) ||
((Thread->KernelApcDisable == 0) &&
(Thread->ApcState.KernelApcInProgress == FALSE)))) {
GateObject = Thread->GateObject;
KiAcquireKobjectLock(GateObject);
RemoveEntryList(&Thread->WaitBlock[0].WaitListEntry);
KiReleaseKobjectLock(GateObject);
if ((Queue = Thread->Queue) != NULL) {
Queue->CurrentCount += 1;
}
Thread->WaitStatus = STATUS_KERNEL_APC;
KiInsertDeferredReadyList(Thread);
}
KiReleaseThreadLock(Thread);
}
} else if ((Thread->State == Waiting) &&
(Thread->WaitMode == UserMode) &&
(Thread->Alertable || Thread->ApcState.UserApcPending)) {
Thread->ApcState.UserApcPending = TRUE;
KiUnwaitThread(Thread, STATUS_USER_APC, Increment);
}
KiUnlockDispatcherDatabaseFromSynchLevel();
if (RequestInterrupt == TRUE) {
KiRequestApcInterrupt(Thread->NextProcessor);
}
}
return;
}
标签:ApcMode,逆向,挂靠,Thread,KeInitializeApc,插入,APC,Apc,KiInsertQueueApc 来源: https://blog.csdn.net/ADADQDQQ/article/details/119462039