#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;
}
枚举进程句柄
于 2021-09-19 14:45:44 首次发布