Object Handle tracing in ETW

634 views Asked by At

Process Explorer from Sysinternals displays all the handles held by a process, with fields such as the object's name, type, address and the handle value. For example:

https://i.stack.imgur.com/hlUQI.png

ETW's NT Kernel Logger trace session has events for handle operations with the syntax:

class ObHandleEvent : ObTrace
{
  uint32 Handle;
  uint32 Object;
  string ObjectName;
  uint16 ObjectType;
};

My question is this: ObjectType in ETW is a 16-bit integer. How to map the integer ObjectType value to the corresponding object type name (as displayed in Process Explorer)?

1

There are 1 answers

1
Alois Kraus On

I think the kernel object types are the ones you are after. Check out in a Kernel debugger or livekd with the command

0: kd> !object \ObjectTypes
Object: ffffe589f9c17aa0  Type: (ffffb28572cd3820) Directory
    ObjectHeader: ffffe589f9c17a70 (new version)
    HandleCount: 0 PointerCount: 68
    Directory Object: ffffe589f9c14a60  Name: ObjectTypes

    Hash Address          Type                      Name
    ---- -------          ----                      ----
     00  ffffb28572d7e180 Type                      TmTm
     01  ffffb28572d76310 Type                      Desktop
         ffffb28572c3e680 Type                      Process
     02  ffffb28572d53ad0 Type                      EnergyTracker
         ffffb28572d5cbb0 Type                      RegistryTransaction
     03  ffffb28572cccc60 Type                      DebugObject
     04  ffffb28575682520 Type                      VRegConfigurationContext
         ffffb28572ccc440 Type                      TpWorkerFactory
     05  ffffb28572d6da20 Type                      Adapter
         ffffb28572ccfc40 Type                      Token
     06  ffffb2857562ebb0 Type                      DxgkSharedResource
     07  ffffb28572ccb560 Type                      PsSiloContextPaged
     ....

Then you can dump the object header with

0: kd> dt nt!_OBJECT_TYPE ffffb28572d68e80
   +0x000 TypeList         : _LIST_ENTRY [ 0xffffb285`72d68e80 - 0xffffb285`72d68e80 ]
   +0x010 Name             : _UNICODE_STRING "Section"
   +0x020 DefaultObject    : 0xfffff801`a03c4680 Void
   **+0x028 Index            : 0x29 ')'**
   +0x02c TotalNumberOfObjects : 0x4943
   +0x030 TotalNumberOfHandles : 0xf50
   +0x034 HighWaterNumberOfObjects : 0x4ccc
   +0x038 HighWaterNumberOfHandles : 0x10c3
   +0x040 TypeInfo         : _OBJECT_TYPE_INITIALIZER
   +0x0b8 TypeLock         : _EX_PUSH_LOCK
   +0x0c0 Key              : 0x74636553
   +0x0c8 CallbackList     : _LIST_ENTRY [ 0xffffb285`72d68f48 - 0xffffb285`72d68f48 ]

The Index field should relate to the corresponding ETW event. I am not sure if this index is constant between windows versions but I think not.

Process Hacker (the better process explorer) formats the object type with this method:

static VOID PhpDumpObjectInfo(
    _In_ PPH_OBJECT_HEADER ObjectHeader
    )
{
    PVOID object;
    PPH_OBJECT_TYPE objectType;

    object = PhObjectHeaderToObject(ObjectHeader);
    objectType = PhGetObjectType(object);

    __try
    {
        wprintf(L"Type: %s\n", objectType->Name);
        wprintf(L"Reference count: %d\n", ObjectHeader->RefCount);
        wprintf(L"Flags: %x\n", ObjectHeader->Flags);

        if (objectType == PhObjectTypeObject)
        {
            wprintf(L"Name: %s\n", ((PPH_OBJECT_TYPE)object)->Name);
            wprintf(L"Number of objects: %u\n", ((PPH_OBJECT_TYPE)object)->NumberOfObjects);
            wprintf(L"Flags: %u\n", ((PPH_OBJECT_TYPE)object)->Flags);
            wprintf(L"Type index: %u\n", ((PPH_OBJECT_TYPE)object)->TypeIndex);
            wprintf(L"Free list count: %u\n", ((PPH_OBJECT_TYPE)object)->FreeList.Count);
        }
        else if (objectType == PhStringType)
        {
            wprintf(L"%s\n", ((PPH_STRING)object)->Buffer);
        }

That should give you some pointers where to look next.