I
I情人下载
Unregistered / Unconfirmed
GUEST, unregistred user!
我想在自己的软件中添加禁止用户指定的程序运行。。不知道怎么实现??是通过注册表还是WInAPI??能否给出代码??系统是2000或XP的
#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
popad
jmp OldSwapContext
}
}
void Set2kSyscallHook()
{
TIdt Idt;
__asm
{
pushad
cli
sidt [Idt]
mov esi, NewSyscall
mov ebx, Idt.Base
xchg [ebx + 0x170], si
rol esi, 0x10
xchg [ebx + 0x176], si
ror esi, 0x10
mov OldSyscall, esi
sti
popad
}
}
void Win2kSyscallUnhook()
{
TIdt Idt;
__asm
{
pushad
cli
sidt [Idt]
mov esi, OldSyscall
mov ebx, Idt.Base
mov [ebx + 0x170], si
rol esi, 0x10
mov [ebx + 0x176], si
sti
xor eax, eax
mov OldSyscall, eax
popad
}
}
void SetXpSyscallHook()
{
TIdt Idt;
__asm
{
pushad
mov ecx, 0x176
rdmsr
mov OldSyscall, eax
mov eax, NewSyscall
xor edx, edx
wrmsr
sidt [Idt]
mov ebx, Idt.Base
xchg [ebx + 0x170], ax
rol eax, 0x10
xchg [ebx + 0x176], ax
ror eax, 0x10
mov OldInt2E, eax
popad
}
}
void XpSyscallUnhook()
{
TIdt Idt;
__asm
{
pushad
mov ecx, 0x176
mov eax, OldSyscall
xor edx, edx
wrmsr
sidt [Idt]
mov eax, OldInt2E
mov ebx, Idt.Base
mov [ebx + 0x170], ax
rol eax, 0x10
mov [ebx + 0x176], ax
xor eax, eax
mov OldSyscall, eax
popad
}
}
void WorkItemProc(PDEVICE_OBJECT DeviceObject, PWorkItemStruct Data)
{
KeWaitForSingleObject(Data->pEPROCESS, Executive, KernelMode, FALSE, NULL);
DelItem(&wLastItem, Data->pEPROCESS);
ObDereferenceObject(Data->pEPROCESS);
IoFreeWorkItem(Data->IoWorkItem);
ExFreePool(Data);
return;
}
void AddLog(PCHAR Message)
{
KIRQL OldIrql;
KeAcquireSpinLock(&LogSpinLock, &OldIrql);
if (MSG_BUFF_SIZE - strlen(SendMsgs) > strlen(Message) + 3)
{
strcat(SendMsgs, Message);
strcat(SendMsgs, "/x0D/x0A");
}
KeReleaseSpinLock(&LogSpinLock, OldIrql);
}
void NotifyRoutine(IN HANDLE ParentId,
IN HANDLE ProcessId,
IN BOOLEAN Create)
{
PEPROCESS process;
PWorkItemStruct Data;
CHAR str[256];
if (Create)
{
PsLookupProcessByProcessId(ProcessId, &process);
CollectProcess(process);
sprintf(str, "Process %s created, Pid = %d, ParentPid = %d", (PVOID)((ULONG)process + NameOffset), ProcessId, ParentId);
AddLog(str);
ObDereferenceObject(process);
} else
{
process = PsGetCurrentProcess();
ObReferenceObject(process);
Data = ExAllocatePool(NonPagedPool, sizeof(TWorkItemStruct));
Data->IoWorkItem = IoAllocateWorkItem(deviceObject);
Data->pEPROCESS = process;
sprintf(str, "Process %s terminated, Pid = %d", (PVOID)((ULONG)process + NameOffset), ProcessId);
AddLog(str);
IoQueueWorkItem(Data->IoWorkItem, WorkItemProc, DelayedWorkQueue, Data);
}
return;
}
void ProcessObject(PVOID Object)
{
POBJECT_HEADER ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
if (ObjectHeader->Type == *PsProcessType) CollectProcess(Object);
if (ObjectHeader->Type == *PsThreadType) ThreadCollect(Object);
}
void ScanXpHandleTable(PXP_HANDLE_TABLE HandleTable)
{
int i, j, k;
PHANDLE_TABLE_ENTRY Entry;
ULONG TableCode = HandleTable->TableCode & ~TABLE_LEVEL_MASK;
switch (HandleTable->TableCode & TABLE_LEVEL_MASK)
{
case 0 :
for (i = 0; i < 0x200; i++)
{
Entry = &((PHANDLE_TABLE_ENTRY)TableCode)[i];
if (Entry->Object) ProcessObject((PVOID)((ULONG)Entry->Object & ~XP_TABLE_ENTRY_LOCK_BIT));
}
break;
case 1 :
for (i = 0; i < 0x200; i++)
{
if (((PVOID *)TableCode)[i])
{
for (j = 0; j < 0x200; j++)
{
Entry = &((PHANDLE_TABLE_ENTRY *)TableCode)[i][j];
if (Entry->Object) ProcessObject((PVOID)((ULONG)Entry->Object & ~XP_TABLE_ENTRY_LOCK_BIT));
}
}
}
break;
case 2 :
for (i = 0; i < 0x200; i++)
{
if (((PVOID *)TableCode)[i])
{
for (j = 0; j < 0x200; j++)
{
if (((PVOID **)TableCode)[i][j])
{
for (k = 0; k < 0x200; k++)
{
Entry = &((PHANDLE_TABLE_ENTRY **)TableCode)[i][j][k];
if (Entry->Object) ProcessObject((PVOID)((ULONG)Entry->Object & ~XP_TABLE_ENTRY_LOCK_BIT));
}
}
}
}
}
break;
}
}
void ScanWin2KHandleTable(PWIN2K_HANDLE_TABLE HandleTable)
{
int i, j, k;
PHANDLE_TABLE_ENTRY Entry;
for (i = 0; i < 0x100; i++)
{
if (HandleTable->Table[i])
{
for (j = 0; j < 0x100; j++)
{
if (HandleTable->Table[i][j])
{
for (k = 0; k < 0x100; k++)
{
Entry = &HandleTable->Table[i][j][k];
if (Entry->Object) ProcessObject((PVOID)((ULONG)Entry->Object | WIN2K_TABLE_ENTRY_LOCK_BIT));
}
}
}
}
}
}
void ScanHandleTablesList()
{
PLIST_ENTRY CurrTable;
PEPROCESS QuotaProcess;
for (CurrTable = HandleTableListHead->Flink;
CurrTable != HandleTableListHead;
CurrTable = CurrTable->Flink)
{
QuotaProcess = *(PEPROCESS *)((PUCHAR)CurrTable - HandleTableListOffset + QuotaProcessOffset);
if (QuotaProcess) CollectProcess(QuotaProcess);
}
}
#ifdef DEBUG
void DriverUnload(IN PDRIVER_OBJECT DriverObject)
{
if (OldSwapContext) UnhookCode(OldSwapContext);
if (OldSyscall) SyscallUnhook();
PsSetCreateProcessNotifyRoutine(NotifyRoutine, TRUE);
FreePointers(wLastItem);
IoDeleteSymbolicLink(&SymbolicLinkName);
IoDeleteDevice(deviceObject);
ExFreePool(SendMsgs);
}
#endif
NTSTATUS GetServiceConsts()
{
NTSTATUS st = STATUS_SUCCESS;
PEPROCESS SysProc = PsGetCurrentProcess();
switch (*NtBuildNumber)
{
case 2195 : //win 2k
pIdOffset = 0x09C;
ActPsLink = 0x0A0;
NameOffset = 0x1FC;
ppIdOffset = 0x1C8;
ThreadProc = 0x22C;
WaitProcOffset = 0x1D0;
HandleTableOffset = 0x128;
HandleTableListOffset = 0x054;
QuotaProcessOffset = 0x00C;
SetSyscallHook = Set2kSyscallHook;
SyscallUnhook = Win2kSyscallUnhook;
ScanHandleTable = ScanWin2KHandleTable;
Win2KGetKiDispatcherReadyListHead();
Win2KGetKiWaitInOutListHeads();
break;
case 2600 : //win xp
pIdOffset = 0x084;
NameOffset = 0x174;
ppIdOffset = 0x14C;
ActPsLink = 0x088;
ThreadProc = 0x220;
WaitProcOffset = 0x1C0;
HandleTableOffset = 0x0C4;
HandleTableListOffset = 0x01C;
QuotaProcessOffset = 0x004;
SetSyscallHook = SetXpSyscallHook;
SyscallUnhook = XpSyscallUnhook;
ScanHandleTable = ScanXpHandleTable;
XPGetKiWaitListHead();
XPGetKiDispatcherReadyListHead();
break;
default :
st = STATUS_NOT_IMPLEMENTED;
break;
}
GetSwapContextAddress();
GetPspCidTable();
GetHandleTableListHead();
PsActiveProcessHead = *(PVOID *)((PUCHAR)SysProc + ActPsLink + 4);
return st;
}
NTSTATUS DriverIoControl(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
PIO_STACK_LOCATION pisl;
NTSTATUS ns = STATUS_UNSUCCESSFUL;
ULONG BuffSize, DataSize;
PVOID pBuff, pData;
KIRQL OldIrql;
pisl = IoGetCurrentIrpStackLocation (Irp);
BuffSize = pisl->Parameters.DeviceIoControl.OutputBufferLength;
pBuff = Irp->AssociatedIrp.SystemBuffer;
Irp->IoStatus.Information = 0;
switch(pisl->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_SET_SWAPCONTEXT_HOOK :
if (pSwapContext && !OldSwapContext)
{
OldSwapContext = HookCode(pSwapContext, NewSwapContext);
ns = STATUS_SUCCESS;
}
break;
case IOCTL_SWAPCONTEXT_UNHOOK :
if (OldSwapContext)
{
UnhookCode(OldSwapContext);
OldSwapContext = NULL;
ns = STATUS_SUCCESS;
}
break;
case IOCTL_SET_SYSCALL_HOOK :
if (!OldSyscall)
{
SetSyscallHook();
ns = STATUS_SUCCESS;
}
break;
case IOCTL_SYSCALL_UNHOOK :
if (OldSyscall)
{
SyscallUnhook();
ns = STATUS_SUCCESS;
}
break;
case IOCTL_GET_EXTEND_PSLIST :
pData = GetHooksProcessList(&DataSize);
if (pData)
{
if (BuffSize >= DataSize)
{
memcpy(pBuff, pData, DataSize);
Irp->IoStatus.Information = DataSize;
ns = STATUS_SUCCESS;
} else ns = STATUS_INFO_LENGTH_MISMATCH;
ExFreePool(pData);
}
break;
case IOCTL_GET_NATIVE_PSLIST :
pData = GetNativeProcessList(&DataSize);
if (pData)
{
if (BuffSize >= DataSize)
{
memcpy(pBuff, pData, DataSize);
Irp->IoStatus.Information = DataSize;
ns = STATUS_SUCCESS;
} else ns = STATUS_INFO_LENGTH_MISMATCH;
ExFreePool(pData);
}
break;
case IOCTL_GET_EPROCESS_PSLIST :
pData = GetEprocessProcessList(&DataSize);
if (pData)
{
if (BuffSize >= DataSize)
{
memcpy(pBuff, pData, DataSize);
Irp->IoStatus.Information = DataSize;
ns = STATUS_SUCCESS;
} else ns = STATUS_INFO_LENGTH_MISMATCH;
ExFreePool(pData);
}
break;
case IOCTL_SCAN_THREADS :
ProcessListHead(KiWaitInListHead);
ProcessListHead(KiWaitOutListHead);
ProcessListHead(KiDispatcherReadyListHead);
ns = STATUS_SUCCESS;
break;
case IOCTL_SCAN_PSP_CID_TABLE :
if(PspCidTable)
{
ScanHandleTable(PspCidTable);
ns = STATUS_SUCCESS;
}
break;
case IOCTL_HANDLETABLES_LIST :
if (HandleTableListHead)
{
ScanHandleTablesList();
ns = STATUS_SUCCESS;
}
break;
case IOCTL_GET_MESSAGES :
if (BuffSize >= MSG_BUFF_SIZE)
{
KeAcquireSpinLock(&LogSpinLock, &OldIrql);
strcpy(pBuff, SendMsgs);
memset(SendMsgs, 0, MSG_BUFF_SIZE);
Irp->IoStatus.Information = MSG_BUFF_SIZE;
ns = STATUS_SUCCESS;
KeReleaseSpinLock(&LogSpinLock, OldIrql);
}
break;
}
Irp->IoStatus.Status = ns;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return ns;
}
NTSTATUS DriverCreateClose(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{
NTSTATUS status;
PDRIVER_DISPATCH *ppdd;
PCWSTR dDeviceName = L"//Device//phunter";
PCWSTR dSymbolicLinkName = L"//DosDevices//phunter";
RtlInitUnicodeString(&DeviceName, dDeviceName);
RtlInitUnicodeString(&SymbolicLinkName, dSymbolicLinkName);
KeInitializeSpinLock(&LogSpinLock);
status = GetServiceConsts();
if (!NT_SUCCESS(status)) return status;
status = IoCreateDevice(DriverObject, 0, &DeviceName, FILE_DEVICE_UNKNOWN, 0, TRUE, &deviceObject);
if (!NT_SUCCESS(status)) return status;
status = IoCreateSymbolicLink(&SymbolicLinkName, &DeviceName);
SendMsgs = ExAllocatePool(NonPagedPool, MSG_BUFF_SIZE);
if (!NT_SUCCESS(status) || !SendMsgs)
{
IoDeleteDevice(deviceObject);
if (!SendMsgs) status = STATUS_INSUFFICIENT_RESOURCES;
return status;
}
memset(SendMsgs, 0, MSG_BUFF_SIZE);
PsSetCreateProcessNotifyRoutine(NotifyRoutine, FALSE);
#ifdef DEBUG
DriverObject->DriverUnload = DriverUnload;
#endif
ppdd = DriverObject->MajorFunction;
ppdd [IRP_MJ_CREATE] =
ppdd [IRP_MJ_CLOSE ] = DriverCreateClose;
ppdd [IRP_MJ_DEVICE_CONTROL ] = DriverIoControl;
return status;
}
unit ProcList;
interface
uses
windows, advApiHook, NativeAPI, TlHelp32, UList, SysUtils;
type
PProcessRecord = ^TProcessRecord;
TProcessRecord = packed record
Visible: boolean;
SignalState: dword;
Present: boolean;
ProcessId: dword;
ParrentPID: dword;
pEPROCESS: dword;
ProcessName: array [0..255] of Char;
end;
procedure GetFullProcessesInfo(var List: PListStruct);
function OpenDriver(): boolean;
function SetSwapcontextHook(): boolean;
function SetSyscallHook(): boolean;
function UnhookAll(): boolean;
function DrvGetLogString(): string;
var
hDriver: dword = 0;
implementation
uses
Unit1;
type
JOBOBJECTINFOCLASS =
(
JobObjectBasicAccountingInformation = 1,
JobObjectBasicLimitInformation,
JobObjectBasicProcessIdList,
JobObjectBasicUIRestrictions,
JobObjectSecurityLimitInformation,
JobObjectEndOfJobTimeInformation,
JobObjectAssociateCompletionPortInformation,
MaxJobObjectInfoClass
);
PJOBOBJECT_BASIC_PROCESS_ID_LIST = ^JOBOBJECT_BASIC_PROCESS_ID_LIST;
JOBOBJECT_BASIC_PROCESS_ID_LIST = packed record
NumberOfAssignedProcesses,
NumberOfProcessIdsInList: dword;
ProcessIdList: array [0..0] of dword;
end;
function QueryInformationJobObject(hJob: dword; JobObjectInfoClass: JOBOBJECTINFOCLASS;
lpJobObjectInfo: pointer;
bJobObjectInfoLength: dword;
lpReturnLength: pdword): bool; stdcall; external 'kernel32.dll';
const
MSG_BUFF_SIZE = 4096;
BASE_IOCTL = (FILE_DEVICE_UNKNOWN shl 16) or (FILE_READ_ACCESS shl 14) or METHOD_BUFFERED;
IOCTL_SET_SWAPCONTEXT_HOOK = BASE_IOCTL or (1 shl 2);
IOCTL_SWAPCONTEXT_UNHOOK = BASE_IOCTL or (2 shl 2);
IOCTL_SET_SYSCALL_HOOK = BASE_IOCTL or (3 shl 2);
IOCTL_SYSCALL_UNHOOK = BASE_IOCTL or (4 shl 2);
IOCTL_GET_EXTEND_PSLIST = BASE_IOCTL or (5 shl 2);
IOCTL_GET_NATIVE_PSLIST = BASE_IOCTL or (6 shl 2);
IOCTL_GET_EPROCESS_PSLIST = BASE_IOCTL or (7 shl 2);
IOCTL_SCAN_THREADS = BASE_IOCTL or (8 shl 2);
IOCTL_SCAN_PSP_CID_TABLE = BASE_IOCTL or (9 shl 2);
IOCTL_HANDLETABLES_LIST = BASE_IOCTL or (10 shl 2);
IOCTL_GET_MESSAGES = BASE_IOCTL or (11 shl 2);
var
CsrPid: dword;
Version: TOSVersionInfo;
Res: boolean = false;
IsWin2K: boolean = false;
ZwQuerySystemInfoCall: function(ASystemInformationClass: dword;
ASystemInformation: Pointer;
ASystemInformationLength: dword;
AReturnLength: pdword): dword; stdcall;
{
项塍麇龛?耧桉赅 镳铞羼耦?麇疱?ToolHelp API.
}
procedure GetToolHelpProcessList(var List: PListStruct);
var
Snap: dword;
Process: TPROCESSENTRY32;
NewItem: PProcessRecord;
begin
Snap := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if Snap <> INVALID_HANDLE_VALUE then
begin
Process.dwSize := SizeOf(TPROCESSENTRY32);
if Process32First(Snap, Process) then
repeat
GetMem(NewItem, SizeOf(TProcessRecord));
ZeroMemory(NewItem, SizeOf(TProcessRecord));
NewItem^.ProcessId := Process.th32ProcessID;
NewItem^.ParrentPID := Process.th32ParentProcessID;
lstrcpy(@NewItem^.ProcessName, Process.szExeFile);
AddItem(List, NewItem);
until not Process32Next(Snap, Process);
CloseHandle(Snap);
end;
end;
{
项塍麇龛?耧桉赅 镳铞羼耦?麇疱?ZwQuerySystemInformation.
}
procedure GetNativeProcessList(var List: PListStruct);
var
Info: PSYSTEM_PROCESSES;
NewItem: PProcessRecord;
Mem: pointer;
begin
Info := GetInfoTable(SystemProcessesAndThreadsInformation);
Mem := Info;
if Info = nil then Exit;
repeat
GetMem(NewItem, SizeOf(TProcessRecord));
ZeroMemory(NewItem, SizeOf(TProcessRecord));
lstrcpy(@NewItem^.ProcessName,
PChar(WideCharToString(Info^.ProcessName.Buffer)));
NewItem^.ProcessId := Info^.ProcessId;
NewItem^.ParrentPID := Info^.InheritedFromProcessId;
AddItem(List, NewItem);
Info := pointer(dword(info) + info^.NextEntryDelta);
until Info^.NextEntryDelta = 0;
VirtualFree(Mem, 0, MEM_RELEASE);
end;
{
项塍麇龛?耧桉赅 镳铞羼耦?镱 耧桉牦 铗牮?? 觚礓腩?
骂玮疣?弪 蝾朦觐 ProcessId.
}
procedure GetHandlesProcessList(var List: PListStruct);
var
Info: PSYSTEM_HANDLE_INFORMATION_EX;
NewItem: PProcessRecord;
r: dword;
OldPid: dword;
begin
OldPid := 0;
Info := GetInfoTable(SystemHandleInformation);
if Info = nil then Exit;
for r := 0 to Info^.NumberOfHandles do
if Info^.Information[r].ProcessId <> OldPid then
begin
OldPid := Info^.Information[r].ProcessId;
GetMem(NewItem, SizeOf(TProcessRecord));
ZeroMemory(NewItem, SizeOf(TProcessRecord));
NewItem^.ProcessId := OldPid;
AddItem(List, NewItem);
end;
VirtualFree(Info, 0, MEM_RELEASE);
end;
function IsPidAdded(List: PListStruct; Pid: dword): boolean;
begin
Result := false;
while (List <> nil) do
begin
if PProcessRecord(List^.pData)^.ProcessId = Pid then
begin
Result := true;
Exit;
end;
List := List^.pNext;
end;
end;
function IsEprocessAdded(List: PListStruct; pEPROCESS: dword): boolean;
begin
Result := false;
while (List <> nil) do
begin
if PProcessRecord(List^.pData)^.pEPROCESS = pEPROCESS then
begin
Result := true;
Exit;
end;
List := List^.pNext;
end;
end;
Procedure CopyListWithData(var NewList: PListStruct; List: PListStruct);
var
NewItem: PProcessRecord;
begin
while (List <> nil) do
begin
GetMem(NewItem, SizeOf(TProcessRecord));
ZeroMemory(NewItem, SizeOf(TProcessRecord));
NewItem^ := PProcessRecord(List^.pData)^;
NewItem^.Visible := false;
AddItem(NewList, NewItem);
List := List^.pNext;
end;
end;
function FindProcess(List: PListStruct; Pid, pEPROCESS: dword): PProcessRecord;
var
Process: PProcessRecord;
begin
Result := nil;
while (List <> nil) do
begin
Process := List^.pData;
if ( ((pEPROCESS <> 0) and (Process^.pEPROCESS = pEPROCESS)) or
((Pid <> 0) and (Process^.ProcessId = Pid)) or
((Pid = 0) and (pEPROCESS = 0) and (Process^.pEPROCESS = 0)
and (Process^.ProcessId = 0)) ) then
begin
Result := Process;
Exit;
end;
List := List^.pNext;
end;
end;
procedure MergeList(var List: PListStruct; List2: PListStruct);
var
Process, Process2: PProcessRecord;
begin
while (List2 <> nil) do
begin
Process := List2^.pData;
Process2 := FindProcess(List, Process^.ProcessId, Process^.pEPROCESS);
if Process2 = nil then AddItem(List, Process) else
begin
if Process2^.ProcessId = 0 then Process2^.ProcessId := Process^.ProcessId;
if Process2^.pEPROCESS = 0 then Process2^.pEPROCESS := Process^.pEPROCESS;
if Process2^.ParrentPID = 0 then Process2^.ParrentPID := Process^.ParrentPID;
if Process2^.ProcessName = '' then Process2^.ProcessName := Process^.ProcessName;
if Process2^.SignalState = 0 then Process2^.SignalState := Process^.SignalState;
end;
List2 := List2^.pNext;
end;
end;
procedure MakeVisible(AllProc: PListStruct; CmpList: PListStruct);
var
Process: PProcessRecord;
begin
while (AllProc <> nil) do
begin
Process := AllProc^.pData;
Process.Visible := FindProcess(CmpList, Process^.ProcessId, Process^.pEPROCESS) <> nil;
AllProc := AllProc^.pNext;
end;
end;
{
项塍麇龛?耧桉赅 镳铞羼耦?镱 耧桉牦 铌铐.
骂玮疣?弪 蝾朦觐 ProcessId.
}
procedure GetWindowsProcessList(var List: PListStruct);
function EnumWindowsProc(hwnd: dword; PList: PPListStruct): bool; stdcall;
var
ProcId: dword;
NewItem: PProcessRecord;
begin
GetWindowThreadProcessId(hwnd, ProcId);
if not IsPidAdded(PList^, ProcId) then
begin
GetMem(NewItem, SizeOf(TProcessRecord));
ZeroMemory(NewItem, SizeOf(TProcessRecord));
NewItem^.ProcessId := ProcId;
AddItem(PList^, NewItem);
end;
Result := true;
end;
begin
EnumWindows(@EnumWindowsProc, dword(@List));
end;
{
谚耱屐睇?恹珙?ZwQuerySystemInformation 潆