⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 driver.c

📁 进程获取工具。process hunter
💻 C
📖 第 1 页 / 共 2 页
字号:
#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 + -