私有句柄表
_HANDLE_TABLE_ENTRY的Object直接指向_OBJECT_HEADER不用减
#include <ntifs.h>
//一个页最大容纳的_HANDLE_TABLE_ENTRY
#define MAX_ENTRY_COUNT (0x1000/sizeof(HANDLE_TABLE_ENTRY))
//未公开未文档化
typedef PVOID(NTAPI *OBGETOBJECTTYPE)(IN PVOID pObject);
EXTERN_C NTKERNELAPI UCHAR* PsGetProcessImageFileName(IN PEPROCESS Process);
OBGETOBJECTTYPE ObGetObjectType = 0;
//OBGETOBJECTTYPE ObGetObjectType = 0x840ac7bd;
//OBGETOBJECTTYPE ObGetObjectType = 0xfffff80004170eb4;
ULONG g_FlagLevel = 0;
//x64
typedef struct _HANDLE_TABLE
{
ULONGLONG TableCode; //0x0
PVOID QuotaProcess; //0x8
VOID* UniqueProcessId; //0x10
ULONG64 HandleLock; //0x18
struct _LIST_ENTRY HandleTableList; //0x20
ULONG64 HandleContentionEvent; //0x30
PVOID DebugInfo; //0x38
LONG ExtraInfoPages; //0x40
union
{
ULONG Flags; //0x44
UCHAR StrictFIFO : 1; //0x44
};
ULONG FirstFreeHandle; //0x48
struct _HANDLE_TABLE_ENTRY* LastFreeHandleEntry; //0x50
ULONG HandleCount; //0x58
ULONG NextHandleNeedingPool; //0x5c
ULONG HandleCountHighWatermark; //0x60
}HANDLE_TABLE, *PHANDLE_TABLE;
typedef struct _HANDLE_TABLE_ENTRY
{
union
{
//86 64..
ULONG_PTR Object; //0x0
ULONG ObAttributes; //0x0
//86 64
struct _HANDLE_TABLE_ENTRY_INFO* InfoTable; //0x0
ULONG_PTR Value; //0x0
};
union
{
ULONG GrantedAccess; //0x8
struct
{
USHORT GrantedAccessIndex; //0x8
USHORT CreatorBackTraceIndex; //0xa
};
ULONG NextFreeTableEntry; //0x8
};
}HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY;
typedef struct _OBJECT_TYPE_INITIALIZER {
USHORT wLength;
UCHAR ObjectTypeFlags;
ULONG ObjcetTypeCode;
ULONG InvalidAttributes;
GENERIC_MAPPING GenericMapping;
ULONG ValidAccessMask;
ULONG RetainAccess;
ULONG PoolType;
ULONG DefaultPagedPoolCharge;
ULONG DefaultNonPagedPoolCharge;
ULONG_PTR DumpProcedure;
ULONG_PTR OpenProcedure;
ULONG_PTR CloseProcedure;
ULONG_PTR DeleteProcedure;
ULONG_PTR ParseProcedure;
ULONG_PTR SecurityProcedure;
ULONG_PTR QueryNameProcedure;
ULONG_PTR OkayToCloseProcedure;
}OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER;
typedef struct _OBJECT_TYPE {
LIST_ENTRY TypeList;
UNICODE_STRING Name;
ULONG_PTR DefaultObject;
UCHAR Index;
ULONG TotalNumberOfObjects;
ULONG TotalNumberOfHandles;
ULONG HighWaterNumberOfObjects;
ULONG HighWaterNumberOfHandles;
OBJECT_TYPE_INITIALIZER TypeInfo;
ULONGLONG TypeLock;
ULONG Key;
LIST_ENTRY CallbackList;
}OBJECT_TYPE, *POBJECT_TYPE;
typedef struct _LDR_DATA_TABLE_ENTRY
{
LIST_ENTRY InLoadOrderLinks;
LIST_ENTRY InMemoryOrderLinks;
LIST_ENTRY InInitializationOrderLinks;
PVOID DllBase;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
USHORT LoadCount;
USHORT TlsIndex;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
//判断多少个Object
ULONG_PTR ObjectCount = 0;
UCHAR x64CodeFlag[] = { 0x0F,0xB6,0x41,0xE8,0x48,0x8D,0x0D,0xC1,0x1C,0xF0,0xFF,0x48,0x8B,0x04,0xC1,0xC3 };
UCHAR x86CodeFlag[] = { 0x8b,0xff,0x55,0x8b,0xec,0x8b,0x45,0x08,0x0f,0xb6,0x40,0xf4,0x8b,0x04,0x85,0x00,0x79,0xf9,0x83,0x5d,0xc2,0x04,0x00,0x90,0x90,0x90,0x90,0x90,0x8b,0xff,0x55,0x8b };
NTSTATUS FindObGetObjectType(PULONG_PTR retFunAddr, PDRIVER_OBJECT pDriver)
{
ULONG_PTR PEBase = 0;
ULONG PESize = 0;
PLIST_ENTRY DriverList = NULL;
PLIST_ENTRY NextList = NULL;
UNICODE_STRING usDriverName;
PUNICODE_STRING pusDriverName = NULL;
RtlInitUnicodeString(&usDriverName, L"ntoskrnl.exe");
DriverList = (PLIST_ENTRY)pDriver->DriverSection;
NextList = DriverList;
do
{
//0x58 BaseDllName
PLDR_DATA_TABLE_ENTRY pEntry = (PLDR_DATA_TABLE_ENTRY)((ULONG_PTR)NextList);
#ifdef _WIN64
pusDriverName = (PUNICODE_STRING)((ULONG_PTR)NextList + 0x058);
#else
pusDriverName = (PUNICODE_STRING)((ULONG_PTR)NextList + 0x2C);
#endif // _WIN64
if (!RtlCompareUnicodeString(&usDriverName, pusDriverName, TRUE))
{
PEBase = pEntry->DllBase;
PESize = (pEntry->SizeOfImage);
break;
}
NextList = NextList->Flink;
} while (NextList != DriverList);
for (size_t i = 0; i <= PESize; i++)
{
PULONG_PTR pCode = (PULONG_PTR)(PEBase + i);
//必须判断 不然直接蓝
if (!MmIsAddressValid((PVOID)pCode))
{
//KdPrint(("无效页:%I64x\n", i));
i = i + 0xfff;
continue;
}
#ifdef _WIN64
if (memcmp((void*)pCode, x64CodeFlag, 16) == 0)
#else
if (memcmp((void*)pCode, x86CodeFlag, 32) == 0)
#endif // _WIN64
{
*retFunAddr = pCode;
return STATUS_SUCCESS;
}
}
return -1;
}
NTSTATUS LookupProcessByName(PCHAR szTarName,PEPROCESS* pEPROCESS)
{
ULONG_PTR pEprocess = NULL;
pEprocess = (PEPROCESS)PsGetCurrentProcess();
#ifdef _WIN64
PLIST_ENTRY pHeadNode = (PLIST_ENTRY)(pEprocess + 0x188);
#else
PLIST_ENTRY pHeadNode = (PLIST_ENTRY)(pEprocess + 0xb8);
#endif // _WIN64
PLIST_ENTRY pNextNode = pHeadNode;
do
{
#ifdef _WIN64
pEprocess = (ULONG_PTR)pNextNode - 0x188;
PCHAR ProcessName = (ULONG_PTR)(pEprocess + 0x2e0);
#else
pEprocess = (ULONG_PTR)pNextNode - 0xb8;
PCHAR ProcessName = (ULONG_PTR)(pEprocess + 0x16C);
#endif // _WIN64
if (strcmp(ProcessName, szTarName) == 0)
{
*pEPROCESS = pEprocess;
return STATUS_SUCCESS;
}
pNextNode = pNextNode->Blink;
} while (pNextNode != pHeadNode);
return -1;
}
SIZE_T FindCidTablePrivate(PCHAR szName)
{
PEPROCESS pEprocess;
ULONG_PTR CidTableAddr = 0;
DbgBreakPoint();
if (LookupProcessByName(szName, &pEprocess) == -1)
{
DbgPrint("未找到私有句柄表");
return -1;
}
#ifdef _WIN64
CidTableAddr = (ULONG_PTR)pEprocess + 0x200;
#else
CidTableAddr = (ULONG_PTR)pEprocess + 0x0f4;
#endif // __WIN64
return CidTableAddr;
}
NTSTATUS Operation0(ULONG_PTR TableCode)
{
PHANDLE_TABLE_ENTRY HandleTableEntry = NULL;
ULONG Index = 0;
HandleTableEntry = (PHANDLE_TABLE_ENTRY)((ULONG_PTR*)(TableCode));
for (Index = 0; Index < (PAGE_SIZE / sizeof(HANDLE_TABLE_ENTRY)); Index++)
{
if (MmIsAddressValid((PVOID)HandleTableEntry))
{
PVOID ObjectHeader = (PVOID)(*(ULONG_PTR*)HandleTableEntry & ~3);
if (MmIsAddressValid(ObjectHeader))
{
#ifdef _WIN64
POBJECT_TYPE pObjectType = ObGetObjectType((ULONG_PTR)ObjectHeader + 0x30);
#elif _WIN32
POBJECT_TYPE pObjectType = ObGetObjectType((ULONG_PTR)ObjectHeader + 0x18);
#endif // _WIN64
if (MmIsAddressValid(ObjectHeader)) //这里应当判断对象是否合法
{
//打印数量以及ObjectBody的地址
ObjectCount++;
#ifdef _WIN64
DbgPrint("句柄类型:%-16wZ 句柄:0x%-08X 句柄对象(BODY):0x%-llX 句柄类型代号:%-2d 引用计数:%-6d\r ", &(pObjectType->Name), (g_FlagLevel*MAX_ENTRY_COUNT + Index) * 4, (ULONG_PTR)ObjectHeader + 0x30, pObjectType->Index, *((PULONG_PTR)ObjectHeader));
#else
DbgPrint("句柄类型:%-16wZ 句柄:0x%-08X 句柄对象:0x%-08X 句柄类型代号:%-2d 引用计数:%-6d\r ",&(pObjectType->Name), (g_FlagLevel*MAX_ENTRY_COUNT +Index)*4, (ULONG_PTR)ObjectHeader + 0x18,pObjectType->Index,*((PULONG_PTR)ObjectHeader));
#endif // _WIN64
}
}
}
HandleTableEntry++; //结构体指针++ 越过当前这个结构体
}
g_FlagLevel++; //用于计算句柄编号
return STATUS_SUCCESS;
}
NTSTATUS EnumProcessByHandle(PDRIVER_OBJECT pDriver)
{
FindObGetObjectType(&ObGetObjectType, pDriver);
PHANDLE_TABLE_ENTRY *TableLevel1, **TableLevel3;
ULONG_PTR CidTableAddr = FindCidTablePrivate("explorer.exe");
if (CidTableAddr == -1)
{
DbgPrint("获取Table失败!");
return -1;
}
ULONG_PTR TableCode = *(ULONG_PTR*)(*(ULONG_PTR*)(CidTableAddr));
ULONG_PTR TableLevel = TableCode & 3;
TableCode = TableCode & (~3);
switch (TableLevel)
{
case 0:
{
Operation0(TableCode);
break;
}
case 1:
{
TableLevel1 = TableCode;
SIZE_T i = 0;
//计算句柄数,遍历一次 加_HANDLE_TABLE_ENTRY
g_FlagLevel = 0;
while (TableLevel1[i])
{
Operation0(TableLevel1[i]);
i++;
}
break;
}
}
}
NTSTATUS DriverUnload(PDRIVER_OBJECT pDriver)
{
DbgPrint("Driver Unload!\n");
return STATUS_SUCCESS;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pRegpath)
{
EnumProcessByHandle(pDriver);
pDriver->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}