Geoff Chappell - Software Analyst
The KPROCESS structure (formally _KPROCESS) is the Kernel’s portion of the Executive’s EPROCESS structure. The latter is the process object as exposed through the Object Manager. The KPROCESS is the start of it.
The process is a fundamental object in Windows. The KPROCESS exists in all versions, i.e., 3.10 and higher.
For being fundamental, the KPROCESS has never been secret as something that exists. It is, however, deeply internal. It is not formally documented. Even among C-language headers in the Device Driver Kit (DDK) or Windows Driver Kit (WDK), the KPROCESS is only ever declared as an opaque type: its contents are never defined.
Though Microsoft is not known ever to have published a C-language definition of the KPROCESS, the practical equivalent is disclosed as type information in public symbol files for the kernel starting with Windows 2000 SP3. One earlier disclosure of type information is known from a statically linked library, named craShlib.Lib (sic), which Microsoft distributed with the Win32 SDK in 1996. Though it is supplied to help with building the user-mode Dr. Watson sample, it has type information that matches the kernel-mode KPROCESS for version 4.0.
Presumably because the KPROCESS is only as much of the process’s representation as needed by the core of the kernel, it has very little exposure independently of its nesting in the EPROCESS as the latter’s Pcb member. Where code outside the kernel refers to a process by address, what will almost always be wanted is the larger EPROCESS. Notable exceptions are the KTHREAD and KAPC_STATE: being other creatures of the kernel’s core, these each have a member named Process that points to a KPROCESS.
The KPROCESS structure is plainly internal to the kernel and its layout changes greatly between Windows versions and even between builds. Throughout this article, early and late builds within a version have the following cut-offs:
Though the KPROCESS is highly variable, it has grown mostly by appending. This article attempts to lay out the structure’s members as one sequence for all versions. The following changes of size are known:
Version | Size (x86) | Size (x64) |
---|---|---|
3.10 | 0x70 | |
3.50 to 4.0 | 0x68 | |
5.0 to early 5.2 | 0x6C | |
late 5.2 | 0x78 | 0xB8 |
6.0 | 0x80 | 0xC0 |
6.1 | 0x98 | 0x0160 |
6.2 to 6.3 | 0xA0 | 0x02C8 |
10.0 to 1607 | 0xA8 | 0x02D8 |
1703 to 1809 | 0xB0 | 0x02D8 |
1903 | 0xB0 | 0x02E0 |
2004 | 0xE0 | 0x0438 |
These sizes, and the offsets, types and names in the tables that follow, are from Microsoft’s public symbol files for the kernel starting with Windows 2000 SP3. Since symbol files for earlier versions do not contain type information for the KPROCESS, what’s known for earlier versions is instead inferred from what use the kernel is seen to make of the KPROCESS. Sizes are relatively straightforward, even without symbol files, but Microsoft’s names and types are something of a guess. Where use of a member corresponds closely with that of a version for which Microsoft’s symbols are available, 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.
For the detailed layout in the tables that follow, it helps with some processor-dependent definitions if a macro, say MAX_PROC_GROUPS, is presumed for the maximum number of processor groups:
Note that the intention here is not to say that these limits on processor groups are permanent, let alone that they should be depended on when programming, just that they’re what are built in to various members of the KPROCESS in the presently observed Windows versions.
It is well known even to user-mode programmers that a process can be waited on until it gets signalled, as happens when the process ends its execution. In version 3.50 and higher, this is effected by having the KPROCESS start with a DISPATCHER_HEADER so that it can be waited on by passing its address to such functions as KeWaitForSingleObject. In this header, the Type is ProcessObject (3) from the KOBJECTS enumeration.
It was not always so, however. In all versions, the EPROCESS can be waited on by passing a handle to NtWaitForSingleObject, but what’s actually waited on in version 3.10 is a KEVENT at offset 0x70 in the EPROCESS. The KPROCESS originally has no role in this. It does not begin with a DISPATCHER_HEADER, but like the other kernel objects that do not have this header, it does begin with a Type and Size. In version 3.10, this Type was surely named ProcessObject, as for later versions, but its numerical value is 0x0E.
Offset (x86) | Offset (x64) | Definition | Versions | Remarks |
---|---|---|---|---|
0x00 (3.10) |
USHORT Type; |
3.10 only | next in Header at 0x00 | |
0x02 (3.10) |
USHORT Size; |
3.10 only | next in Header at 0x00 | |
0x04 (3.10) |
ULONG StackCount; |
3.10 only | next as USHORT at 0x60 | |
0x00 | 0x00 |
DISPATCHER_HEADER Header; |
3.50 and higher | |
0x08 (3.10); 0x10 |
0x18 |
LIST_ENTRY ProfileListHead; |
all |
Whether the header is the full DISPATCHER_HEADER or just something a little like one, it has somehow always been followed by the list head for process-specific KPROFILE objects. Pretty much everything else that’s original to the KPROCESS was rearranged even as soon as versions 3.50 and 3.51.
Offset (x86) | Offset (x64) | Definition | Versions | Remarks |
---|---|---|---|---|
0x10 (3.10); 0x18 (3.50) |
LIST_ENTRY ReadyListHead; |
3.10 to 3.50 | next at 0x40 | |
0x18 (3.10); 0x20 (3.50) |
LIST_ENTRY SwapListEntry; |
3.10 to 3.50 | next at 0x48 | |
0x20 (3.10); 0x28 (3.50) |
LIST_ENTRY ThreadListHead; |
3.10 to 3.50 | next at 0x50 | |
0x28 (3.10); 0x30 (3.50) |
LARGE_INTEGER KernelTime; |
3.10 only | ||
ULONG KernelTime; |
3.50 only | next at 0x38 | ||
0x30 (3.10); 0x34 (3.50) |
LARGE_INTEGER UserTime; |
3.10 only | ||
ULONG UserTime; |
3.50 only | next at 0x3C | ||
0x38 (3.10 to 3.50); 0x18 |
0x28 |
ULONG_PTR DirectoryTableBase [2]; |
3.10 to 5.2 | |
ULONG_PTR DirectoryTableBase; |
6.0 and higher | |||
0x1C (6.0) | 0x30 (6.0) |
ULONG_PTR Unused0; |
6.0 only | |
0x40 (3.10) | unknown KSPIN_LOCK | 3.10 only | ||
0x44 (3.10) |
ULONG Iopl; |
3.10 only | next as UCHAR at 0x5E | |
0x48 (3.10); 0x3C (3.50) |
unaccounted eight bytes | 3.10 to 3.50 | ||
0x50 (3.10) |
LONG ThreadQuantum; |
3.10 only | next as CHAR at 0x65 | |
0x54 (3.10); 0x44 (3.50) |
KAFFINITY ActiveProcessors; |
3.10 to 3.50 | next at 0x34 | |
0x58 (3.10); 0x48 (3.50) |
KAFFINITY Affinity; |
3.10 to 3.50 | next at 0x5C | |
0x5C (3.10); 0x4C (3.50); 0x20 (3.51 to 6.0); 0x1C |
KGDTENTRY LdtDescriptor; |
all | ||
0x54 (3.50); 0x28 (3.51 to 6.0); 0x24 |
KIDTENTRY Int21Descriptor; |
3.50 and higher | ||
0x64 (3.10); 0x5C (3.50); 0x30 (3.51 to 6.0) |
0x38 (late 5.2 to 6.0) |
USHORT IopmOffset; |
3.10 to 6.0 | next at 0x6E (x86) |
0x5E (3.50); 0x32 (3.51 to 6.0) |
UCHAR Iopl; |
3.50 to early 6.0 | previously ULONG at 0x44 | |
UCHAR Unused1; |
late 6.0 only | |||
0x66 (3.10); 0x5F (3.50); 0x33 (3.51 to 6.0) |
UCHAR VdmFlag; |
3.10 to 5.0 | ||
UCHAR Unused; |
5.1 to early 6.0 | |||
UCHAR Unused2; |
late 6.0 only | |||
0x34 (3.51 to 6.0) | 0x40 (late 5.2 to 6.0) |
KAFFINITY ActiveProcessors; |
3.51 to 5.1 | previously 0x44 |
KAFFINITY volatile ActiveProcessors; |
5.2 to 6.0 | next as KAFFINITY_EX volatile at 0x50 and 0x88 | ||
0x38 (3.51 to 6.0) | 0x48 (5.0 to 6.0) |
ULONG KernelTime; |
3.51 to 6.0 | previously 0x30; next at 0x88 and 0xF8 |
0x3C (3.51 to 6.0) | 0x4C (5.0 to 6.0) |
ULONG UserTime; |
3.51 to 6.0 | previously 0x34; next at 0x8C and 0xFC |
0x2C | 0x30 |
LIST_ENTRY ThreadListHead; |
6.1 and higher | previously 0x50 and 0x70 |
0x34 | 0x40 |
ULONG_PTR ProcessLock; |
6.1 only | previously 0x58 and 0x80 |
ULONG ProcessLock; |
6.2 and higher | |||
0x44 |
ULONG Spare0; |
6.2 to 1607 | ||
ULONG ProcessTimerDelay; |
1703 and higher | at 0xAC for x86 | ||
0x38 | 0x48 |
ULONGLONG DeepFreezeStartTime; |
10.0 and higher | |
0x38 (6.1 to 6.3); 0x40 |
0x48 (6.1 to 6.3); 0x50 |
KAFFINITY_EX Affinity; |
6.1 and higher | previously KAFFINITY at 0x5C and 0x88 |
0xF8 |
ULONGLONG AffinityPadding [0x0C]; |
2004 and higher | ||
0x40 (3.51 to 6.0); 0x44 (6.1 to 6.3); 0x4C |
0x50 (late 5.2 to 6.0); 0x70 (6.1); 0xF0 (6.2 to 6.3); 0xF8 (10.0 to 1903); 0x0158 |
LIST_ENTRY ReadyListHead; |
3.51 and higher | previously 0x18 |
0x48 (3.51 to 6.0); 0x4C (6.1 to 6.3); 0x54 |
LIST_ENTRY SwapListEntry; |
3.51 to 5.0 | previously 0x20 | |
0x60 (late 5.2 to 6.0); 0x80 (6.1); 0x0100 (6.2 to 6.3); 0x0108 (10.0 to 1903); 0x0168 |
SINGLE_LIST_ENTRY SwapListEntry; |
5.1 and higher | ||
0x50 (6.1 to 6.3); 0x58 |
0x88 (6.1); 0x0108 (6.2 to 6.3); 0x0110 (10.0 to 1903); 0x0170 |
KAFFINITY_EX volatile ActiveProcessors; |
6.1 and higher | previously KAFFINITY volatile at 0x34 and 0x40 |
0x0218 |
ULONGLONG ActiveProcessorsPadding [0x0C]; |
2004 and higher | ||
0x4C (5.1 to 6.0) |
PVOID VdmTrapcHandler; |
5.1 to 6.0 | next at 0x90 | |
0x68 (late 5.2 to 6.0) |
PVOID Reserved1; |
late 5.2 only | ||
PVOID InstrumentationCallback; |
6.0 only | next at 0x0100 | ||
0x50 (3.51 to 6.0) | 0x70 (late 5.2 to 6.0) |
LIST_ENTRY ThreadListHead; |
3.51 to 6.0 | previously 0x28; next at 0x2C and 0x30 |
0x58 (3.51 to 6.0) | 0x80 (late 5.2 to 6.0) |
KSPIN_LOCK ProcessLock; |
3.51 to 6.0 | next at 0x34 and 0x40 |
0x5C (3.51 to 6.0) | 0x88 (late 5.2 to 6.0) |
KAFFINITY Affinity; |
3.51 to 6.0 | previously at 0x48; next as KAFFINITY_EX at 0x40 and 0x50 |
0x60 (3.50 to early 5.2) |
USHORT StackCount; |
3.50 to early 5.2 | previously as ULONG at 0x04; next as ULONG_PTR at 0x6C and 0xA0 |
|
0x60 (late 5.2 to 6.0); 0x5C (6.1 to 6.3); 0x64 |
0x90 (late 5.2 to 6.0); 0xB0 (6.1); 0x01B0 (6.2 to 6.3); 0x01B8 (10.0 to 1903); 0x0278 |
union { struct { /* bit fields, follow link */ }; LONG ProcessFlags; }; |
late 5.2 only | |
union { struct { /* bit fields, follow link */ }; LONG volatile ProcessFlags; }; |
6.0 and higher | |||
0x67 (3.10); 0x62 (3.50) |
BOOLEAN AutoAlignment; |
3.10 to 3.50 | next at 0x64 | |
0x01BC (1903); 0x027C |
ULONG ActiveGroupsMask; |
1903 and higher | previously in ProcessFlags | |
0x68 (3.10); 0x63 (3.50); 0x62 (3.51 to early 5.2); 0x64 (late 5.2 to 6.0); 0x60 (6.1 to 6.3); 0x68 |
0x94 (late 5.2 to 6.0); 0xB4 (6.1); 0x01B4 (6.2 to 6.3); 0x01BC (10.0 to 1809); 0x01C0 (1903); 0x0280 |
CHAR BasePriority; |
all | |
0x69 (3.10); 0x64 (3.50) |
UCHAR State; |
3.10 to 3.50 | next at 0x65; last member in 3.10 |
|
0x65 (3.50); 0x63 (3.51 to early 5.2); 0x65 (late 5.2 to 6.0); 0x61 (6.1 to 6.3); 0x69 |
0x95 (late 5.2 to 6.0); 0xB5 (6.1); 0x01B5 (6.2 to 6.3); 0x01BD (10.0 to 1809); 0x01C1 (1903); 0x0281 |
CHAR ThreadQuantum; |
3.50 to early 5.2 | previously LONG at 0x50; last member in 3.50 |
CHAR QuantumReset; |
late 5.2 and higher | |||
0x64 (3.51 to early 5.2) |
BOOLEAN AutoAlignment; |
3.51 to early 5.2 | previously 0x62; next in ProcessFlags |
|
0x65 (3.51 to early 5.2); 0x66 (late 5.2 to 6.0) |
0x96 (late 5.2 to 6.0) |
UCHAR State; |
3.51 to 6.0 | previously 0x64; next in StackCount; last member in 3.51 |
Whatever may have motivated the reordering of byte-size members at the end in versions 3.10 to 3.51, all these versions end the structure with unused space because of alignment: six bytes in 3.10 because of the structure’s 8-byte alignment (from using LARGE_INTEGER for KernelTime and UserTime); two bytes in versions 3.50 and 3.51.
Version 4.0 adds just two bytes which anyway fit into the earlier versions’ alignment padding. Neither stays put.
Offset (x86) | Offset (x64) | Definition | Versions | Remarks |
---|---|---|---|---|
0x66 (4.0 to early 5.2); 0x67 (late 5.2 to 6.0) |
0x97 (late 5.2 to 6.0) |
UCHAR ThreadSeed; |
4.0 to 6.0 | next as ULONG array at 0x64 and 0xB8 |
0x67 (4.0 to early 5.2) |
BOOLEAN DisableBoost; |
4.0 to early 5.2 | next in ProcessFlags; last member in 4.0 |
The ThreadSeed helps to spread the process’s threads over the available processors. It is initialised pseudo-randomly (from the low byte of KeTickCount) when the process is created. As each thread is initialised, the process’s ThreadSeeed (modulo the number of processors) becomes that thread’s IdealProcessor and is then incremented in anticipation of the next thread. When Windows 7 greatly increased the potential number of processors, the single-byte processor number widened to the four-byte processor index and the ThreadSeed was reworked elsewhere in the structure.
Offset (x86) | Offset (x64) | Definition | Versions | Remarks |
---|---|---|---|---|
0x68 (5.0 to 6.0) | 0x98 (late 5.2 to 6.0) |
UCHAR PowerState; |
5.0 to 6.0 | |
0x69 (5.0 to early 5.2) |
BOOLEAN DisableQuantum; |
5.0 to early 5.2 | next in ProcessFlags | |
0x6A (5.0) |
UCHAR Spare [2]; |
5.0 only | last member in 5.0 |
Additions for version 5.1 begin with the bytes that version 5.0 left explicitly Spare at its end.
Offset (x86) | Offset (x64) | Definition | Versions | Remarks |
---|---|---|---|---|
0x6A (5.1 to early 5.2); 0x69 (late 5.2 to 6.0) |
0x99 (late 5.2 to 6.0) |
UCHAR IdealNode; |
5.1 to 6.0 | next as USHORT array at 0x68 and 0xC8 |
0x6A (late 5.2 to 6.0); 0x62 (6.1 to 6.3); 0x6A |
0x9A (late 5.2 to 6.0); 0xB6 (6.1); 0x01B6 (6.2 to 6.3); 0x01BE (10.0 to 1809); 0x01C2 (1903); 0x0282 |
BOOLEAN Visited; |
late 5.2 and higher | |
0x6B (5.1 to 6.0); 0x63 (6.1 to 6.3); 0x6B |
UCHAR Spare; |
early 5.1; early 5.2 |
last member in early 5.1; last member in early 5.2 |
|
0x9B (late 5.2 to 6.0); 0xB7 (6.1); 0x01B7 (6.2 to 6.3); 0x01BF (10.0 to 1809); 0x01C3 (1903); 0x0283 |
union { KEXECUTE_OPTIONS Flags; UCHAR ExecuteOptions; }; |
late 5.1; late 5.2 to 6.0 |
next without union at 0x6C and 0xD2; last member in late 5.1 |
|
UCHAR Spare3; |
6.1 only | |||
KEXECUTE_OPTIONS Flags; |
6.2 and higher | previously at 0x6C and 0xD2 |
Offset (x86) | Offset (x64) | Definition | Versions | Remarks |
---|---|---|---|---|
0x64 (6.1 to 6.3); 0x6C |
0xB8 (6.1); 0x01B8 (6.2 to 6.3); 0x01C0 (10.0 to 1809); 0x01C4 (1903); 0x0284 |
ULONG ThreadSeed [MAX_PROC_GROUPS]; |
6.1 to 1809 | previously UCHAR at 0x67 and 0x97 |
USHORT ThreadSeed [MAX_PROC_GROUPS]; |
1903 and higher | |||
0x02AC |
USHORT ThreadSeedPadding [0x0C]; |
2004 and higher | ||
0x6E | 0x01EC (1903); 0x02C4 |
USHORT IdealProcessor [MAX_PROC_GROUPS]; |
1903 and higher | |
0x02EC |
USHORT IdealProcessorPadding [0x0C]; |
2004 and higher | ||
0x68 (6.1 to 6.3); 0x70 |
0xC8 (6.1); 0x0208 (6.2 to 6.3); 0x0210 (10.0 to 1809); 0x0214 (1903); 0x0304 |
USHORT IdealNode [MAX_PROC_GROUPS]; |
6.1 and higher | previously UCHAR at 0x69 and 0x99 |
0x032C |
USHORT IdealNodePadding [0x0C]; |
2004 and higher | ||
0x6A (6.1 to 6.3); 0x72 |
0xD0 (6.1); 0x0230 (6.2 to 6.3); 0x0238 (10.0 to 1809); 0x023C (1903); 0x0344 |
USHORT IdealGlobalNode; |
6.1 and higher | |
0x6C (6.1 to 6.3); 0x74 |
0xD2 (6.1); 0x0232 (6.2 to 6.3); 0x023A (10.0 to 1809); 0x023E (1903); 0x0346 |
KEXECUTE_OPTIONS Flags; |
6.1 only | previously in union at 0x6B and 0x9B; next at 0x63 and 0x01B7 |
USHORT Spare1; |
6.2 and higher | |||
0x6D (6.1) | 0xD3 (6.1) |
UCHAR Unused1; |
6.1 only | |
0x6E (6.1 to 6.3); 0x76 |
USHORT IopmOffset; |
6.1 and higher | previously at 0x30 | |
0xD4 (6.1) |
ULONG Unused2; |
6.1 only | ||
0x70 (6.1 to 6.3); 0x78 |
0xD8 (6.1) |
ULONG Unused4; |
6.1 only | |
KSCHEDULING_GROUP *SchedulingGroup; |
6.2 and higher | x64 at 0x0258 |
While the first version with x64 builds found a few opportunities to save space by converting the AutoAlignment, DisableBoost and DisableQuantum booleans to bit fields in what were then the new ProcessFlags, it widened the StackCount and moved it to the end. Version 6.1 merged the ancient State into the StackCount as a bit field.
Offset (x86) | Offset (x64) | Definition | Versions | Remarks |
---|---|---|---|---|
0x6C (late 5.2 to 6.0); 0x74 (6.1 to 6.3); 0x7C |
0xA0 (late 5.2 to 6.0); 0xDC (6.1); 0x0234 (6.2 to 6.3); 0x023C (10.0 to 1809); 0x0240 (1903); 0x0348 |
ULONG_PTR StackCount; |
late 5.2 to 6.0 | previously USHORT at 0x60 |
KSTACK_COUNT StackCount; |
6.1 only | |||
KSTACK_COUNT volatile StackCount; |
6.2 and higher | |||
0x70 (late 5.2 to 6.0); 0x78 (6.1 to 6.3); 0x80 |
0xA8 (late 5.2 to 6.0); 0xE0 (6.1); 0x0238 (6.2 to 6.3); 0x0240 (10.0 to 1809); 0x0248 (1903); 0x0350 |
LIST_ENTRY ProcessListEntry; |
late 5.2 and higher | last member in late 5.2 |
On x64 builds only, the ProcessListEntry links the KPROCESS into a global list whose head is an internal kernel variable that symbol files name KiProcessListHead. The only known use is for Kernel Patch Protection (perhaps more commonly known as PatchGuard). The list entry is defined all the while for the x86 builds, but not even initialised.
Offset (x86) | Offset (x64) | Definition | Versions | Remarks |
---|---|---|---|---|
0x78 (6.0); 0x80 (6.1 to 6.3); 0x88 |
0xB8 (late 5.2 to 6.0); 0xF0 (6.1); 0x0248 (6.2 to 6.3); 0x0250 (10.0 to 1809); 0x0258 (1903); 0x0360 |
ULONGLONG volatile CycleTime; |
6.0 to 6.1 | last member in 6.0 |
ULONGLONG CycleTime; |
6.2 and higher |
Offset (x86) | Offset (x64) | Definition | Versions | Remarks |
---|---|---|---|---|
0x88 (6.2 to 6.3); 0x90 |
0x0250 (6.2 to 6.3); 0x0258 (10.0 to 1809); 0x0260 (1903); 0x0368 |
ULONGLONG ContextSwitches; |
6.2 and higher | |
0x0258 (6.2 to 6.3); 0x0260 (10.0 to 1809); 0x0268 (1903); 0x0370 |
KSCHEDULING_GROUP *SchedulingGroup; |
6.2 and higher | x86 at 0x70 | |
0x90 (6.2 to 6.3); 0x98 |
0x0260 (6.2 to 6.3); 0x0268 (10.0 to 1809); 0x0270 (1903); 0x0378 |
ULONG FreezeCount; |
6.2 and higher |
Version 6.1 did not so much append to the structure as move some old, even ancient, members to the end.
Offset (x86) | Offset (x64) | Definition | Versions | Remarks |
---|---|---|---|---|
0x88 (6.1); 0x94 (6.2 to 6.3); 0x9C |
0xF8 (6.1); 0x0264 (6.2 to 6.3); 0x026C (10.0 to 1809); 0x0274 (1903); 0x037C |
ULONG KernelTime; |
6.1 and higher | previously 0x38 and 0x48 |
0x8C (6.1); 0x98 (6.2 to 6.3); 0xA0 |
0xFC (6.1); 0x0268 (6.2 to 6.3); 0x0270 (10.0 to 1809); 0x0278 (1903); 0x0380 |
ULONG UserTime; |
6.1 and higher | previously 0x3C and 0x4C |
0xA4 | 0x0274 (1703 to 1809); 0x027C (1903); 0x0384 |
ULONG ReadyTime; |
1703 and higher | |
0x90 (6.1); 0x9C (6.2 to 6.3); 0xA4 (10.0 to 1607); 0xA8 |
PVOID VdmTrapcHandler; |
6.1 and higher | previously 0x4C; last member in 6.1 to 1607 (x86) |
|
0xAC |
ULONG ProcessTimerDelay; |
1703 and higher | at 0x44 for x64; last member in 1703 to 1903 (x86) |
The only truly new members that Windows 7 added are for 64-bit Windows only. Even these relatively few additions are not pretty, since shifts in preceding members allowed version 6.2 to get tighter packing just from rearranging what version 6.1 added.
Offset (x64) | Definition | Versions | Remarks |
---|---|---|---|
0x0100 (6.1) |
PVOID InstrumentationCallback; |
6.1 only | previously 0x68; next at 0x02C0 |
0x0108 (6.1) |
KDGENTRY64 LdtSystemDescriptor; |
6.1 only | next at 0x0270 |
0x0118 (6.1) |
PVOID LdtBaseAddress; |
6.1 only | next at 0x0280 |
0x0120 (6.1) |
KGUARDED_MUTEX LdtProcessLock; |
6.1 only | next as FAST_MUTEX at 0x0288 |
0x0158 (6.1); 0x026C (6.2 to 6.3); 0x0274 (10.0 to 1607) |
USHORT LdtFreeSelectorHint; |
6.1 to 1607 | |
0x015A (6.1); 0x026E (6.2 to 6.3); 0x0276 (10.0 to 1607) |
USHORT LdtTableLength; |
6.1 to 1607 | last member in 6.1 (x64) |
0x0270 (6.2 to 6.3); 0x0278 (10.0 to 1607) |
KGDTENTRY64 LdtSystemDescriptor; |
6.2 to 1607 | previously 0x0108 |
0x0280 (6.2 to 6.3); 0x0288 (10.0 to 1607) |
PVOID LdtBaseAddress; |
6.2 to 1607 | previously 0x0118 |
0x0288 (6.2 to 6.3); 0x0290 (10.0 to 1607) |
FAST_MUTEX LdtProcessLock; |
6.2 to 1607 | previously KGUARDED_MUTEX at 0x0120 |
0x0278 (1803 to 1809); 0x0280 (1903); 0x0388 |
ULONGLONG UserDirectoryTableBase; |
1803 and higher | |
0x0280 (1803 to 1809); 0x0288 (1903); 0x0390 |
UCHAR AddressPolicy; |
1803 and higher | |
0x0278 (1703 to 1709); 0x0281 (1803 to 1809); 0x0289 (1903); 0x0391 |
UCHAR Spare2 [0x50]; |
1703 to 1709 | |
UCHAR Spare2 [0x47]; |
1803 and higher | ||
0x02C0 (6.2 to 6.3); 0x02C8 (10.0 to 1809); 0x02D0 (1903); 0x03D8 |
PVOID InstrumentationCallback; |
6.2 and higher | previously 0x0100; last member in 6.2 to 6.3 (x64) |
0x02D0 (10.0 to 1809); 0x02D8 (1903); 0x03E0 |
ULONGLONG SecurePid; |
10.0 to 1703 | last member in 10.0 to 1703 (x64) |
union { ULONGLONG SecureHandle; struct { ULONGLONG SecureProcess : 1; ULONGLONG Unused : 1; } Flags; } SecureState; |
1709 and higher | last member in 1709 to 1903 (x64) |
Offset (x86) | Offset (x64) | Definition | Versions | Remarks |
---|---|---|---|---|
0xB0 | 0x03E8 |
ULONGLONG KernelWaitTime; |
2004 and higher | |
0xB8 | 0x03F0 |
ULONGLONG UserWaitTime; |
2004 and higher | |
0xC0 | 0x03F8 |
ULONG_PTR EndPadding [8]; |
2004 and higher | last member in 2004 |