下列提出两种获取对象名的方式
- 通过_OBJECT_TYPE::Name获取对象名称,通过_OBJECT_TYPE::Index获取对象索引;
- 通过NtQueryObject的方式获取,r0与r3通用,代码如下:
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <Windows.h>
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#define STATUS_SUCCESS ((NTSTATUS)0x0L)
#define STATUS_UNSUCCESSFUL ((NTSTATUS)0xC0000001L)
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
#define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023)
typedef enum _OBJECT_INFORMATION_CLASS {
ObjectBasicInformation,
ObjectNameInformation,
ObjectTypeInformation,
ObjectTypesInformation,
ObjectHandleFlagInformation,
ObjectSessionInformation,
} OBJECT_INFORMATION_CLASS;
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
typedef struct _OBJECT_TYPE_INFORMATION
{
UNICODE_STRING TypeName;
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 ValidAccessMask;
BOOLEAN SecurityRequired;
BOOLEAN MaintainHandleCount;
UCHAR TypeIndex; // since WINBLUE
CHAR ReservedByte;
ULONG PoolType;
ULONG DefaultPagedPoolCharge;
ULONG DefaultNonPagedPoolCharge;
} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;
typedef struct _OBJECT_TYPES_INFORMATION {
LONG NumberOfTypes;
OBJECT_TYPE_INFORMATION TypeInformation [1];
} OBJECT_TYPES_INFORMATION, *POBJECT_TYPES_INFORMATION;
typedef NTSTATUS (__stdcall* typedef_NtQueryObject)(
HANDLE Handle,
OBJECT_INFORMATION_CLASS ObjectInformationClass,
PVOID ObjectInformation,
ULONG ObjectInformationLength,
PULONG ReturnLength
);
#define PAD_8(p) (((p) + 7) & ~7)
int main(void) {
HMODULE hNtDLL = GetModuleHandleW(L"ntdll.dll");
if (!hNtDLL) {
return -1;
}
typedef_NtQueryObject myNtQueryObject = (typedef_NtQueryObject)GetProcAddress(hNtDLL, "NtQueryObject");
if (!myNtQueryObject) {
return -1;
}
NTSTATUS status = STATUS_SUCCESS;
POBJECT_TYPES_INFORMATION TypesInfo = NULL;
ULONG BufferLength = 0;
// 如果需要获取指定Handle的对象类型,可以把第一个参数的NULL换成Handle值
status = myNtQueryObject(NULL, ObjectTypesInformation, NULL, 0, &BufferLength);
if (status != STATUS_INFO_LENGTH_MISMATCH) {
return -1;
}
while (status == STATUS_INFO_LENGTH_MISMATCH) {
ULONG StartBufferLength = BufferLength;
if (TypesInfo) {
free(TypesInfo);
TypesInfo = NULL;
}
TypesInfo = (POBJECT_TYPES_INFORMATION)malloc(StartBufferLength);
memset(TypesInfo, 0, StartBufferLength);
if (!TypesInfo) {
return -1;
}
status = myNtQueryObject(NULL, ObjectTypesInformation, TypesInfo, StartBufferLength, &BufferLength);
}
POBJECT_TYPE_INFORMATION TypeInfoIterator = &TypesInfo->TypeInformation[0];
for (LONG i = 0; i < TypesInfo->NumberOfTypes; i++) {
std::wstring typeName;
typeName.resize(TypeInfoIterator->TypeName.Length / sizeof(WCHAR));
memcpy_s(&typeName[0], TypeInfoIterator->TypeName.Length, TypeInfoIterator->TypeName.Buffer, TypeInfoIterator->TypeName.Length);
std::wcout << "TypeIdx=" << i << ", TypeName=" << typeName.c_str() << std::endl;
// 注意:这里的结构在x64上必须按照8字节对齐
TypeInfoIterator = (POBJECT_TYPE_INFORMATION)(PAD_8((ULONG_PTR)TypeInfoIterator->TypeName.Buffer + TypeInfoIterator->TypeName.MaximumLength));
}
free(TypesInfo);
TypesInfo = NULL;
system("pause");
return 0;
}
运行结果: