KOBJECTS

The kernel’s core has its own set of objects that it works with independently of the Object Manager. Many kernel objects, but not all, begin with a DISPATCHER_HEADER. Some kernel objects, but not all, are the beginning of an object that is managed by the Object Manager. Consider, for example, the process object that is referred to when a handle is obtained to a process: it is an EPROCESS which has the kernel’s KPROCESS at its start. All kernel objects begin with a byte or word that signifies the type of object. The signifiers are formally defined as the KOBJECTS enumeration.

Microsoft does not document the KOBJECTS enumeration, nor even declare it in header files from any Windows Driver Kit (WDK). However, Microsoft’s names for it and its values are known from symbol files for Windows Vista and higher. Since symbol files for earlier versions do not contain type information for KOBJECTS, what’s known for these earlier versions is instead inferred from inspecting different versions of the kernel for corresponding use. Where close correspondence is found it seems reasonable to suppose continuity. Some use, however, has no correspondence, the code having changed too much. Even where the use hasn’t changed, tracking it down exhaustively would be difficult, if not impossible, even with source code. Beware, then, that the description below is something of a guess before Windows Vista.

Value Symbol Object Versions
0x00 EventNotificationObject KEVENT 3.51 and higher
0x01 EventSynchronizationObject KEVENT 3.51 and higher
0x02 MutantObject KMUTANT 3.51 and higher
0x03 ProcessObject KPROCESS 3.51 and higher
0x04 QueueObject KQUEUE 3.51 and higher
0x05 SemaphoreObject KSEMAPHORE 3.51 and higher
0x06 ThreadObject KTHREAD 3.51 and higher
0x07 TimerObject (proposed) KTIMER 3.51 only
SpareObject (proposed)   4.0 to 5.2 before Windows Server 2003 SP1
GateObject KGATE 5.2 from Windows Server 2003 SP1, and higher
0x08 TimerNotificationObject KTIMER 4.0 and higher
0x09 TimerSynchronizationObject KTIMER 4.0 and higher
0x0A Spare2Object   4.0 and higher
0x0B Spare3Object   4.0 and higher
0x0C Spare4Object   4.0 and higher
0x0D Spare5Object   4.0 and higher
0x0E Spare6Object   4.0 and higher
0x0F Spare7Object   4.0 and higher
0x10 Spare8Object   4.0 and higher
0x11 Spare9Object   4.0 to 6.1
ProfileCallbackObject KPROFILE (proposed) 6.2 and higher
0x08 (3.51);
0x12
ApcObject KAPC 3.51 and higher
0x09 (3.51);
0x13
DpcObject KDPC 3.51 and higher
0x0A (3.51);
0x14
DeviceQueueObject KDEVICE_QUEUE 3.51 and higher
0x0B (3.51);
0x15
EventPairObject KEVENT_PAIR (proposed) 3.51 and higher
PriQueueObject KPRIQUEUE 6.3 and higher
0x0C (3.51);
0x16
InterruptObject KINTERRUPT 3.51 and higher
0x17 ProfileObject KPROFILE (proposed) 4.0 and higher
0x18 Timer2NotificationObject KTIMER2 6.3 and higher
0x19 Timer2SynchronizationObject KTIMER2 6.3 and higher
0x18 (5.2 to 6.2);
0x1A
ThreadedDpcObject KDPC 5.2 and higher
0x0D (3.51);
0x18 (4.0 to 5.1);
0x19 (5.2 to 6.2);
0x1B
MaximumKernelObject    

It is not merely coincidental or neat that EventSynchronizationObject, TimerSynchronizationObject and Timer2SynchronizationObject are each one more than a multiple of 8. Kernel objects that begin with a DISPATCHER_HEADER—let’s call them dispatcher objects—are waitable. Their addresses can be passed to the KeWaitForSingleObject and KeWaitForMultipleObjects functions such that the function should not return unless the object or objects (all or any) get signalled. How a dispatcher object gets signalled varies with the object. What’s relevant to the KOBJECTS enumeration is that, starting with version 4.0, if a value in KOBJECTS signifies a dispatcher object and its low 3 bits are 1, then the object is specifically a synchronisation object: when it is signalled and a waiting thread is released from its wait, the object is automatically reset to non-signalled and no more threads are released from waiting until the object is signalled again.

The name TimerObject is proposed for 0x07 in version 3.51. The corresponding object is the same KTIMER that later versions support in two types. In version 3.51, the object is specifically a notification timer, but version 3.51 presumably has no notion of a TimerNotificationObject as separate from a TimerSynchronizationObject, just as it has only a KeInitializeTimer function, not the later KeInitializeTimerEx that can initialise either type.

No later use of any kernel object of type 0x07 is known until Windows Server 2003 SP1 introduced the gate object. It seems at least plausible that 0x07 was left as the original SpareObject or Spare1Object as a side-effect of skipping ahead to 0x08 and 0x09 for the new types of timer object so that notification versus synchronisation can be discerned in common for events and timers just from the low 3 bits.

The name KEVENT_PAIR is proposed for the object that corresponds to EventPairObject. It is just a 16-bit type, a 16-bit size and two KEVENT objects (specifically, two synchronisation events), but no structure with this layout is known from Microsoft’s symbol files for the kernel in any version. Whatever its name, the kernel’s structure for an event pair is exposed through the Object Manager such that event pairs, with and without names, can be created and worked with through such (undocumented) functions as NtCreateEventPair.

Similarly, Microsoft’s name for the object that’s signified by ProfileObject is not known, but there would be no surprise if it was KPROFILE. Whatever its name, it begins a very slightly larger structure that is exposed through the Object Manager such that profiles can be created and worked with through such (undocumented) functions as NtCreateProfile. It also is the object that corresponds to ProfileCallbackObject in Windows 8 and higher.