Geoff Chappell - Software Analyst
The ETHREAD structure is the kernel’s representation of a thread object. For instance, if the ObReferenceObjectByHandle function successfully resolves a handle though directed to do so only if the object type is PsThreadType, then the pointer that the function produces for the object is a pointer to an ETHREAD.
Many functions that are exported from the kernel, e.g., for use by drivers, provide for referring to a thread object through a pointer to an ETHREAD. However, the pointer is intended just as an identifier: the structure itself is plainly meant to be opaque outside the kernel.
Since the ETHREAD structure is internal to the kernel, it should not surprise that the layout changes greatly between Windows versions and even between builds. Some sense of the variability can be gained just from the structure’s changing size. In the following table, different builds of the same version are distinguished as early, late and even very late because they are known to vary the structure even if they don’t change the size. These descriptions are then used as a shorthand throughout this article and its companions.
Version | Size (x86) | Size (x64) |
---|---|---|
3.10 | 0x02E8 | |
3.50 to 4.0 | 0x0240 | |
5.0 | 0x0248 | |
5.1 | 0x0258 | |
early 5.2 (before SP1) | 0x0260 | |
late 5.2 (SP1) | 0x0250 | 0x0428 |
very late 5.2 (SP2) | 0x0250 | 0x0410 |
early 6.0 (before SP1); late 6.0 |
0x0288 | 0x0450 |
6.1 | 0x02B8 | 0x0498 |
6.2 | 0x02C0 | 0x04C8 |
6.3 | 0x0418 | 0x0778 |
10.0 to 1511 | 0x0458 | 0x07C0 |
1607 | 0x0460 | 0x07E0 |
1703 | 0x0480 | 0x0810 |
1709 to 1803 | 0x0480 | 0x0818 |
1809 | 0x0480 | 0x0810 |
1903 | 0x0488 | 0x0820 |
2004 | 0x04E0 | 0x0898 |
Offsets, types and names in the tables that follow, are from Microsoft’s symbol files for the kernel starting with Windows 2000 SP3. Since symbol files for earlier versions do not contain type information for the ETHREAD, Microsoft’s names and types are something of a guess from inspection of how the kernel in those versions uses the ETHREAD. Where use of a member corresponds closely with that of a version for which type information is available in Microsoft’s symbol files, 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 so much, tracking down the correspondence exhaustively would be difficult, if not impossible, even with source code.
For all versions, it is well known that the ETHREAD starts with a KTHREAD. The latter is the Kernel Core’s representation of the thread object. It is itself a dispatcher object, which has the useful effect that a handle to an ETHREAD can be waited on. It gets signalled when the thread terminates.
Almost all the shifting of offsets of ETHREAD members between versions is explained by the KTHREAD being even more variable—indeed, much more variable—than the ETHREAD. The only known difference between Windows Server 2003 SP1 and SP2 for the 64-bit builds is that the KTHREAD shrank. To save space, “late 5.2” for the 32-bit builds stands for “v. late 5.2” also.
Offset (x86) | Offset (x64) | Definition | Versions |
---|---|---|---|
0x00 | 0x00 |
KTHREAD Tcb; |
all |
0x01D8 (3.10); 0x01B0 (3.50 to 5.0); 0x01C0 (5.1); 0x01C8 (early 5.2); 0x01B8 (late 5.2); 0x01E0 (6.0); 0x0200 (6.1); 0x01E8 (6.2); 0x0338 (6.3); 0x0348 (10.0 to 1607); 0x0350 (1703 to 1809); 0x0358 (1903); 0x0280 |
LARGE_INTEGER CreateTime; |
3.10 to 4.0 | |
union { LARGE_INTEGER CreateTime; struct { UINT NestedFaultCount : 2; // 0x00000003 UINT ApcNeeded : 1; // 0x00000004 }; }; |
5.0 to early 5.2 | ||
0x0320 (late 5.2); 0x0308 (v. late 5.2); 0x0330 (6.0); 0x0360 (6.1); 0x0348 (6.2); 0x05D0 (6.3); 0x05D8 (10.0 to 1511); 0x05E0 (1607); 0x05E8 (1703); 0x05F0 (1709 to 1809); 0x0600 (1903); 0x0430 |
LARGE_INTEGER CreateTime; |
late 5.2 and higher |
In those builds that have CreateTime share space with bit fields, the CreateTime actually is in bits 3 to 63 as if it too is a bit field. It’s not that the low 3 bits are lost, but that the whole is shifted left by 3 bits.
Offset (x86) | Offset (x64) | Definition | Versions | Remarks |
---|---|---|---|---|
0x01E0 (3.10); 0x01B8 (3.50 to 5.0); 0x01C8 (5.1); 0x01D0 (early 5.2); 0x01C0 (late 5.2); 0x01E8 (6.0); 0x0208 (6.1); 0x01F0 (6.2); 0x0340 (6.3); 0x0350 (10.0 to 1607); 0x0358 (1703 to 1809); 0x0360 (1903); 0x0288 |
union { LARGE_INTEGER ExitTime; LIST_ENTRY LpcReplyChain; }; |
3.10 to 5.0 | ||
0x0328 (late 5.2); 0x0310 (v. late 5.2); 0x0338 (6.0); 0x0368 (6.1); 0x0350 (6.2); 0x05D8 (6.3); 0x05E0 (10.0 to 1511); 0x05E8 (1607); 0x05F0 (1703); 0x05F8 (1709 to 1809); 0x0608 (1903); 0x0438 |
union { LARGE_INTEGER ExitTime; LIST_ENTRY LpcReplyChain; LIST_ENTRY KeyedWaitChain; }; |
5.1 to 5.2 | ||
union { LARGE_INTEGER ExitTime; LIST_ENTRY KeyedWaitChain; }; |
6.0 and higher | |||
0x01E8 (3.10); 0x01C0 (3.50 to 5.0); 0x01D0 (5.1); 0x01D8 (early 5.2); 0x01C8 (late 5.2); 0x01F0 (6.0); 0x0210 (6.1) |
0x0338 (late 5.2); 0x0320 (v. late 5.2); 0x0348 (6.0); 0x0378 (6.1) |
union { LONG ExitStatus; PVOID OfsChain; }; |
3.10 to 6.0 | |
LONG ExitStatus; |
6.1 only | next at 0x0280 and 0x0450 | ||
0x01F8 (6.2); 0x0348 (6.3); 0x0358 (10.0 to 1607); 0x0360 (1703 to 1809); 0x0368 (1903); 0x0290 |
0x0360 (6.2); 0x05E8 (6.3); 0x05F0 (10.0 to 1511); 0x05F8 (1607); 0x0600 (1703) |
PVOID ChargeOnlySession; |
6.2 and higher (x86); 6.2 to 1703 (x64) |
next at 0x0698 (x64) |
0x01EC (3.10) | unknown dword | 3.10 only | ||
0x01F0 (3.10) | unknown dword | 3.10 only | ||
0x01C4 (3.50 to 5.0); 0x01D4 (5.1); 0x01DC (early 5.2); 0x01CC (late 5.2); 0x01F4 (6.0); 0x0214 (6.1); 0x01FC (6.2); 0x034C (6.3); 0x035C (10.0 to 1607); 0x0364 (1703 to 1809); 0x036C (1903); 0x0294 |
0x0340 (late 5.2); 0x0328 (v. late 5.2); 0x0350 (6.0); 0x0380 (6.1); 0x0368 (6.2); 0x05F0 (6.3); 0x05F8 (10.0 to 1511); 0x0600 (1607); 0x0608 (1703 to 1809); 0x0618 (1903); 0x0448 |
LIST_ENTRY PostBlockList; |
3.50 to 5.2 | previously at 0x02C4 |
union { LIST_ENTRY PostBlockList; struct { /* packed members, see below */ }; }; |
6.0 and higher |
Take away the construction, and these are the members that are packed with PostBlockList:
Offset (x86) | Offset (x64) | Definition | Versions | Remarks |
---|---|---|---|---|
0x01F4 (6.0); 0x0214 (6.1); 0x01FC (6.2); 0x034C (6.3); 0x035C (10.0 to 1607); 0x0364 (1703 to 1809); 0x036C (1903); 0x0294 |
0x0350 (6.0); 0x0380 (6.1); 0x0368 (6.2); 0x05F0 (6.3); 0x05F8 (10.0 to 1511); 0x0600 (1607); 0x0608 (1703 to 1809); 0x0618 (1903); 0x0448 |
PVOID ForwardLinkShadow; |
6.0 and higher | |
0x01F8 (6.0); 0x0218 (6.1); 0x0200 (6.2); 0x0350 (6.3); 0x0360 (10.0 to 1607); 0x0368 (1703 to 1809); 0x0370 (1903); 0x0298 |
0x0358 (6.0); 0x0388 (6.1); 0x0370 (6.2); 0x05F8 (6.3); 0x0600 (10.0 to 1511); 0x0608 (1607); 0x0610 (1703 to 1809); 0x0620 (1903); 0x0450 |
PVOID StartAddress; |
6.0 and higher | previously at 0x021C and 0x03D8 |
Yes, there is a plan to write something here.
Offset (x86) | Offset (x64) | Definition | Versions |
---|---|---|---|
0x01F4 (3.10); 0x01CC (3.50 to 5.0); 0x01DC (5.1); 0x01E4 (early 5.2); 0x01D4 (late 5.2); 0x01FC (6.0); 0x021C (6.1); 0x0204 (6.2); 0x0354 (6.3); 0x0364 (10.0 to 1607); 0x036C (1703 to 1809); 0x0374 (1903); 0x029C |
LIST_ENTRY TerminationPortList; |
3.10 to 5.0 | |
0x0350 (late 5.2); 0x0338 (v. late 5.2); 0x0360 (6.0); 0x0390 (6.1); 0x0378 (6.2); 0x0600 (6.3); 0x0608 (10.0 to 1511); 0x0610 (1607); 0x0618 (1703 to 1809); 0x0628 (1903); 0x0458 |
union { TERMINATION_PORT *TerminationPort; ETHREAD *ReaperLink; PVOID KeyedWaitValue; }; |
5.1 to 5.2 | |
union { TERMINATION_PORT *TerminationPort; ETHREAD *ReaperLink; PVOID KeyedWaitValue; PVOID Win32StartParameter; }; |
6.0 only | ||
union { TERMINATION_PORT *TerminationPort; ETHREAD *ReaperLink; PVOID KeyedWaitValue; }; |
6.1 and higher | ||
0x01FC (3.10); 0x01D4 (3.50 to 5.0); 0x01E0 (5.1); 0x01E8 (early 5.2); 0x01D8 (late 5.2); 0x0200 (6.0); 0x0220 (6.1); 0x0208 (6.2); 0x0358 (6.3); 0x0368 (10.0 to 1607); 0x0370 (1703 to 1809); 0x0378 (1903); 0x02A0 |
0x0358 (late 5.2); 0x0340 (v. late 5.2); 0x0368 (6.0); 0x0398 (6.1); 0x0380 (6.2); 0x0608 (6.3); 0x0610 (10.0 to 1511); 0x0618 (1607); 0x0620 (1703 to 1809); 0x0630 (1903); 0x0460 |
KSPIN_LOCK ActiveTimerListLock; |
all |
0x0200 (3.10); 0x01D8 (3.50 to 5.0); 0x01E4 (5.1); 0x01EC (early 5.2); 0x01DC (late 5.2); 0x0204 (6.0); 0x0224 (6.1); 0x020C (6.2); 0x035C (6.3); 0x036C (10.0 to 1607); 0x0374 (1703 to 1809); 0x037C (1903); 0x02A4 |
0x0360 (late 5.2); 0x0348 (v. late 5.2); 0x0370 (6.0); 0x03A0 (6.1); 0x0388 (6.2); 0x0610 (6.3); 0x0618 (10.0 to 1511); 0x0620 (1607); 0x0628 (1703 to 1809); 0x0638 (1903); 0x0468 |
LIST_ENTRY ActiveTimerListHead; |
all |
0x0208 (3.10); 0x01E0 (3.50 to 5.0); 0x01EC (5.1); 0x01F4 (early 5.2); 0x01E4 (late 5.2); 0x020C (6.0); 0x022C (6.1); 0x0214 (6.2); 0x0364 (6.3); 0x0374 (10.0 to 1607); 0x037C (1703 to 1809); 0x0384 (1903); 0x02AC |
0x0370 (late 5.2); 0x0358 (v. late 5.2); 0x0380 (6.0); 0x03B0 (6.1); 0x0398 (6.2); 0x0620 (6.3); 0x0628 (10.0 to 1511); 0x0630 (1607); 0x0638 (1703 to 1809); 0x0648 (1903); 0x0478 |
CLIENT_ID Cid; |
all |
The Cid holds the process and thread IDs that represent the thread in user mode, notably for API functions that let user-mode clients open a handle to a thread. For some measure of how these IDs were at least originally intended solely for client-level identification, consider that the kernel did not originally export functions that allow kernel-mode software to gets these IDs even for the current thread. The PsGetCurrentProcessId and PsGetCurrentThreadId functions do nothing but extract the IDs from the Cid for the current thread, but they are not exported until version 4.0 (and were not immediately documented). The same straightforward extraction but for an arbitrary thread is done by the PsGetThreadProcessId and PsGetThreadId functions, but these aren’t exported until version 5.1 (apparently still without documentation).
Offset (x86) | Offset (x64) | Definition | Versions | Remarks |
---|---|---|---|---|
0x0210 (3.10); 0x01E8 (3.50 to 5.0); 0x01F4 (5.1); 0x01FC (early 5.2); 0x01EC (late 5.2); 0x0214 (6.0); 0x0234 (6.1); 0x021C (6.2); 0x036C (6.3); 0x037C (10.0 to 1607); 0x0384 (1703 to 1809); 0x038C (1903); 0x0284 |
KSEMAPHORE LpcReplySemaphore; |
3.10 to 5.0 | ||
0x0380 (late 5.2); 0x0368 (v. late 5.2); 0x0390 (6.0); 0x03C0 (6.1); 0x03A8 (6.2); 0x0630 (6.3); 0x0638 (10.0 to 1511); 0x0640 (1607); 0x0648 (1703 to 1809); 0x0658 (1903); 0x0488 |
union { KSEMAPHORE LpcReplySemaphore; KSEMAPHORE KeyedWaitSemaphore; }; |
5.1 to 5.2 | ||
union { KSEMAPHORE KeyedWaitSemaphore; KSEMAPHORE AlpcWaitSemaphore; }; |
6.0 and higher | |||
0x0224 (3.10); 0x01FC (3.51 to 5.0); 0x0208 (5.1); 0x0210 (early 5.2); 0x0200 (late 5.2) |
0x03A0 (late 5.2); 0x0388 (v. late 5.2) |
union { PVOID LpcReplyMessage; PVOID LpcWaitingOnPort; }; |
3.10 to 5.2 | |
0x0200 (3.51 to 5.0) |
ULONG LpcReplyMessageId; |
3.51 to 5.0 | next at 0x023C | |
0x0204 (3.51 to 5.0) |
ULONG PerformanceCountLow; |
3.51 to 5.0 | ||
0x0228 (3.10) | unknown KMUTEX | 3.10 only | ||
0x0248 (3.10) | unknown TOKEN pointer | 3.10 only | ||
0x024C (3.10) |
TOKEN *Token; |
3.10 only | ||
0x0250 (3.10) |
BOOLEAN CopyOnOpen; |
3.10 only | ||
0x0251 (3.10) |
BOOLEAN EffectiveOnly; |
3.10 only | ||
0x0252 (3.10) |
BOOLEAN LpcExitThreadCalled; |
3.10 only | next at 0x0238 | |
0x0254 (3.10) |
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; |
3.10 only | ||
0x0208 (3.50 to 5.0); 0x020C (5.1); 0x0214 (early 5.2); 0x0204 (late 5.2); 0x0228 (6.0); 0x0248 (6.1); 0x0230 (6.2); 0x0380 (6.3); 0x0390 (10.0 to 1607); 0x0398 (1703 to 1809); 0x03A0 (1903); 0x02C8 |
0x03A8 (late 5.2); 0x0390 (v. late 5.2); 0x03B0 (6.0); 0x03E0 (6.1); 0x03C8 (6.2); 0x0650 (6.3); 0x0658 (10.0 to 1511); 0x0660 (1607); 0x0668 (1703 to 1809); 0x0678 (1903); 0x04A8 |
PS_IMPERSONATION_INFORMATION *ImpersonationInfo; |
3.50 to 5.2 | |
PS_CLIENT_SECURITY_CONTEXT ClientSecurity; |
6.0 and higher |
The names for the version 3.10 members Token, CopyOnOpen, EffectiveOnly and ImpersonationLevel are here duplicated from the structure that symbol files later name as a PS_IMPERSONATION_INFORMATION. In effect, version 3.10 has the whole of this structure where later versions have only a pointer to it. See, however, that version 3.10 doesn’t actually have the structure as a member, named or not, due to intrusion of the apparently unrelated LpcExitThreadCalled (which soon moves to nearly the end of the KTHREAD).
Offset (x86) | Offset (x64) | Definition | Versions | Remarks |
---|---|---|---|---|
0x0258 (3.10); 0x020C (3.50 to 5.0); 0x0210 (5.1); 0x0218 (early 5.2); 0x0208 (late 5.2); 0x022C (6.0); 0x024C (6.1); 0x0234 (6.2); 0x0384 (6.3); 0x0394 (10.0 to 1607); 0x039C (1703 to 1809); 0x03A4 (1903); 0x02CC |
0x03B0 (late 5.2); 0x0398 (v. late 5.2); 0x03B8 (6.0); 0x03E8 (6.1); 0x03D0 (6.2); 0x0658 (6.3); 0x0660 (10.0 to 1511); 0x0668 (1607); 0x0670 (1703 to 1809); 0x0680 (1903); 0x04B0 |
LIST_ENTRY IrpList; |
all | |
0x0260 (3.10); 0x0214 (3.50 to 5.0); 0x0218 (5.1); 0x0220 (early 5.2); 0x0210 (late 5.2); 0x0234 (6.0); 0x0254 (6.1); 0x023C (6.2); 0x038C (6.3); 0x039C (10.0 to 1607); 0x03A4 (1703 to 1809); 0x03AC (1903); 0x02D4 |
0x03C0 (late 5.2); 0x03A8 (v. late 5.2); 0x03C8 (6.0); 0x03F8 (6.1); 0x03E0 (6.2); 0x0668 (6.3); 0x0670 (10.0 to 1511); 0x0678 (1607); 0x0680 (1703 to 1809); 0x0690 (1903); 0x04C0 |
ULONG_PTR TopLevelIrp; |
all | |
0x0264 (3.10); 0x0218 (3.50 to 5.0); 0x021C (5.1); 0x0224 (early 5.2); 0x0214 (late 5.2); 0x0238 (6.0); 0x0258 (6.1); 0x0240 (6.2); 0x0390 (6.3); 0x03A0 (10.0 to 1607); 0x03A8 (1703 to 1809); 0x03B0 (1903); 0x02D8 |
0x03C8 (late 5.2); 0x03B0 (v. late 5.2); 0x03D0 (6.0); 0x0400 (6.1); 0x03E8 (6.2); 0x0670 (6.3); 0x0678 (10.0 to 1511); 0x0680 (1607); 0x0688 (1703 to 1809); 0x0698 (1903); 0x04C8 |
DEVICE_OBJECT *DeviceToVerify; |
all | |
0x0268 (3.10) | unknown dword | 3.10 only | ||
0x026C (3.10) | unknown array of two unknown 0x1C-byte structures | 3.10 only | ||
0x02A4 (3.10); 0x021C (3.50 to 5.0) |
ULONG ReadClusterSize; |
3.10 to 5.0 | next at 0x0240 | |
0x02A8 (3.10); 0x0220 (3.50 to 5.0) |
BOOLEAN ForwardClusterOnly; |
3.10 to 5.0 | next at 0x0254 | |
0x02A9 (3.10); 0x0221 (3.50 to 5.0) |
BOOLEAN DisablePageFaultClustering; |
3.10 to 5.0 | next at 0x0255 | |
0x02AA (3.10); 0x0222 (3.50 to 5.0) |
BOOLEAN DeadThread; |
3.10 to 5.0 | next as bit in CrossThreadFlags | |
0x0223 (5.0) |
BOOLEAN HideFromDebugger; |
5.0 only | next as bit in CrossThreadFlags | |
0x02AB (3.10); 0x0223 (3.50 to 4.0); 0x0224 (5.0) |
BOOLEAN HasTerminated; |
3.10 to 4.0 | ||
ULONG HasTerminated; |
5.0 only | next as bit in CrossThreadFlags | ||
0x02AC (3.10); 0x0224 (3.50 to 4.0) |
EEVENT_PAIR *EventPair; |
3.10 to 4.0 | ||
0x02B0 (3.10) | unknown LARGE_INTEGER | 3.10 only |
The EventPair is the address of an event-pair object for a user-mode client and server to synchronise their work through the NTDLL functions NtSetLowWaitHighThread and NtSetHighWaitLowThread. That Microsoft used the name EventPair for this member is known from the USERKDX.DLL debugger extension for Windows NT 4.0. Type information in CRASHLIB.LIB from an SDK for Windows NT 4.0 not only names the member but its type.
Offset (x86) | Offset (x64) | Definition | Versions | Remarks |
---|---|---|---|---|
0x02B8 (3.10); 0x0228 (3.50 to 5.0) |
ACCESS_MASK GrantedAccess; |
3.10 to 5.0 | next at 0x0244 | |
0x02BC (3.10); 0x022C (3.50 to 5.0); 0x0220 (5.1); 0x0228 (early 5.2); 0x0218 (late 5.2) |
0x03D0 (late 5.2); 0x03B8 (v. late 5.2) |
KPROCESS *ThreadsProcess; |
3.10 to 5.2 | |
0x02C0 (3.10); 0x0230 (3.50 to 5.0); 0x0224 (5.1); 0x022C (early 5.2); 0x021C (late 5.2) |
0x03D8 (late 5.2); 0x03C0 (v. late 5.2) |
PVOID StartAddress; |
3.10 to 5.2 | next at 0x01F8 and 0x0358 |
0x02C4 (3.10) |
LIST_ENTRY PostBlockList; |
3.10 only | next at 0x01C4 | |
0x023C (6.0); 0x025C (6.1) |
0x03D8 (6.0); 0x0408 (6.1) |
PSP_RATE_APC *RateControlApc; |
6.0 only | |
PSP_CPU_QUOTA_APC *CpuQuotaApc; |
6.1 only | |||
0x02CC (3.10); 0x0234 (3.50 to 5.0); 0x0228 (5.1); 0x0230 (early 5.2); 0x0220 (late 5.2); 0x0240 (6.0); 0x0260 (6.1); 0x0244 (6.2); 0x0394 (6.3); 0x03A4 (10.0 to 1607); 0x03AC (1703 to 1809); 0x03B4 (1903); 0x02DC |
0x03E0 (late 5.2); 0x03C8 (v. late 5.2); 0x03E0 (6.0); 0x0410 (6.1); 0x03F0 (6.2); 0x0678 (6.3); 0x0680 (10.0 to 1511); 0x0688 (1607); 0x0690 (1703 to 1809); 0x06A0 (1903); 0x04D0 |
union { PVOID Win32StartAddress; ULONG LpcReceivedMessageId; }; |
3.10 to 5.2 | |
PVOID Win32StartAddress; |
6.0 and higher | |||
0x02D0 (3.10) | unknown pointer | 3.10 only | ||
0x02D4 (3.10) | unaccounted 0x14 bytes | 3.10 only | last member in 3.10 | |
0x0238 (3.50 to 5.0) |
BOOLEAN LpcExitThreadCalled; |
3.50 to 5.0 | previously at 0x0252; next as bit in SameThreadApcFlags |
|
0x0239 (3.50 to 5.0) |
BOOLEAN HardErrorsAreDisabled; |
3.50 to 5.0 | next as bit in CrossThreadFlags | |
0x023A (3.50 to 5.0) |
BOOLEAN LpcReceivedMsgIdValid; |
3.50 to 5.0 | next as bit in SameThreadApcFlags | |
0x023B (4.0 to 5.0) |
BOOLEAN ActiveImpersonationInfo; |
4.0 to 5.0 | next as bit in CrossThreadFlags | |
0x023C (3.50 to 5.0) |
LONG PerformanceCountHigh; |
3.50 to 5.0 | last member in 3.50; last member in 3.51; last member in 4.0 |
|
0x0698 (1709 to 1809); 0x06A8 (1903); 0x04D8 |
PVOID ChargeOnlySession; |
1709 and higher | previously at 0x0600 | |
0x0244 (6.0); 0x0264 (6.1); 0x0248 (6.2); 0x0398 (6.3); 0x03A8 (10.0 to 1607); 0x03B0 (1703 to 1809); 0x03B8 (1903); 0x02E0 |
0x03E8 (6.0); 0x0418 (6.1); 0x03F8 (6.2); 0x0680 (6.3); 0x0688 (10.0 to 1511); 0x0690 (1607); 0x0698 (1703); 0x06A0 (1709 to 1809); 0x06B0 (1903); 0x04E0 |
PVOID SparePtr0; |
6.0 only | |
PVOID LegacyPowerObject; |
6.1 and higher | |||
0x0240 (5.0); 0x022C (5.1); 0x0234 (early 5.2); 0x0224 (late 5.2); 0x0248 (6.0); 0x0268 (6.1); 0x024C (6.2); 0x039C (6.3); 0x03AC (10.0 to 1607); 0x03B4 (1703 to 1809); 0x03BC (1903); 0x02E4 |
0x03E8 (late 5.2); 0x03D0 (v. late 5.2); 0x03F0 (6.0); 0x0420 (6.1); 0x0400 (6.2); 0x0688 (6.3); 0x0690 (10.0 to 1511); 0x0698 (1607); 0x06A0 (1703); 0x06A8 (1709 to 1809); 0x06B8 (1903); 0x04E8 |
LIST_ENTRY ThreadListEntry; |
5.0 and higher | last member in 5.0 |
Offset (x86) | Offset (x64) | Definition | Versions | Remarks |
---|---|---|---|---|
0x0234 (5.1); 0x023C (early 5.2); 0x022C (late 5.2); 0x0250 (6.0); 0x0270 (6.1); 0x0254 (6.2); 0x03A4 (6.3); 0x03B4 (10.0 to 1607); 0x03BC (1703 to 1809); 0x03C4 (1903); 0x02EC |
0x03F8 (late 5.2); 0x03E0 (v. late 5.2); 0x0400 (6.0); 0x0430 (6.1); 0x0410 (6.2); 0x0698 (6.3); 0x06A0 (10.0 to 1511); 0x06A8 (1607); 0x06B0 (1703); 0x06B8 (1709 to 1809); 0x06C8 (1903); 0x04F8 |
EX_RUNDOWN_REF RundownProtect; |
5.1 and higher | |
0x0238 (5.1); 0x0240 (early 5.2); 0x0230 (late 5.2); 0x0254 (6.0); 0x0274 (6.1); 0x0258 (6.2); 0x03A8 (6.3); 0x03B8 (10.0 to 1607); 0x03C0 (1703 to 1809); 0x03C8 (1903); 0x02F0 |
0x0400 (late 5.2); 0x03E8 (v. late 5.2); 0x0408 (6.0); 0x0438 (6.1); 0x0418 (6.2); 0x06A0 (6.3); 0x06A8 (10.0 to 1511); 0x06B0 (1607); 0x06B8 (1703); 0x06C0 (1709 to 1809); 0x06D0 (1903); 0x0500 |
EX_PUSH_LOCK ThreadLock; |
5.1 and higher | |
0x023C (5.1); 0x0244 (early 5.2); 0x0234 (late 5.2) |
0x0408 (late 5.2); 0x03F0 (v. late 5.2) |
ULONG LpcReplyMessageId; |
5.1 to 5.2 | previously at 0x0200 |
0x0240 (5.1); 0x0248 (early 5.2); 0x0238 (late 5.2); 0x0258 (6.0); 0x0278 (6.1); 0x025C (6.2); 0x03AC (6.3); 0x03BC (10.0 to 1607); 0x03C4 (1703 to 1809); 0x03CC (1903); 0x02F4 |
0x040C (late 5.2); 0x03F4 (v. late 5.2); 0x0410 (6.0); 0x0440 (6.1); 0x0420 (6.2); 0x06A8 (6.3); 0x06B0 (10.0 to 1511); 0x06B8 (1607); 0x06C0 (1703); 0x06C8 (1709 to 1809); 0x06D8 (1903); 0x0508 |
ULONG ReadClusterSize; |
5.1 and higher | previously at 0x021C |
0x0244 (5.1); 0x024C (early 5.2); 0x023C (late 5.2) |
0x0410 (late 5.2); 0x03F8 (v. late 5.2) |
ACCESS_MASK GrantedAccess; |
5.1 to 5.2 | previously at 0x0228 |
0x025C (6.0); 0x027C (6.1); 0x0260 (6.2); 0x03B0 (6.3); 0x03C0 (10.0 to 1607); 0x03C8 (1703 to 1809); 0x03D0 (1903); 0x02F8 |
0x0414 (6.0); 0x0444 (6.1); 0x0424 (6.2); 0x06AC (6.3); 0x06B4 (10.0 to 1511); 0x06BC (1607); 0x06C4 (1703); 0x06CC (1709 to 1809); 0x06DC (1903); 0x050C |
LONG volatile MmLockOrdering; |
6.0 and higher | |
0x0264 (6.2); 0x03B4 (6.3); 0x03C4 (10.0 to 1511) |
0x0428 (6.2); 0x06B0 (6.3); 0x06B8 (10.0 to 1511) |
LONG volatile CmLockOrdering; |
6.2 to 1511 |
Windows XP gathered seven booleans into bit fields in three sets, whose assignment of bits to functionality inevitably changes through successive versions:
Offset (x86) | Offset (x64) | Definition | Versions |
---|---|---|---|
0x0248 (5.1); 0x0250 (early 5.2); 0x0240 (late 5.2); 0x0260 (6.0); 0x0280 (6.1); 0x0268 (6.2); 0x03B8 (6.3); 0x03C8 (10.0 to 1511); 0x03C4 (1607); 0x03CC (1703 to 1809); 0x03D4 (1903); 0x02FC |
0x0414 (late 5.2); 0x03FC (v. late 5.2); 0x0418 (6.0); 0x0448 (6.1); 0x042C (6.2); 0x06B4 (6.3); 0x06BC (10.0 to 1511); 0x06C0 (1607); 0x06C8 (1703); 0x06D0 (1709 to 1809); 0x06E0 (1903); 0x0510 |
union { ULONG CrossThreadFlags; struct { /* bit fields, follow link */ }; }; |
5.1 and higher |
0x024C (5.1); 0x0254 (early 5.2); 0x0244 (late 5.2); 0x0264 (6.0); 0x0284 (6.1); 0x026C (6.2); 0x03BC (6.3); 0x03CC (10.0 to 1511); 0x03C8 (1607); 0x03D0 (1703 to 1809); 0x03D8 (1903); 0x300 |
0x0418 (late 5.2); 0x0400 (v. late 5.2); 0x041C (6.0); 0x044C (6.1); 0x0430 (6.2); 0x06B8 (6.3); 0x06C0 (10.0 to 1511); 0x06C4 (1607); 0x06CC (1703); 0x06D4 (1709 to 1809); 0x6E4 (1903); 0x514 |
union { ULONG SameThreadPassiveFlags; struct { /* bit fields, follow link */ }; }; |
5.1 and higher |
0x0250 (5.1); 0x0258 (early 5.2); 0x0248 (late 5.2); 0x0268 (6.0); 0x0288 (6.1); 0x0270 (6.2); 0x03C0 (6.3); 0x03D0 (10.0 to 1511); 0x03CC (1607); 0x03D4 (1703 to 1809); 0x03DC (1903); 0x0304 |
0x041C (late 5.2); 0x0404 (v. late 5.2); 0x0420 (6.0); 0x0450 (6.1); 0x0434 (6.2); 0x06BC (6.3); 0x06C4 (10.0 to 1511); 0x06C8 (1607); 0x06D0 (1703); 0x06D8 (1709 to 1809); 0x06E8 (1903); 0x0518 |
union { ULONG SameThreadApcFlags; struct { /* bit fields, follow link */ }; }; |
5.1 and higher |
For who knows what reason, two booleans weren’t changed to bit fields but were merely shifted to the structure’s end.
Offset (x86) | Offset (x64) | Definition | Versions | Remarks |
---|---|---|---|---|
0x0254 (5.1); 0x025C (early 5.2); 0x024C (late 5.2) |
0x0420 (late 5.2); 0x0408 (v. late 5.2) |
BOOLEAN ForwardClusterOnly; |
5.1 to 5.2 | previously at 0x0220 |
0x026C (6.0); 0x028C (6.1); 0x0274 (6.2); 0x03C4 (6.3); 0x03D4 (10.0 to 1511); 0x03D0 (1607); 0x03D8 (1709 to 1809); 0x03E0 (1903); 0x0308 |
0x0424 (6.0); 0x0454 (6.1); 0x0438 (6.2); 0x06C0 (6.3); 0x06C8 (10.0 to 1511); 0x06CC (1607); 0x06D4 (1703); 0x06DC (1709 to 1809); 0x06EC (1903); 0x051C |
BOOLEAN CacheManagerActive; |
6.0 and higher | |
0x0255 (5.1); 0x0x25D (early 5.2); 0x024D (late 5.2); 0x026D (6.0); 0x028D (6.1); 0x0275 (6.2); 0x03C5 (6.3); 0x03D5 (10.0 to 1511); 0x03D1 (1607); 0x03D9 (1709 to 1809); 0x03E1 (1903); 0x0309 |
0x0421 (late 5.2); 0x0409 (v. late 5.2); 0x0425 (6.0); 0x0455 (6.1); 0x0439 (6.2); 0x06C1 (6.3); 0x06C9 (10.0 to 1511); 0x06CD (1607); 0x06D5 (1703); 0x06DD (1709 to 1803); 0x06ED (1903); 0x051D |
BOOLEAN DisablePageFaultClustering; |
5.1 and higher | previously at 0x0221; last member in 5.1; last member in early 5.2 |
For all that the build of version 5.2 for Windows Server 2003 SP1 rearranged the KTHREAD, it added just one byte beyond in the ETHREAD, and it anyway fits into alignment space. Indeed, through versions 5.1 and 5.2, the ETHREAD is in some sense very stable: that members shift and that the structure changes size is only because of the KTHREAD.
Even after this addition for Windows Server 2003 SP1, one byte of unnamed alignment space remained until Windows 7 found a use for it:
Offset (x86) | Offset (x64) | Definition | Versions | Remarks |
---|---|---|---|---|
0x024E (late 5.2); 0x026E (6.0); 0x028E (6.1); 0x0276 (6.2); 0x03C6 (6.3); 0x03D6 (10.0 to 1511); 0x03D2 (1607); 0x03DA (1709 to 1809); 0x03E2 (1903); 0x030A |
0x0422 (late 5.2); 0x040A (v. late 5.2); 0x0426 (6.0); 0x0456 (6.1); 0x043A (6.2); 0x06C2 (6.3); 0x06CA (10.0 to 1511); 0x06CE (1607); 0x06D6 (1703); 0x06DE (1709 to 1803); 0x051E |
UCHAR ActiveFaultCount; |
late 5.2 and higher | last member in late 5.2; last member in v. late 5.2 |
0x028F (6.1); 0x0277 (6.2); 0x03C7 (6.3); 0x03D7 (10.0 to 1511); 0x03D3 (1607); 0x03DB (1709 to 1809); 0x03E3 (1903); 0x030B |
0x0457 (6.1); 0x043B (6.2); 0x06C3 (6.3); 0x06CB (10.0 to 1511); 0x06CF (1607); 0x06D7 (1703); 0x06DF (1709 to 1809); 0x06EF (1903); 0x051F |
UCHAR LockOrderState; |
6.1 and higher |
Offset (x86) | Offset (x64) | Definition | Versions | Remarks |
---|---|---|---|---|
0x030C | 0x0520 |
ULONG PerformanceCountLowReserved; |
2004 and higher | |
0x0310 | 0x0524 |
LONG PerformanceCountHighReserved; |
2004 and higher | |
0x0270 (6.0); 0x0290 (6.1); 0x0278 (6.2); 0x03C8 (6.3); 0x03D8 (10.0 to 1511); 0x03D4 (1607); 0x03DC (1703 to 1809); 0x03E4 (1903); 0x0314 |
0x0428 (6.0); 0x0458 (6.1); 0x0440 (6.2); 0x06C8 (6.3); 0x06D0 (10.0 to 1607); 0x06D8 (1703); 0x06E0 (1709 to 1809); 0x06F0 (1903); 0x0528 |
ULONG_PTR AlpcMessageId; |
6.0 and higher | |
0x0274 (6.0); 0x0294 (6.1); 0x027C (6.2); 0x03CC (6.3); 0x03DC (10.0 to 1511); 0x03D8 (1607); 0x03E0 (1703 to 1809); 0x03E8 (1903); 0x0318 |
0x0430 (6.0); 0x0460 (6.1); 0x0448 (6.2); 0x06D0 (6.3); 0x06D8 (10.0 to 1607); 0x06E0 (1703); 0x06E8 (1709 to 1809); 0x06F8 (1903); 0x0530 |
union { PVOID AlpcMessage; ULONG AlpcReceiveAttributeSet; }; |
6.0 and higher | |
0x0280 (6.2); 0x03D0 (6.3); 0x03E0 (10.0 to 1511) |
0x0450 (6.2); 0x06D8 (6.3); 0x06E0 (10.0 to 1511) |
LONG ExitStatus; |
6.2 to 1511 | previously at 0x0210 and 0x0378; next at 0x03E4 and 0x06F0 |
0x0278 (6.0); 0x0298 (6.1); 0x0284 (6.2); 0x03D4 (6.3); 0x03E4 (10.0 to 1511); 0x03DC (1607); 0x03E4 (1703 to 1809); 0x03EC (1903); 0x031C |
0x0438 (6.0); 0x0468 (6.1); 0x0458 (6.2); 0x06E0 (6.3); 0x06E8 (10.0 to 1511); 0x06E0 (1607); 0x06E8 (1703); 0x06F0 (1709 to 1809); 0x0700 (1903); 0x0538 |
LIST_ENTRY AlpcWaitListEntry; |
6.0 and higher | |
0x03E4 (1607); 0x03EC (1703 to 1809); 0x03F4 (1903); 0x0324 |
0x06F0 (1607); 0x06F8 (1703); 0x0700 (1709 to 1809); 0x0710 (1903); 0x0548 |
NTSTATUS ExitStatus; |
1607 and higher | previously at 0x03E4 and 0x06E0 |
0x0280 (6.0); 0x02A0 (6.1); 0x028C (6.2); 0x03DC (6.3); 0x03EC (10.0 to 1511); 0x03E8 (1607); 0x03F0 (1703 to 1809); 0x03F8 (1903); 0x0328 |
0x0448 (6.0); 0x0478 (6.1); 0x0468 (6.2); 0x06F0 (6.3); 0x06F8 (10.0 to 1511); 0x06F4 (1607); 0x06FC (1703); 0x0704 (1709 to 1809); 0x0714 (1903); 0x054C |
ULONG CacheManagerCount; |
6.0 and higher | last member in 6.0 |
Offset (x86) | Offset (x64) | Definition | Versions | Remarks |
---|---|---|---|---|
0x02A4 (6.1); 0x0290 (6.2); 0x03E0 (6.3); 0x03F0 (10.0 to 1511); 0x03EC (1607); 0x03F4 (1703 to 1809); 0x03FC (1903); 0x032C |
0x047C (6.1); 0x046C (6.2); 0x06F4 (6.3); 0x06FC (10.0 to 1511); 0x06F8 (1607); 0x0700 (1703); 0x0708 (1709 to 1809); 0x0718 (1903); 0x0550 |
ULONG IoBoostCount; |
6.1 and higher | |
0x03F0 (1607); 0x03F8 (1703 to 1809); 0x0400 (1903); 0x0330 |
0x06FC (1607); 0x0704 (1703); 0x07C0 (1709 to 1803); 0x071C (1903); 0x0554 |
ULONG IoQoSBoostCount; |
1607 and higher | |
0x03F4 (1607); 0x03FC (1703 to 1809); 0x0404 (1903); 0x0334 |
0x0700 (1607); 0x0708 (1703); 0x0710 (1709 to 1809); 0x0720 (1903); 0x0558 |
ULONG IoQoSThrottleCount; |
1607 and higher | |
0x0400 (1809); 0x0408 (1903); 0x0338 |
0x0714 (1809); 0x0724 (1903); 0x055C |
ULONG KernelStackReference; |
previously at 0x042C and 0x0770 | |
0x0294 (6.2); 0x03E4 (6.3); 0x03F4 (10.0 to 1511); 0x03F8 (1607); 0x0400 (1703 to 1803); 0x0404 (1809); 0x040C (1903); 0x033C |
0x0470 (6.2); 0x06F8 (6.3); 0x0700 (10.0 to 1511); 0x0708 (1607); 0x0710 (1703); 0x0718 (1709 to 1809); 0x0728 (1903); 0x0560 |
LIST_ENTRY BoostList; |
6.2 and higher | |
0x029C (6.2); 0x03EC (6.3); 0x03FC (10.0 to 1511); 0x0400 (1607); 0x0408 (1703 to 1803); 0x040C (1809); 0x0414 (1903); 0x0344 |
0x0480 (6.2); 0x0708 (6.3); 0x0710 (10.0 to 1511); 0x0718 (1607); 0x0720 (1703); 0x0728 (1709 to 1809); 0x0738 (1903); 0x0570 |
LIST_ENTRY DeboostList; |
6.2 and higher | |
0x02A4 (6.2); 0x03F4 (6.3); 0x0404 (10.0 to 1511); 0x0408 (1607); 0x0410 (1703 to 1803); 0x0414 (1809); 0x041C (1903); 0x034C |
0x0490 (6.2); 0x0718 (6.3); 0x0720 (10.0 to 1511); 0x0728 (1607); 0x0730 (1703); 0x0738 (1709 to 1809); 0x0748 (1903); 0x0580 |
KSPIN_LOCK BoostListLock; |
6.2 and higher | |
0x02A8 (6.1 to 6.2); 0x03F8 (6.3); 0x0408 (10.0 to 1511); 0x040C (1607); 0x0414 (1703 to 1803); 0x0418 (1809); 0x0420 (1903); 0x0350 |
0x0480 (6.1); 0x0498 (6.2); 0x0720 (6.3); 0x0728 (10.0 to 1511); 0x0730 (1607); 0x0738 (1703); 0x0740 (1709 to 1809); 0x0750 (1903); 0x0588 |
KSPIN_LOCK IrpListLock; |
6.1 and higher | |
0x02AC (6.1 to 6.2); 0x03FC (6.3); 0x040C (10.0 to 1511); 0x0410 (1607); 0x0418 (1703 to 1803); 0x041C (1809); 0x0424 (1903); 0x0354 |
0x0488 (6.1); 0x04A0 (6.2); 0x0728 (6.3); 0x0730 (10.0 to 1511); 0x0738 (1607); 0x0740 (1703); 0x0748 (1709 to 1809); 0x0758 (1903); 0x0590 |
PVOID ReservedForSynchTracking; |
6.1 and higher | |
0x02B0 (6.1 to 6.2); 0x0400 (6.3); 0x0410 (10.0 to 1511); 0x0414 (1607); 0x041C (1703 to 1803); 0x0420 (1809); 0x0428 (1903); 0x0358 |
0x0490 (6.1); 0x04A8 (6.2); 0x0730 (6.3); 0x0738 (10.0 to 1511); 0x0740 (1607); 0x0748 (1703); 0x0750 (1709 to 1809); 0x0760 (1903); 0x0598 |
SINGLE_LIST_ENTRY CmCallbackListHead; |
6.1 and higher | last member in 6.1 |
Offset (x86) | Offset (x64) | Definition | Versions | Remarks |
---|---|---|---|---|
0x02B4 (6.2); 0x0404 (6.3); 0x0414 (10.0 to 1511); 0x0418 (1607); 0x0420 (1703 to 1803); 0x0424 (1809); 0x042C (1903); 0x035C |
0x04B0 (6.2); 0x0738 (6.3); 0x0740 (10.0 to 1511); 0x0748 (1607); 0x0750 (1703); 0x0758 (1709 to 1809); 0x0768 (1903); 0x05A0 |
GUID const *ActivityId; |
6.2 and higher | |
0x02B8 (6.2) | 0x04B8 (6.2) |
PVOID WnfContext; |
6.2 only | |
0x0408 (6.3); 0x0418 (10.0 to 1511); 0x041C (1607); 0x0424 (1703 to 1803); 0x0428 (1809); 0x0430 (1903); 0x0360 |
0x0740 (6.3); 0x0748 (10.0 to 1511); 0x0750 (1607); 0x0758 (1703); 0x0760 (1709 to 1809); 0x0770 (1903); 0x05A8 |
SINGLE_LIST_ENTRY SeLearningModeListHead; |
6.3 and higher | |
0x040C (6.3); 0x041C (10.0 to 1511); 0x0420 (1607); 0x0428 (1703 to 1803); 0x042C (1809); 0x0434 (1903); 0x0364 |
0x0748 (6.3); 0x0750 (10.0 to 1511); 0x0758 (1607); 0x0760 (1703); 0x0768 (1709 to 1809); 0x0778 (1903); 0x05B0 |
PVOID VerifierContext; |
6.3 and higher | |
0x02BC (6.2); 0x0410 (6.3); 0x0420 (10.0 to 1511); 0x0424 (1607); 0x042C (1703 to 1803) |
0x04C0 (6.2); 0x0750 (6.3); 0x0758 (10.0 to 1511); 0x0760 (1607); 0x0768 (1703); 0x0770 (1709 to 1803) |
ULONG KernelStackReference; |
6.2 to 1803 | next at 0x0400 and 0x0714; last member in 6.2 |
See that for 64-bit Windows 8, the 32-bit KernelStackReference left the structure to end with four bytes of alignment padding. That Windows 8.1 followed with a pointer (see next) turned this padding into wasted space which the 1809 edition of Windows 10 reclaimed by moving the member to fill the alignment space that 64-bit Windows 8 also wasted immediately before the BoostList (above).
Offset (x86) | Offset (x64) | Definition | Versions | Remarks |
---|---|---|---|---|
0x0414 (6.3); 0x0424 (10.0 to 1511); 0x0428 (1607); 0x0430 (1703 to 1809); 0x0438 (1903); 0x0368 |
0x0758 (6.3); 0x0760 (10.0 to 1511); 0x0768 (1607); 0x0770 (1703); 0x0778 (1709 to 1803); 0x0770 (1809); 0x0780 (1903); 0x05B8 |
PVOID AdjustedClientToken; |
6.3 and higher | last member in 6.3 (x86) |
0x0760 (6.3) |
ULONG UserFsBase; |
6.3 only | next at 0x043C and 0x0790 | |
0x0768 (6.3) |
ULONGLONG UserGsBase; |
6.3 only | next at 0x0440 and 0x0798 | |
0x0770 (6.3) |
PVOID PicoContext; |
6.3 only | next at 0x0438 and 0x0788 last member in 6.3 (x64) |
Offset (x86) | Offset (x64) | Definition | Versions | Remarks |
---|---|---|---|---|
0x0428 (10.0 to 1511); 0x042C (1607); 0x0434 (1703 to 1809); 0x043C (1903); 0x036C |
0x0768 (10.0 to 1511); 0x0770 (1607); 0x0778 (1703); 0x0780 (1709 to 1803); 0x0778 (1809); 0x0788 (1903); 0x05C0 |
PVOID WorkingOnBehalfClient; |
10.0 to 1511 | |
PVOID WorkOnBehalfThread; |
1607 and higher | |||
0x042C (10.0 to 1511); 0x0430 (1607); 0x0438 (1703 to 1809); 0x0440 (1903); 0x0370 |
0x0770 (10.0 to 1511); 0x0778 (1607); 0x0780 (1703); 0x0788 (1709 to 1803); 0x0780 (1809); 0x0790 (1903); 0x05C8 |
PS_PROPERTY_SET PropertySet; |
10.0 and higher | |
0x0438 (10.0 to 1511); 0x043C (1607); 0x0444 (1703 to 1809); 0x044C (1903); 0x037C |
0x0788 (10.0 to 1511); 0x0790 (1607); 0x0798 (1703); 0x07A0 (1709 to 1803); 0x0798 (1809); 0x07A8 (1903); 0x05E0 |
PVOID PicoContext; |
10.0 and higher | previously x64-only at 0x0770 |
0x043C (10.0 to 1511); 0x0440 (1607); 0x0448 (1703 to 1809); 0x0450 (1903); 0x0380 |
0x0790 (10.0 to 1511); 0x0798 (1607); 0x07A0 (1703); 0x07A8 (1709 to 1803); 0x07A0 (1809); 0x07B0 (1903); 0x05E8 |
ULONG UserFsBase; |
10.0 to 1511 | previously x64-only at 0x0760 |
ULONG_PTR UserFsBase; |
1607 and higher | |||
0x0440 (10.0 to 1511); 0x0444 (1607); 0x044C (1703 to 1809); 0x0454 (1903); 0x0384 |
0x0798 (10.0 to 1511); 0x07A0 (1607); 0x07A8 (1703); 0x07B0 (1709 to 1803); 0x07A8 (1809); 0x07B8 (1903); 0x05F0 |
ULONG_PTR UserGsBase; |
10.0 and higher | previously x64-only at 0x0768 |
0x0444 (10.0 to 1511); 0x0448 (1607); 0x0450 (1703 to 1809); 0x0458 (1903); 0x0388 |
0x07A0 (10.0 to 1511); 0x07A8 (1607); 0x07B0 (1703); 0x07B8 (1709 to 1803); 0x07B0 (1809); 0x07C0 (1903); 0x05F8 |
THREAD_ENERGY_VALUES *EnergyValues; |
10.0 and higher | |
0x0448 (10.0 to 1511); 0x044C (1607); 0x0454 (1703 to 1809); 0x045C (1903) |
0x07A8 (10.0 to 1511); 0x07B0 (1607); 0x07B8 (1703); 0x07C0 (1709 to 1803); 0x07B8 (1809); 0x07C8 (1903) |
ULONG volatile CmCellReferences; |
10.0 to 1511 | |
PVOID CmDbgInfo; |
1607 to 1903 | |||
0x044C (10.0 to 1511); 0x0450 (1607); 0x0458 (1703 to 1809); 0x0460 (1903); 0x038C |
0x07B0 (10.0 to 1511); 0x07B8 (1607); 0x07C0 (1703); 0x07C8 (1709 to 1803); 0x07C0 (1809); 0x07D0 (1903); 0x0600 |
union { ULONG_PTR SelectedCpuSets; ULONG_PTR *SelectedCpuSetsIndirect; }; |
10.0 and higher | |
0x0450 (10.0 to 1511); 0x0454 (1607); 0x045C (1703 to 1809); 0x0464 (1903); 0x0390 |
0x07B8 (10.0 to 1511); 0x07C0 (1607); 0x07C8 (1703); 0x07D0 (1709 to 1803); 0x07C8 (1809); 0x07D8 (1903); 0x0608 |
ESILO *Silo; |
10.0 only | last member in 10.0 |
EJOB *Silo; |
1511 and higher | last member in 1511 |
Whether silos are their own type of object, as in the original Windows 10, or are special types of job object, the Silo member can have the special value -3 to mean that the thread is not itself attached to a silo but the thread’s process may be.
Offset (x86) | Offset (x64) | Definition | Versions | Remarks |
---|---|---|---|---|
0x0458 (1607); 0x0460 (1703 to 1809); 0x0468 (1903); 0x0394 |
0x07C8 (1607); 0x07D0 (1703); 0x07D8 (1709 to 1803); 0x07D0 (1809); 0x07E0 (1903); 0x0610 |
UNICODE_STRING *ThreadName; |
1607 and higher | |
0x07D0 (1607); 0x07D8 (1703); 0x07E0 (1709 to 1803); 0x07D8 (1809); 0x07E8 (1903); 0x0618 |
CONTEXT *SetContextState; |
1607 and higher | ||
0x045C (1607) | 0x07D8 (1607) |
ULONG ReadyTime; |
1607 only | last member in 1607 |
0x0398 |
PVOID SparePointer; |
2004 and higher | ||
0x0464 (1703 to 1809); 0x046C (1903); 0x039C |
0x07E0 (1703); 0x07E8 (1709 to 1803); 0x07E0 (1809); 0x07F0 (1903); 0x0620 |
ULONG LastExpectedRunTime; |
1703 and higher | |
0x0468 (1809); 0x0470 (1903); 0x03A0 |
0x07E4 (1809); 0x07F4 (1903); 0x0624 |
ULONG HeapData; |
1809 and higher | |
0x0468 (1703 to 1803); 0x046C (1809); 0x0474 (1903); 0x03A4 |
0x07E8 (1703); 0x07F0 (1709 to 1803); 0x07E8 (1809); 0x07F8 (1903); 0x0628 |
LIST_ENTRY OwnerEntryListHead; |
1703 and higher | |
0x0470 (1703 to 1803); 0x0474 (1809); 0x047C (1903); 0x03AC |
0x07F8 (1703); 0x0800 (1709 to 1803); 0x07F8 (1809); 0x0808 (1903); 0x0638 |
ULONG_PTR DisownedOwnerEntryListLock; |
1703 and higher | |
0x0474 (1703 to 1803); 0x0478 (1809); 0x0480 (1903); 0x03B0 |
0x0800 (1703); 0x0808 (1709 to 1803); 0x0800 (1809); 0x0818 (1903); 0x0640 |
LIST_ENTRY DisownedOwnerEntryListHead; |
1703 and higher | last member in 1703 to 1903 |
0x03B8 | 0x0650 |
KLOCK_ENTRY *LockEntries [0x48]; |
2004 and higher | |
0x04D8 | 0x0890 |
PVOID CmDbgInfo; |
2004 and higher |