获取Windows内核对象的索引与对象名

下列提出两种获取对象名的方式

  1. 通过_OBJECT_TYPE::Name获取对象名称,通过_OBJECT_TYPE::Index获取对象索引;
  2. 通过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;
}

运行结果:

posted @ 2023-11-29 16:25  倚剑问天  阅读(33)  评论(0编辑  收藏  举报