#include <ntddk.h> #include <string.h> #define WINAPI __stdcall typedef unsigned long DWORD; typedef DWORD *PDWORD; typedef unsigned short WORD; typedef WORD *PWORD; typedef unsigned char BYTE; typedef BYTE *PBYTE; typedef struct _HANDLE_TABLE { ULONG TableCode; PVOID QuotaProcess; PVOID UniqueProcessId; ULONG HandleTableLock[4]; LIST_ENTRY HandleTableList; ULONG HandleContentionEvent; PVOID DebugInfo; LONG ExtraInfoPages; ULONG FirstFreeHandle; ULONG LastFreeHandle; ULONG NextHandleNeedingPool; LONG HandleCount; union { ULONG Flags; ULONG StrictFIFO:1; }; } HANDLE_TABLE, *PHANDLE_TABLE; typedef struct _HANDLE_TABLE_ENTRY { union { PVOID Object; ULONG ObAttributes; PULONG AuditMask; ULONG Value; }; union { ULONG GrantedAccess; struct { WORD GrantedAccessIndex; WORD CreatorBackTraceIndex; }; LONG NextFreeTableEntry; }; } HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY; typedef struct _OBJECT_TYPE_INITIALIZER { USHORT Length; BOOLEAN UseDefaultObject; BOOLEAN Reserved; ULONG InvalidAttributes; UCHAR GenericMapping[0x10]; ULONG ValidAccessMask; BOOLEAN SecurityRequired; BOOLEAN MaintainHandleCount; BOOLEAN MaintainTypeList; USHORT PoolType; ULONG DefaultPagedPoolCharge; ULONG DefaultNonPagedPoolCharge; PVOID DumpProcedure; PVOID OpenProcedure; PVOID CloseProcedure; PVOID DeleteProcedure; PVOID ParseProcedure; PVOID SecurityProcedure; PVOID QueryNameProcedure; PVOID OkayToCloseProcedure; } OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER; typedef struct _OBJECT_HEADER { LONG PointerCount; union { LONG HandleCount; PVOID NextToFree; }; POBJECT_TYPE Type; UCHAR NameInfoOffset; UCHAR HandleInfoOffset; UCHAR QuotaInfoOffset; UCHAR Flags; union { PVOID ObjectCreateInfo; PVOID QuotaBlockCharged; }; PVOID SecurityDescriptor; QUAD Body; } OBJECT_HEADER, *POBJECT_HEADER; typedef struct _OBJECT_HEADER_NAME_INFO { PVOID Directory; UNICODE_STRING Name; ULONG QueryReferences; ULONG Reserved2; ULONG DbgReferenceCount; } OBJECT_HEADER_NAME_INFO, *POBJECT_HEADER_NAME_INFO; VOID OnUnload(IN PDRIVER_OBJECT pDriverObject); NTSTATUS OnStubDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp); DWORD FindProcessEPROC(int Pid); VOID listHandle(DWORD tableHandle, PDWORD Handle); NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING RegistryPath) { NTSTATUS Status = 0; DWORD SysEproc, PEB, tableHandle, Handle = 0; PHANDLE_TABLE ObjectTable; ULONG i; pDriverObject->DriverUnload = OnUnload; for(i=0; i<IRP_MJ_MAXIMUM_FUNCTION; i++) pDriverObject->MajorFunction[i] = OnStubDispatch; SysEproc = FindProcessEPROC(4); ObjectTable = (PHANDLE_TABLE)*((PDWORD)(SysEproc+0xc4)); DbgPrint("Object table adresse: 0x%x (%d handle)\n\n", ObjectTable, ObjectTable->HandleCount); tableHandle = ObjectTable->TableCode; if((ObjectTable->TableCode & 1) < 1) { listHandle(tableHandle, &Handle); } else { tableHandle |= 0x80000000; tableHandle &= 0xfffffff8; while(*(PDWORD)tableHandle != 0) { listHandle(*(PDWORD)tableHandle, &Handle); ((PDWORD)tableHandle)++; } } return Status; } VOID OnUnload(IN PDRIVER_OBJECT pDriverObject) { DbgPrint("Unload..."); } NTSTATUS OnStubDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; } DWORD FindProcessEPROC (int Pid) { DWORD eproc = 0x00000000; int current_PID = 0; int start_PID = 0; int i = 0; PLIST_ENTRY plist_active_procs; if (Pid == 0) return Pid; eproc = (DWORD)PsGetCurrentProcess(); start_PID = *((DWORD*)(eproc+0x84)); current_PID = start_PID; while(1) { if(Pid == current_PID) return eproc; else if((i >= 1) && (start_PID == current_PID)) return 0x00000000; else { plist_active_procs = (LIST_ENTRY *) (eproc+0x88); eproc = (DWORD) plist_active_procs->Flink; eproc = eproc - 0x88; current_PID = *((int *)(eproc+0x84)); i++; } } } VOID listHandle(DWORD tableHandle, PDWORD Handle) { PHANDLE_TABLE_ENTRY entryHandle; POBJECT_HEADER entryHeadObj, typeHeadObj; POBJECT_TYPE entryType; POBJECT_HEADER_NAME_INFO nameType, nameObj; ANSI_STRING AnsiString; ULONG i; for(i=0; i<512; i++) { entryHandle = (PHANDLE_TABLE_ENTRY)((DWORD)tableHandle+i*8); if(*(PDWORD)entryHandle != 0) { entryHeadObj = (POBJECT_HEADER)(((DWORD)entryHandle->Object | 0x80000000) & 0xfffffff8); typeHeadObj = (POBJECT_HEADER)((((DWORD)entryHeadObj->Type | 0x80000000) & 0xfffffff8)-0x18); nameType = (POBJECT_HEADER_NAME_INFO)((DWORD)typeHeadObj-(DWORD)typeHeadObj->NameInfoOffset); DbgPrint("%04x: Object: %x GrantedAccess: %x Entry: %x\n", *Handle, (DWORD)entryHeadObj+0x18, entryHandle->GrantedAccess, entryHandle); DbgPrint("\tType: %S ObjectHeader: %x\n", nameType->Name.Buffer, (DWORD)entryHeadObj); DbgPrint("\tHandleCount: %ld PointerCount: %ld\n", entryHeadObj->HandleCount, entryHeadObj->PointerCount); if(entryHeadObj->NameInfoOffset != 0) { nameObj = (POBJECT_HEADER_NAME_INFO)((DWORD)entryHeadObj-(DWORD)entryHeadObj->NameInfoOffset); DbgPrint("\tName: %S\n", nameObj->Name.Buffer); } DbgPrint("\n"); } *Handle += 4; } }