Geoff Chappell, Software Analyst
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.