枚举进程句柄

#include <windows.h>
#include <stdio.h>

#define NT_SUCCESS(x) ((x) >= 0)
#define STATUS_INFO_LENGTH_MISMATCH 0xc0000004

#define SystemHandleInformation 16
#define ObjectBasicInformation 0
#define ObjectNameInformation 1
#define ObjectTypeInformation 2

typedef NTSTATUS(NTAPI *NTQUERYSYSTEMINFORMATION)(
	ULONG SystemInformationClass,
	PVOID SystemInformation,
	ULONG SystemInformationLength,
	PULONG ReturnLength
	);
typedef NTSTATUS(NTAPI *NTDUPLICATEOBJECT)(
	HANDLE SourceProcessHandle,
	HANDLE SourceHandle,
	HANDLE TargetProcessHandle,
	PHANDLE TargetHandle,
	ACCESS_MASK DesiredAccess,
	ULONG Attributes,
	ULONG Options
	);
typedef NTSTATUS(NTAPI *NTQUERYOBJECT)(
	HANDLE ObjectHandle,
	ULONG ObjectInformationClass,
	PVOID ObjectInformation,
	ULONG ObjectInformationLength,
	PULONG ReturnLength
	);

typedef struct _UNICODE_STRING {
	USHORT Length;
	USHORT MaximumLength;
	PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

typedef struct _SYSTEM_HANDLE {
	ULONG ProcessId;
	BYTE ObjectTypeNumber;
	BYTE Flags;
	USHORT Handle;
	PVOID Object;
	ACCESS_MASK GrantedAccess;
} SYSTEM_HANDLE, *PSYSTEM_HANDLE;

typedef struct _SYSTEM_HANDLE_INFORMATION {
	ULONG HandleCount;
	SYSTEM_HANDLE Handles[1];
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;

typedef enum _POOL_TYPE {
	NonPagedPool,
	PagedPool,
	NonPagedPoolMustSucceed,
	DontUseThisType,
	NonPagedPoolCacheAligned,
	PagedPoolCacheAligned,
	NonPagedPoolCacheAlignedMustS
} POOL_TYPE, *PPOOL_TYPE;

typedef struct _OBJECT_TYPE_INFORMATION {
	UNICODE_STRING Name;
	ULONG TotalNumberOfObjects;
	ULONG TotalNumberOfHandles;
	ULONG TotalPagedPoolUsage;
	ULONG TotalNonPagedPoolUsage;
	ULONG TotalNamePoolUsage;
	ULONG TotalHandleTableUsage;
	ULONG HighWaterNumberOfObjects;
	ULONG HighWaterNumberOfHandles;
	ULONG HighWaterPagedPoolUsage;
	ULONG HighWaterNonPagedPoolUsage;
	ULONG HighWaterNamePoolUsage;
	ULONG HighWaterHandleTableUsage;
	ULONG InvalidAttributes;
	GENERIC_MAPPING GenericMapping;
	ULONG ValidAccess;
	BOOLEAN SecurityRequired;
	BOOLEAN MaintainHandleCount;
	USHORT MaintainTypeList;
	POOL_TYPE PoolType;
	ULONG PagedPoolUsage;
	ULONG NonPagedPoolUsage;
} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;

int enumhandle(DWORD ProcessId)
{
	HMODULE hNtMod = LoadLibrary(L"ntdll.dll");
	if (!hNtMod)
	{
		return 0;
	}
	
	NTQUERYSYSTEMINFORMATION NtQuerySystemInformation = (NTQUERYSYSTEMINFORMATION)GetProcAddress(hNtMod, "NtQuerySystemInformation");
	NTDUPLICATEOBJECT NtDuplicateObject = (NTDUPLICATEOBJECT)GetProcAddress(hNtMod, "NtDuplicateObject");
	NTQUERYOBJECT NtQueryObject = (NTQUERYOBJECT)GetProcAddress(hNtMod, "NtQueryObject");

	if (!NtQuerySystemInformation || !NtDuplicateObject || !NtQueryObject)
	{
		return 0;
	}

	PSYSTEM_HANDLE_INFORMATION handleInfo = NULL;
	HANDLE processHandle;
	ULONG i;
	ULONG neededSize = 0x1000;
	NTSTATUS Status = 0;
	ULONG ReturnLength = 0;
	// NtQuerySystemInformation won't give us the correct buffer size,
	//  so we guess by doubling the buffer size.

	handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(neededSize);

	if (!handleInfo)
	{
		return 0;
	}

	//一直查询 直到成功
	while (STATUS_INFO_LENGTH_MISMATCH == (Status = NtQuerySystemInformation(
		SystemHandleInformation,
		handleInfo,
		neededSize,
		&ReturnLength
	)))
	{
		if (handleInfo)
		{
			free(handleInfo);
			handleInfo = NULL;
		}
		neededSize = ReturnLength;
		handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(neededSize);
		if (!handleInfo)
		{
			
			return 0;
		}
	}
	processHandle = OpenProcess(PROCESS_DUP_HANDLE, FALSE, ProcessId);

	for (i = 0; i < handleInfo->HandleCount; i++) {
		SYSTEM_HANDLE handle = handleInfo->Handles[i];
		if (handle.ProcessId!=ProcessId)
		{
			continue;
		}
		printf("句柄值%d\n",handle.Handle);

		if (processHandle)
		{
			HANDLE dupHandle = NULL;
			POBJECT_TYPE_INFORMATION objectTypeInfo = NULL;
			PVOID objectNameInfo = NULL;
			UNICODE_STRING objectName = { 0 };
			ULONG returnLength = 0;

			do
			{
				//句柄复制失败 就不去获取类型名
				Status = NtDuplicateObject(
					processHandle,
					(void*)handle.Handle,
					GetCurrentProcess(),
					&dupHandle,
					0,
					0,
					0
				);
				if (!NT_SUCCESS(Status))
				{
					break;
				}

				//获取对象类型名
				ULONG ObjectInformationLength = 0;
				while (STATUS_INFO_LENGTH_MISMATCH == (Status = NtQueryObject(
					dupHandle,
					ObjectTypeInformation,
					objectTypeInfo,
					ObjectInformationLength,
					&returnLength
				)))
				{
					if (objectTypeInfo)
					{
						free(objectTypeInfo);
						objectTypeInfo = NULL;
					}

					ObjectInformationLength = returnLength;
					objectTypeInfo = (POBJECT_TYPE_INFORMATION)malloc(ObjectInformationLength);
					if (!objectTypeInfo)
					{
						break;
					}
				}

				//获取对象类型名成功
				if (NT_SUCCESS(Status))
				{
					printf(" 对象类型名:%wZ\n",&objectTypeInfo->Name);
					
				}

				// Query the object name (unless it has an access of
				// 0x0012019f, on which NtQueryObject could hang.
				if (handle.GrantedAccess == 0x0012019f) {

					break;
				}
				
				//获取对象名
				ObjectInformationLength = 0;
				returnLength = 0;

				if (STATUS_INFO_LENGTH_MISMATCH == NtQueryObject(
					dupHandle,
					ObjectNameInformation,
					NULL,
					0,
					&returnLength
				)) {

					objectNameInfo = (POBJECT_TYPE_INFORMATION)malloc(returnLength);
					if (!objectNameInfo)
					{
						break;
					}

					ZeroMemory(objectNameInfo, returnLength);
					Status = NtQueryObject(
						dupHandle,
						ObjectNameInformation,
						objectNameInfo,
						returnLength,
						NULL);

				}

				//获取对象名成功
				if (NT_SUCCESS(Status) && ((PUNICODE_STRING)objectNameInfo)->Length > 0)
				{
					UNICODE_STRING objectName = *(PUNICODE_STRING)objectNameInfo;
					printf(" 对象名:%wZ\n", &objectName);
				}
				
			} while (FALSE);
			
			if (dupHandle)
			{
				CloseHandle(dupHandle);
				dupHandle = NULL;
			}
			if (objectTypeInfo)
			{
				free(objectTypeInfo);
				objectTypeInfo = NULL;
			}
			if (objectNameInfo)
			{
				free(objectNameInfo);
				objectNameInfo = NULL;
			}

		}
	}

	free(handleInfo);
	return 0;
}

int wmain(int argc, WCHAR *argv[]) {
	printf("输入进程id\n");
	DWORD ProcessId = 0;
	scanf_s("%d", &ProcessId);
	enumhandle(ProcessId);
	Sleep(200000);
	return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值