Retrieve handle type string using NtQueryObject

Hmm so after a long time I’m back with a new post.

This time I came across a cool API called NtQueryObject. One purpose of the API is to find the name of object type it’s given. For example if you are passing a process handle this API will return “Process” as the string. The caveat of using this API is that it can be changed in the future. So be very careful with the signature of the function, cross check with the documentation before using. Use it at your own risk.

So let’s see the code, since API doesn’t have a lib associated with it we’ll have to use GetProcAddress to retrieve function address. The function signature of NtQueryObject looks like…

[sourcecode language=”cpp”]NTSTATUS NtQueryObject(__in_opt HANDLE Handle,
                        __in OBJECT_INFORMATION_CLASS ObjectInformationClass,
                        __out_opt PVOID ObjectInformation,
                        __in ULONG ObjectInformationLength,
                        __out_opt PULONG ReturnLength );[/sourcecode]

The second parameter to the API can be of two types. The one type of interest for this case is PUBLIC_OBJECT_TYPE_INFORMATION. If we pass this type as second parameter then the API is expecting a PUBLIC_OBJECT_TYPE_INFORMATION as third parameter. The contents of the structure is as follows…

[sourcecode language=”cpp”]typedef struct __PUBLIC_OBJECT_TYPE_INFORMATION {
    UNICODE_STRING TypeName;
    ULONG Reserved [22];    // reserved for internal use
} PUBLIC_OBJECT_TYPE_INFORMATION, *PPUBLIC_OBJECT_TYPE_INFORMATION;[/sourcecode]

The first member in the structure is the one that returns the string, only issue we’ll have to allocate this in special manner. Please have a look in the below function to see how I’ve allocated memory for this structure.
[sourcecode language=”cpp”]void GetHandleTypeName(HANDLE hHandle, CString& TypeName)
{
 typedef NTSTATUS (NTAPI *NtQueryObjectPtr)(HANDLE Handle,
                   OBJECT_INFORMATION_CLASS ObjectInformationClass,
          PVOID ObjectInformation,
          ULONG ObjectInformationLength,
          PULONG ReturnLength);

HMODULE hMod = LoadLibrary(_T(“NtDll.dll”));
 NtQueryObjectPtr QueryObj = (NtQueryObjectPtr)::GetProcAddress(hMod, “NtQueryObject”);
 ASSERT(QueryObj);

ULONG OutSize = 0;
 NTSTATUS NtStatus = QueryObj(hHandle, ObjectTypeInformation, NULL, 0, &OutSize);
 PPUBLIC_OBJECT_TYPE_INFORMATION TypeInfo = (PPUBLIC_OBJECT_TYPE_INFORMATION)calloc(1, OutSize);
 ULONG InSize = OutSize;
 NtStatus = QueryObj(hHandle, ObjectTypeInformation, TypeInfo, InSize, &OutSize);
 TypeName = TypeInfo->TypeName.Buffer;
 free(TypeInfo);
}[/sourcecode]

[sourcecode language=’cpp’]// This is how we invoke the function note: GetCurrentProcess() call.
CString cs;
GetHandleTypeName(GetCurrentProcess(), cs);
MessageBox(cs);[/sourcecode]

Appreciate your comments...