查看文章
 
PN3 += PN2?
2008-08-18 1:24

还有一个礼拜就要开学了...
开学了就要军训了, 军训完就要忙了, 可能也就没时间写程序了.
考虑了一下, 还是用最后一个礼拜把 PN 完善一下吧.

顺便公布一下某原创定位内核函数的方法 (PN1 开始采用):

--- dispatch.c (part) ---

/*++

Routine description:
Detour KeInsertQueueApc to locate PsExitSpecialApc, PspExitApcRundown
and PspExitNormalApc.

Input:
0x0 - Supplies the ID of the temporary thread to be terminated

Output:
0x0 - Status of call

--*/

ULONG PN3InitializeApc(PULONG inPlain, ULONG inPlainLength, PULONG outPlain, ULONG outPlainLength)
{
HANDLE hThread = 0;
OBJECT_ATTRIBUTES oa = {0};
CLIENT_ID cli;
NTSTATUS Status;
PETHREAD Thread;
KIRQL OldIrql;
KPROCESSOR_MODE PreviousMode;

if (inPlainLength < 4 || outPlainLength < 4) return 0;

// Temporarily disable the process protect
Status = PsLookupThreadByThreadId((HANDLE)inPlain[0], &VictimThread);
if (!NT_SUCCESS(Status)) {
   *outPlain = 0;
   return 4;
}
ObDereferenceObject(VictimThread);

// Open the thread
Status = ObOpenObjectByPointer(VictimThread,
           0,
           NULL,
           0,
           NULL,
           KernelMode,
           &hThread);

if (!NT_SUCCESS(Status) || hThread == 0) {
   VictimThread = 0;
   *outPlain = 0;
   return 4;
}

// Terminate the thread with detour of KeInsertQueueApc
PreviousMode = SetCurrentThreadProcessorMode(KernelMode);
KeAcquireSpinLock(&HookApcSpinLock, &OldIrql);
EnableKeInsertQueueApcHook(TRUE);
NtTerminateThread(hThread, 0);
EnableKeInsertQueueApcHook(FALSE);
KeReleaseSpinLock(&HookApcSpinLock, OldIrql);
NtClose(hThread);
SetCurrentThreadProcessorMode(PreviousMode);

// Enable the process protect
VictimThread = NULL;

// Test if our special apcs are presented
if (PsExitSpecialApc == NULL) {
   *outPlain = 0;
} else {
   *outPlain = 1;
}
return 4;
}

--- hookapc.c ---

#include <ntddk.h>
#include <pn3hook.h>
#include <pn3imp.h>
#include <pn3misc.h>

ULONG ApcHookLen = 0;
BOOLEAN ApcFoundNop = FALSE;
PETHREAD VictimThread = NULL;
PVOID PsExitSpecialApc = NULL, PspExitApcRundown = NULL, PspExitNormalApc = NULL;
UCHAR BackupKeInsertQueueApc[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
UCHAR RealKeInsertQueueApc[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};

VOID KeInsertQueueApcNotify(PETHREAD Thread, PVOID KernelRoutine, PVOID RundownRoutine, PVOID NormalRoutine)
{
if (Thread == VictimThread &&
   KernelRoutine != NULL &&
   NormalRoutine != NULL &&
   PsExitSpecialApc == NULL &&
   (ULONG)KernelBase < (ULONG)KernelRoutine &&
   (ULONG)KernelBase + KernelSize > (ULONG)KernelRoutine) {
   PsExitSpecialApc = KernelRoutine;
   PspExitApcRundown = RundownRoutine;
   PspExitNormalApc = NormalRoutine;
}
}

BOOLEAN __stdcall HookedKeInsertQueueApc(IN PKAPC Apc,
        IN PVOID SystemArgument1,
        IN PVOID SystemArgument2,
        IN KPRIORITY Increment) {
KeInsertQueueApcNotify((PETHREAD)Apc->Thread,
         Apc->KernelRoutine,
         Apc->RundownRoutine,
         Apc->NormalRoutine);
return ((KEINSERTQUEUEAPC)RealKeInsertQueueApc)(Apc,
              SystemArgument1,
              SystemArgument2,
              Increment);
}

VOID EnableKeInsertQueueApcHook(BOOLEAN Enable)
{
PUCHAR Ptr = (PUCHAR)KeInsertQueueApc;
KIRQL OldIrql;

// Unhook, no matter what we're gonna do
if (ApcHookLen != 0) {
   if (ApcFoundNop) Ptr += 2;
   OldIrql = KeRaiseIrqlToDpcLevel();
   CliAndDisableWP();
   RtlMoveMemory(Ptr, BackupKeInsertQueueApc, ApcHookLen);
   EnableWPAndSti();
   KeLowerIrql(OldIrql);
   ApcHookLen = 0;
}

if (Enable) {

   // Test if there's any NOPs
   // It's important for keeping compatibility with KV2008
   if (*(PUSHORT)Ptr == 0xff8b) {
    ApcFoundNop = TRUE;
    Ptr += 2;
   } else {
    ApcFoundNop = FALSE;
   }

   // Measure the code length to be copied
   ApcHookLen = MeasureCodeLength(Ptr, 5);
   if (ApcHookLen == 0 || ApcHookLen > 11) {
    ApcHookLen = 0;
    return;
   }

   // Copy the code
   RtlMoveMemory(BackupKeInsertQueueApc, Ptr, ApcHookLen);
   RtlMoveMemory(RealKeInsertQueueApc, Ptr, ApcHookLen);

   // Relocate jmps and calls
   if (!RelocateJumps(RealKeInsertQueueApc, (ULONG)RealKeInsertQueueApc - (ULONG)Ptr, ApcHookLen)) {
    ApcHookLen = 0;
    return;
   }

   // Write jumps
   WriteJump(&RealKeInsertQueueApc[ApcHookLen], (PVOID)((ULONG)Ptr + ApcHookLen));
   WriteJump(Ptr, HookedKeInsertQueueApc);
}
}


类别:Coding Space||添加到搜藏 |分享到i贴吧|浏览(712)|评论 (0)
 
最近读者:
 
网友评论:
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
     

   
帮助中心 | 空间客服 | 投诉中心 | 空间协议
©2012 Baidu