用户句柄表的遍历

30 篇文章 4 订阅
7 篇文章 2 订阅

私有句柄表
_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;

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值