📄 driver.c
字号:
#include <ntddk.h>
#include <wcstr.h>
#include <stdio.h>
#include "winkernel.h"
#include "list.h"
#include "LDasm.h"
//#define DEBUG
UNICODE_STRING DeviceName;
UNICODE_STRING SymbolicLinkName;
PDEVICE_OBJECT deviceObject = NULL;
ULONG pIdOffset, ActPsLink, NameOffset, ppIdOffset, ThreadProc, WaitProcOffset;
ULONG HandleTableOffset, HandleTableListOffset, QuotaProcessOffset;
PVOID OldSyscall = NULL;
PVOID OldSwapContext = NULL;
PVOID pSwapContext = NULL;
PVOID OldInt2E;
PLIST_ENTRY PsActiveProcessHead = NULL;
PLIST_ENTRY KiWaitInListHead = NULL;
PLIST_ENTRY KiWaitOutListHead = NULL;
PLIST_ENTRY KiDispatcherReadyListHead = NULL;
PLIST_ENTRY HandleTableListHead = NULL;
PHANDLE_TABLE PspCidTable = NULL;
PCHAR SendMsgs;
#define MSG_BUFF_SIZE 4096
KSPIN_LOCK LogSpinLock;
#define BASE_IOCTL (FILE_DEVICE_UNKNOWN << 16) | (FILE_READ_ACCESS << 14) | METHOD_BUFFERED
#define IOCTL_SET_SWAPCONTEXT_HOOK BASE_IOCTL | (1 << 2)
#define IOCTL_SWAPCONTEXT_UNHOOK BASE_IOCTL | (2 << 2)
#define IOCTL_SET_SYSCALL_HOOK BASE_IOCTL | (3 << 2)
#define IOCTL_SYSCALL_UNHOOK BASE_IOCTL | (4 << 2)
#define IOCTL_GET_EXTEND_PSLIST BASE_IOCTL | (5 << 2)
#define IOCTL_GET_NATIVE_PSLIST BASE_IOCTL | (6 << 2)
#define IOCTL_GET_EPROCESS_PSLIST BASE_IOCTL | (7 << 2)
#define IOCTL_SCAN_THREADS BASE_IOCTL | (8 << 2)
#define IOCTL_SCAN_PSP_CID_TABLE BASE_IOCTL | (9 << 2)
#define IOCTL_HANDLETABLES_LIST BASE_IOCTL | (10 << 2)
#define IOCTL_GET_MESSAGES BASE_IOCTL | (11 << 2)
#define MemOpen() __asm cli; __asm mov eax, cr0; __asm mov oData, eax; \
__asm and eax, 0xFFFEFFFF; __asm mov cr0, eax;
#define MemClose() __asm mov eax, oData; __asm mov cr0, eax; __asm sti;
#pragma pack (push, 1)
typedef struct _ProcessRecord
{
BOOLEAN Visible;
ULONG SignalState;
BOOLEAN Present;
ULONG ProcessId;
ULONG ParrentPID;
PEPROCESS pEPROCESS;
CHAR ProcessName[256];
} TProcessRecord, *PProcessRecord;
typedef struct _WorkItemStruct
{
PEPROCESS pEPROCESS;
PIO_WORKITEM IoWorkItem;
} TWorkItemStruct, *PWorkItemStruct;
#pragma pack (pop)
PProcessList wLastItem = NULL;
typedef void (*pFn)();
typedef void (*pFnParam)(PVOID Param);
pFn SetSyscallHook;
pFn SyscallUnhook;
pFnParam ScanHandleTable;
PVOID GetInfoTable(ULONG ATableType)
{
ULONG mSize = 0x4000;
PVOID mPtr = NULL;
NTSTATUS St;
do
{
mPtr = ExAllocatePool(PagedPool, mSize);
memset(mPtr, 0, mSize);
if (mPtr)
{
St = ZwQuerySystemInformation(ATableType, mPtr, mSize, NULL);
} else return NULL;
if (St == STATUS_INFO_LENGTH_MISMATCH)
{
ExFreePool(mPtr);
mSize = mSize * 2;
}
} while (St == STATUS_INFO_LENGTH_MISMATCH);
if (St == STATUS_SUCCESS) return mPtr;
ExFreePool(mPtr);
return NULL;
}
UCHAR SaveOldFunction(PUCHAR Proc, PUCHAR Old)
{
ULONG Size;
PUCHAR pOpcode;
ULONG Offset;
PUCHAR oPtr;
ULONG Result = 0;
Offset = (ULONG)Proc - (ULONG)Old;
oPtr = Old;
while (Result < 5)
{
Size = SizeOfCode(Proc, &pOpcode);
memcpy(oPtr, Proc, Size);
if (IsRelativeCmd(pOpcode)) *(PULONG)((ULONG)pOpcode - (ULONG)Proc + (ULONG)oPtr + 1) += Offset;
oPtr += Size;
Proc += Size;
Result += Size;
}
*(PUCHAR)((ULONG)Old + Result) = 0xE9;
*(PULONG)((ULONG)Old + Result + 1) = Offset - 5;
return (UCHAR)Result;
}
PVOID HookCode(PVOID TargetProc, PVOID NewProc)
{
ULONG Address;
PVOID OldFunction;
PVOID Proc = TargetProc;
ULONG oData;
Address = (ULONG)NewProc - (ULONG)Proc - 5;
MemOpen();
OldFunction = ExAllocatePool(NonPagedPool, 20);
*(PULONG)OldFunction = (ULONG)Proc;
*(PUCHAR)((ULONG)OldFunction + 4) = SaveOldFunction((PUCHAR)Proc, (PUCHAR)((ULONG)OldFunction + 5));
*(PUCHAR)Proc = 0xE9;
*(PULONG)((ULONG)Proc + 1) = Address;
MemClose();
return (PVOID)((ULONG)OldFunction + 5);
}
void UnhookCode(PVOID OldProc)
{
PUCHAR Proc, pMem;
PUCHAR pOpcode;
ULONG Size, ThisSize;
ULONG SaveSize, Offset;
ULONG oData;
Proc = (PUCHAR)(*(PULONG)((ULONG)OldProc - 5));
pMem = Proc;
SaveSize = *(PUCHAR)((ULONG)OldProc - 1);
Offset = (ULONG)Proc - (ULONG)OldProc;
MemOpen();
memcpy(Proc, OldProc, SaveSize);
ThisSize = 0;
while (ThisSize < SaveSize)
{
Size = SizeOfCode(Proc, &pOpcode);
if (IsRelativeCmd(pOpcode)) *(PULONG)((ULONG)pOpcode + 1) -= Offset;
Proc += Size;
ThisSize += Size;
}
MemClose();
ExFreePool((PVOID)((ULONG)OldProc - 5));
return;
}
PVOID GetNativeProcessList(ULONG *MemSize)
{
ULONG PsCount = 0;
PVOID Info = GetInfoTable(SystemProcessesAndThreadsInformation);
PSYSTEM_PROCESSES Proc;
PVOID Mem = NULL;
PProcessRecord Data;
if (!Info) return NULL; else Proc = Info;
do
{
Proc = (PSYSTEM_PROCESSES)((ULONG)Proc + Proc->NextEntryDelta);
PsCount++;
} while (Proc->NextEntryDelta);
*MemSize = (PsCount + 1) * sizeof(TProcessRecord);
Mem = ExAllocatePool(PagedPool, *MemSize);
if (!Mem) return NULL; else Data = Mem;
Proc = Info;
do
{
Proc = (PSYSTEM_PROCESSES)((ULONG)Proc + Proc->NextEntryDelta);
wcstombs(Data->ProcessName, Proc->ProcessName.Buffer, 255);
Data->Present = TRUE;
Data->ProcessId = Proc->ProcessId;
Data->ParrentPID = Proc->InheritedFromProcessId;
PsLookupProcessByProcessId((HANDLE)Proc->ProcessId, &Data->pEPROCESS);
ObDereferenceObject(Data->pEPROCESS);
Data++;
} while (Proc->NextEntryDelta);
Data->Present = FALSE;
ExFreePool(Info);
return Mem;
}
PVOID GetEprocessProcessList(ULONG *MemSize)
{
PLIST_ENTRY Process;
ULONG PsCount = 0;
PVOID Mem = NULL;
PProcessRecord Data;
if (!PsActiveProcessHead) return NULL;
Process = PsActiveProcessHead->Flink;
while (Process != PsActiveProcessHead)
{
PsCount++;
Process = Process->Flink;
}
PsCount++;
*MemSize = PsCount * sizeof(TProcessRecord);
Mem = ExAllocatePool(PagedPool, *MemSize);
memset(Mem, 0, *MemSize);
if (!Mem) return NULL; else Data = Mem;
Process = PsActiveProcessHead->Flink;
while (Process != PsActiveProcessHead)
{
Data->Present = TRUE;
Data->ProcessId = *(PULONG)((ULONG)Process - ActPsLink + pIdOffset);
Data->ParrentPID = *(PULONG)((ULONG)Process - ActPsLink + ppIdOffset);
Data->SignalState = *(PULONG)((ULONG)Process - ActPsLink + 4);
Data->pEPROCESS = (PEPROCESS)((ULONG)Process - ActPsLink);
strncpy(Data->ProcessName, (PVOID)((ULONG)Process - ActPsLink + NameOffset), 16);
Data++;
Process = Process->Flink;
}
return Mem;
}
void XPGetKiWaitListHead()
{
PUCHAR cPtr, pOpcode;
ULONG Length;
for (cPtr = (PUCHAR)KeDelayExecutionThread;
cPtr < (PUCHAR)KeDelayExecutionThread + PAGE_SIZE;
cPtr += Length)
{
Length = SizeOfCode(cPtr, &pOpcode);
if (!Length) break;
if (*(PUSHORT)cPtr == 0x03C7 && *(PUSHORT)(pOpcode + 6) == 0x4389)
{
KiWaitInListHead = *(PVOID *)(pOpcode + 2);
break;
}
}
return;
}
void XPGetKiDispatcherReadyListHead()
{
PUCHAR cPtr, pOpcode;
PUCHAR CallAddr = NULL;
ULONG Length;
for (cPtr = (PUCHAR)KiDispatchInterrupt;
cPtr < (PUCHAR)KiDispatchInterrupt + PAGE_SIZE;
cPtr += Length)
{
Length = SizeOfCode(cPtr, &pOpcode);
if (!Length) return;
if (*pOpcode == 0xE8 && *(PUSHORT)(pOpcode + 5) == 0x01B1)
{
CallAddr = (PUCHAR)(*(PULONG)(pOpcode + 1) + (ULONG)cPtr + Length);
break;
}
}
if (!CallAddr || !MmIsAddressValid(CallAddr)) return;
for (cPtr = CallAddr; cPtr < CallAddr + PAGE_SIZE; cPtr += Length)
{
Length = SizeOfCode(cPtr, &pOpcode);
if (!Length) return;
if (*(PUSHORT)pOpcode == 0x148D && *(pOpcode + 2) == 0xCD && IsRelativeCmd(pOpcode + 7))
{
KiDispatcherReadyListHead = *(PLIST_ENTRY *)(pOpcode + 3);
break;
}
}
return;
}
void Win2KGetKiWaitInOutListHeads()
{
PUCHAR cPtr, pOpcode;
ULONG Length;
for (cPtr = (PUCHAR)KeWaitForSingleObject;
cPtr < (PUCHAR)KeWaitForSingleObject + PAGE_SIZE;
cPtr += Length)
{
Length = SizeOfCode(cPtr, &pOpcode);
if (!Length) break;
if (*pOpcode == 0xB9 && *(pOpcode + 5) == 0x84 && *(pOpcode + 24) == 0xB9)
{
KiWaitInListHead = *(PLIST_ENTRY *)(pOpcode + 1);
KiWaitOutListHead = *(PLIST_ENTRY *)(pOpcode + 25);
break;
}
}
return;
}
void Win2KGetKiDispatcherReadyListHead()
{
PUCHAR cPtr, pOpcode;
ULONG Length;
for (cPtr = (PUCHAR)KeSetAffinityThread;
cPtr < (PUCHAR)KeSetAffinityThread + PAGE_SIZE;
cPtr += Length)
{
Length = SizeOfCode(cPtr, &pOpcode);
if (!Length) break;
if (*(PUSHORT)pOpcode == 0x048D && *(pOpcode + 2) == 0xCD && *(pOpcode + 7) == 0x39)
{
KiDispatcherReadyListHead = *(PLIST_ENTRY *)(pOpcode + 3);
break;
}
}
return;
}
void GetSwapContextAddress()
{
PUCHAR cPtr, pOpcode;
ULONG Length;
for (cPtr = (PUCHAR)KiDispatchInterrupt;
cPtr < (PUCHAR)KiDispatchInterrupt + PAGE_SIZE;
cPtr += Length)
{
Length = SizeOfCode(cPtr, &pOpcode);
if (!Length) break;
if (*(PUSHORT)pOpcode == 0x01B1 && *(pOpcode + 2) == 0xE8)
{
pSwapContext = (PVOID)(*(PULONG)(pOpcode + 3) + (ULONG)cPtr + 7);
break;
}
}
return;
}
void GetPspCidTable()
{
PUCHAR cPtr, pOpcode;
ULONG Length;
for (cPtr = (PUCHAR)PsLookupProcessByProcessId;
cPtr < (PUCHAR)PsLookupProcessByProcessId + PAGE_SIZE;
cPtr += Length)
{
Length = SizeOfCode(cPtr, &pOpcode);
if (!Length) break;
if (*(PUSHORT)cPtr == 0x35FF && *(pOpcode + 6) == 0xE8)
{
PspCidTable = **(PVOID **)(pOpcode + 2);
break;
}
}
}
void GetHandleTableListHead()
{
PSYSTEM_MODULE_INFORMATION_EX Info = GetInfoTable(SystemModuleInformation);
ULONG NtoskrnlBase = (ULONG)Info->Modules[0].Base;
ULONG NtoskrnlSize = Info->Modules[0].Size;
PHANDLE_TABLE HandleTable = *(PHANDLE_TABLE *)((ULONG)PsGetCurrentProcess() + HandleTableOffset);
PLIST_ENTRY HandleTableList = (PLIST_ENTRY)((ULONG)HandleTable + HandleTableListOffset);
PLIST_ENTRY CurrTable;
ExFreePool(Info);
for (CurrTable = HandleTableList->Flink;
CurrTable != HandleTableList;
CurrTable = CurrTable->Flink)
{
if ((ULONG)CurrTable > NtoskrnlBase && (ULONG)CurrTable < NtoskrnlBase + NtoskrnlSize)
{
HandleTableListHead = CurrTable;
break;
}
}
}
void _stdcall CollectProcess(PEPROCESS pEPROCESS)
{
if (!IsAdded(wLastItem, pEPROCESS)) AddItem(&wLastItem, pEPROCESS);
return;
}
void __stdcall ThreadCollect(PUCHAR pEthread)
{
PEPROCESS pEprocess = *(PEPROCESS *)(pEthread + ThreadProc);
if (pEprocess) CollectProcess(pEprocess);
return;
}
PVOID GetHooksProcessList(ULONG *MemSize)
{
PProcessList Item = wLastItem;
PVOID Mem = NULL;
PProcessRecord Data;
ULONG PsCount = 0;
while (Item)
{
PsCount++;
Item = Item->NextItem;
}
Item = wLastItem;
*MemSize = (PsCount + 1) * sizeof(TProcessRecord);
Mem = ExAllocatePool(PagedPool, *MemSize);
if (!Mem) return NULL; else Data = Mem;
while (Item)
{
Data->Present = TRUE;
Data->ProcessId = *(PULONG)((ULONG)Item->pEPROCESS + pIdOffset);
Data->ParrentPID = *(PULONG)((ULONG)Item->pEPROCESS + ppIdOffset);
Data->pEPROCESS = Item->pEPROCESS;
strncpy(Data->ProcessName, (PVOID)((ULONG)Item->pEPROCESS + NameOffset), 16);
Data++;
Item = Item->NextItem;
}
Data->Present = FALSE;
return Mem;
}
void ProcessListHead(PLIST_ENTRY ListHead)
{
PLIST_ENTRY Item;
if (ListHead)
{
Item = ListHead->Flink;
while (Item != ListHead)
{
CollectProcess(*(PEPROCESS *)((ULONG)Item + WaitProcOffset));
Item = Item->Flink;
}
}
return;
}
void __declspec(naked) NewSyscall()
{
__asm
{
pushad
pushfd
push fs
mov di, 0x30
mov fs, di
mov eax, fs:[0x124]
mov eax, [eax + 0x44]
push eax
call CollectProcess
pop fs
popfd
popad
jmp OldSyscall
}
}
void __declspec(naked) NewSwapContext()
{
__asm
{
pushad
pushfd
push edi
call ThreadCollect
push esi
call ThreadCollect
popfd
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -