KPRCB (amd64)

The name KPRCB stands for (Kernel) Processor Control Block. The kernel keeps one KPRCB for each logical processor, embedded in the same processor’s KPCR. The KPRCB holds most of what the kernel needs ready access to while managing a processor and while managing resources that are themselves managed more simply (and quickly) per processor. Neither of these structures is formally documented. Both are highly specific to the processor architecture. This page concerns itself only with the KPRCB in 64-bit Windows for the processor architecture that’s variously named amd64 or x64.

Access

Kernel-mode code can easily find the KPRCB for whichever processor it’s executing on, by finding the current KPCR first. The latter is well-known to be accessible through the gs register. Its CurrentPrcb member points to the KPRCB without depending on it to be embedded in the KPCR. Given a C-language definition of the KPCR, getting the current processor’s KPRCB can be conveniently wrapped into one inline function:

FORCEINLINE
KPRCB *KeGetCurrentPrcb (VOID)
{
    return (KPRCB *) __readgsqword (FIELD_OFFSET (KPCR, CurrentPrcb));
}

which, less some dressing, is mostly how Microsoft’s own programmers have been doing it, apparently all along, as confirmed by the NTOSP.H that has recently been disclosed in a Windows Driver Kit (WDK) for Windows 10.

The part of the KPCR that’s ahead of the embedded KPRCB is highly stable, notably so that the offset of the CurrentPrcb member is reliable over all Windows versions, as is the offset of the KPRCB within the KPCR. Members of the KPRCB are sometimes accessed through offsets from the KPCR. For some members, this is even the most usual access. Notably, the KeGetCurrentThread function is implemented very like

KTHREAD *KeGetCurrentThread (VOID)
{
    return (KTHREAD *) __readgsqword (FIELD_OFFSET (KPCR, Prcb.CurrentThread));
}

both as exported and when inlined throughout the kernel. Indeed, this particular offset is so stable and reliable that NTOSP.H doesn’t compute it symbolically but hard-codes it (to 0x0188). More generally, access to KPRCB members as nested in the KPCR is formalised in Microsoft’s assembly-language header KSAMD64.INC through such definitions as PcCurrentThread for the preceding.

In many typical cases, including that of KeGetCurrentThread, kernel-mode code does better to access a KPRCB member via the gs register and an offset from the KPCR. This is because the address that some such routine as KeGetCurrentPrcb obtains is merely the address of the KPRCB for the processor that the current thread was being run on at the time. It remains the address of the current KPRCB only while the thread can ensure it is not switched to another processor. Often, it can’t be—at least in the circumstances that have the kernel itself access the KPRCB. But often is not always, even for the kernel’s own use. How much trouble has been caused by unsynchronised access to a KPRCB for some processor that the thread is no longer running on, whether in the kernel and from outside, is not known.

Other Processors

Finding the KPRCB for an arbitrary processor is easy too in 64-bit Windows. Its kernel exports a function, named KeQueryPrcbAddress, that returns the address of the KPRCB for the processor that is represented by a given processor index.

Variability

The KPRCB is highly variable. The layout changes not just from one version to another but even between builds of version 6.0. Where this article refers to early and late builds of version 6.0, early means before Windows Vista SP1, and late means Windows Vista SP1 or higher.

Names, types and offsets are from Microsoft’s symbol files for the kernel. Some symbol files, e.g., those for the HAL in Windows 7 and higher, define a smaller KPRCB that is just an “architecturally defined section” at the structure’s start. This term is long established from comments in C-language definitions of a partial KPRCB for other processor architectures all the way back to the NTDDK.H from the Device Driver Kit (DDK) for Windows NT 3.51. Microsoft’s first known disclosure of a C-language definition of the KPRCB for the amd64 architecture—though still only of the architecturally defined section—is in the NTOSP.H from the Enterprise WDK for the 1511 release of Windows 10.

Architecturally Defined Section

The very start of the 64-bit KPRCB is relatively stable because it has long been subject to compatibility constraints because offsets for members have been published in the NTDDK.H file. When the processor Number was widened in place for Windows Vista, the NestingLevel moved further on. When Number was widened even further for Windows 7, it too moved further on, and the space it occupied was renamed, presumably so that it is never reassigned.

Offset Definition Versions Remarks
0x00
ULONG MxCsr;
all  
0x04
UCHAR Number;
5.2 only  
USHORT Number;
6.0 only next at offset 0x24
UCHAR LegacyNumber;
6.1 and higher  
0x05
UCHAR NestingLevel;
5.2 only next at offset 0x20
UCHAR ReservedMustBeZero;
6.1 and higher  
0x06
BOOLEAN InterruptRequest;
all  
0x07
BOOLEAN IdleHalt;
all  
0x08
KTHREAD *CurrentThread;
all  
0x10
KTHREAD *NextThread;
all  
0x18
KTHREAD *IdleThread;
all  

Shifting the processor Number from offset 0x04 to widen it to 32 bits had special implications for compatibility because of the vast amounts of kernel-mode code, not only written by Microsoft, that accesses the 8-bit Number through the inline function KeGetCurrentProcessorNumber as defined for seemingly general use in the NTDDK.H from driver kits for versions before Windows 7 (and still defined if targetting those versions). This routine gets Number via the gs register, relying not only on its offset within the KPRCB but the offset of the KPRCB within the KPCR, the sum (0x0184) being hard-coded in the definition. Its replacement, KeGetCurrentProcessorIndex, is similarly hard-coded but to access the 32-bit Number at its new location. The kernel must maintain the LegacyNumber for as long as the old routine remains in use by drivers that might ever get loaded.

The other inline function that is declared in NTDDK.H for general use and which has a hard-coded offset from gs to a KPRCB member is KeGetCurrentThread. It, of course, reads CurrentThread.

There the hard constraints on moving members seem to end. The very next member even got moved out of the KPRCB. This space that was left by moving the 8-byte UserRsp to the KPCR in Windows Vista got reused little by little in each later version. The byte at offset 0x21 even got reused, unused and re-reused. All 8 bytes are in use as of Windows 10.

Offset Definition Versions Remarks
0x20 (5.2)
ULONG64 UserRsp;
5.2 only next at 0x10 in KPCR
0x20
UCHAR NestingLevel;
6.0 and higher previously at 0x05
0x21 (6.0)
UCHAR Group;
6.0 only next as USHORT at 0x0658 (6.1 to 6.2)
0x21
BOOLEAN ClockOwner;
6.2 and higher  
0x22
UCHAR PendingTick;
6.2 only  
union {
    UCHAR PendingTickFlags;
    struct {
        UCHAR PendingTick : 1;          // 0x01
        UCHAR PendingBackupTick : 1;    // 0x02
    };
};
6.3 and higher  
0x23
UCHAR IdleState;
10.0 and higher  
0x22 (6.0);
0x21 (6.1);
0x23 (6.2 to 6.3)
UCHAR PrcbPad00 [6];
6.0 only  
UCHAR PrcbPad00 [3];
6.1 only  
UCHAR PrcbPad00 [1];
6.2 to 6.3  
0x24
ULONG Number;
6.1 and higher previously USHORT at 0x04

Much of the rest of the architecturally defined section had been very nearly stable until the 1703 release moved the ProcessorState futher on, apparently for cache-alignment. Note that this was not done for the 32-bit KPRCB.

Offset Definition Versions Remarks
0x28
ULONG64 RspBase;
all  
0x30
KSPIN_LOCK PrcbLock;
all  
0x38
KAFFINITY SetMember;
5.2 to 6.0  
ULONG64 PrcbPad01;
6.1 to 6.2  
CHAR *PriorityState;
6.3 and higher  
0x40 (5.2 to 1607)
KPROCESSOR_STATE ProcessorState;
5.2 to 1607 next at 0x0100
0x05F0 (5.2 to 1607);
0x40
CHAR CpuType;
all  
0x05F1 (5.2 to 1607);
0x41
CHAR CpuID;
all  
0x05F2 (5.2 to 1607);
0x42
USHORT CpuStep;
5.2 only  
union {
    USHORT CpuStep;
    struct {
        UCHAR CpuStepping;
        UCHAR CpuModel;
    };
};
6.0 and higher  
0x05F4 (5.2 to 1607);
0x44
ULONG MHz;
all  
0x05F8 (5.2 to 1607);
0x48
ULONG64 HalReserved [8];
all  
0x0638 (5.2 to 1607);
0x88
USHORT MinorVersion;
all  
0x063A (5.2 to 1607);
0x8A
USHORT MajorVersion;
all  
0x063C (5.2 to 1607);
0x8C
UCHAR BuildType;
all  
0x063D (5.2 to 1607);
0x8D
UCHAR CpuVendor;
all  
0x063E (5.2 to 1607);
0x8E
UCHAR InitialApicId;
5.2 only next as ULONG at 0x0650
UCHAR CoresPerPhysicalProcessor;
6.0 and higher  
0x063F (5.2 to 1607);
0x8F
UCHAR LogicalProcessorsPerPhysicalProcessor;
5.2 only  
UCHAR LogicalProcessorsPerCore;
6.0 and higher  
0x90
ULONG64 PrcbPad04 [6];
1703 and higher  

The remainder of the architecturally defined section got heavily reworked for Windows 8.1. An initially 8-bit CFlushSize was followed by padding that accounts explicitly for the next member’s alignment requirement and which went away when CFlushSize was widened in-place. An initial 32 bytes of padding (as PrcbPad00) completed the architecturally defined section. As more of it was brought into use, it shifted and shrank (as PrcbPad01), until by version 6.1 it was no longer needed (assuming 8-byte alignment of whatever follows). Note the will, over many versions, to preserve the size of the architecturally defined section.

Offset Definition Versions Remarks
0x0640 (6.3 to 1607);
0xC0
KNODE *ParentNode;
6.3 and higher previously at 0x5338
0x0648 (6.3 to 1607);
0xC8
KAFFINITY GroupSetMember;
6.3 and higher previously at 0x0660
0x0650 (6.3 to 1607);
0xD0
UCHAR Group;
6.3 and higher previously USHORT at 0x0658
0x0651 (6.3 to 1607);
0xD1
UCHAR GroupIndex;
6.3 and higher previously at 0x0668
0x0652 (6.3 to 1607);
0xD2
UCHAR PrcbPad05 [2];
6.3 and higher  
0x0654 (10.0 to 1607);
0xD4
ULONG InitialApicId;
10.0 and higher previously at 0x0668
0x0658 (10.0 to 1607);
0xD8
ULONG ScbOffset;
10.0 and higher previously at 0x0531C
0x0640 (5.2 to 6.2);
0x0654 (6.3);
0x065C (10.0 to 1607);
0xDC
ULONG ApicMask;
all  
0x0644 (5.2 to 6.2);
0x0658 (6.3)
UCHAR CFlushSize;
5.2 only  
ULONG CFlushSize;
6.0 to 6.3 next at 0x0668
0x0645 (5.2)
UCHAR PrcbPad0x [3];
5.2 only  
0x0648 (5.2 to 6.2);
0x0660 (6.3 to 1607);
0xE0
PVOID AcpiReserved;
all  
0x0650 (6.0 to 6.2);
0x0668 (6.3)
ULONG InitialApicId;
6.0 to 6.3 previously UCHAR at 0x063E;
next at 0x0654
0x0654 (6.0 to 6.2)
ULONG Stride;
6.0 to 6.2  
0x0650 (5.2);
0x0658 (6.0)
ULONG64 PrcbPad00 [4];
5.2 only  
ULONG64 PrcbPad01 [3];
6.0 only  
0x0658 (6.1 to 6.2)
USHORT Group;
6.1 to 6.2 previously UCHAR at 0x21;
next as UCHAR at 0x0650
0x0660 (6.1 to 6.2)
KAFFINITY GroupSetMember;
6.1 to 6.2 next at 0x0648
0x0668 (6.1 to 6.2)
UCHAR GroupIndex;
6.1 to 6.2 next at 0x0651
0x0668 (10.0 to 1607);
0xE8
ULONG CFlushSize;
10.0 and higher previously at 0x0658
0x066C (10.0 to 1607);
0xEC
ULONG PrcbPad10;
10.0 to 1703  
union {
    LONG volatile BamFlags;
    struct {
        ULONG BamQosLevel : 2;
        ULONG PendingQosUpdate : 2;
        ULONG BamFlagsReserved : 28;
    };
};
1709 only  
KPRCBFLAG PrcbFlags;
1803 and higher not in HAL symbols

For Windows 8.1 to bring ParentNode from (much) further into the structure without pushing anything beyond offset 0x0670, the inefficient packing of Group and GroupIndex had to be reorganised. Bringing in ScbOffset from further into the structure for Windows 10 then seems to have prompted a reordering of ApicMask, CFlushSize, AcpiReserved and InitialApicId.

This reordering does seem to have troubled someone at Microsoft. The NTOSP.H from the Enterprise WDK for the 1511 release of Windows 10 has a C_ASSERT to enforce at compile-time that AcpiReserved is at offset 0x0660, specifically, and then the comment “Do not move field”. Was the offset changed for Windows 8.1 despite the comment or was the comment added after? Now that the offset has changed yet again, have the assertion and comment changed too?

Windows 10 also defined explicit padding to keep to 0x0670 bytes for the architecturally defined section. This did not get used until the 1709 release, which defines bit fields in union with the BamFlags. That the 1803 release formalises them as their own type, now as PrcbFlags, looks to have been motivated by more than mere tidiness. Notably, the new PrcbFlags do not pass into the type information for the KPRCB in the public symbol files for the HAL. This suggests strongly that conditional compilation keeps them from the HAL programmers. To the HAL, the PrcbFlags are just unnamed alignment space.

Offset Definition Versions Remarks
0xF0
ULONG64 PrcbPad11 [2];
1703 to 1709  
union {
    ULONG64 PrcbPad11 [2];
    struct {
        ULONG64 TrappedSecurityDomain;
        union {
            USHORT BpbState;
            struct {
                USHORT BpbIbrsPresent : 1;
                USHORT BpbStibpPresent : 1;
                USHORT BpbSmepPresent : 1;
                USHORT BpbSimulateSpecCtrl : 1;
                USHORT BpbSimulateIbpb : 1;
                USHORT BpbIbpbPresent : 1;
                USHORT BpbCpuIdle : 1;
                USHORT BpbClearSpecCtrlOnIdle : 1;
                USHORT BpbHTDisabled : 1;
                USHORT BpbUserToUserOnly : 1;
                USHORT BpbReserved : 6;
            };
        };
        UCHAR BpbSpecCtrlValue;
        UCHAR BpbCtxSwapSetValue;
        UCHAR BpbPad [4];
    };
};
1803 and higher see notes below

Cache-alignment of the age-old ProcessorState for the 1703 release created space, defined explicitly above as PrcbPad11. When the 1803 release uses up this cache-alignment padding, albeit by defining padding of its own (BpbPad), it retains the seemingly superfluous PrcbPad11 in a clumsy union. The new members do not pass into the type information in the public symbol files for the HAL. Presumably, their definitions are enclosed in a conditional compilation block. The kernel is compiled for using the new members. The HAL sees just PrcbPad11.

Offset Definition Versions Remarks
0x0100
KPROCESSOR_STATE ProcessorState;
1703 and higher previously at 0x40;
cache-aligned
0x06C0
XSAVE_AREA_HEADER *ExtendedSupervisorState;
1803 and higher  
0x06C8 (HAL)
ULONG ProcessorSignature;
1803 and higher from HAL symbols
0x06CC (HAL)
ULONG PrcbPad11a;
1803 and higher from HAL symbols
0x06C0 (1703);
0x06C8 (kernel);
0x06D0 (HAL) 
ULONG64 PrcbPad12 [6];
1703 to 1709  
ULONG64 PrcbPad12 [5];
1803 and higher from kernel symbols
ULONG64 PrcbPad12 [4];
1803 and higher from HAL symbols

For reasons not yet understood, the HAL symbols show a ProcessorSignature member that the kernel symbols don’t, plus a corresponding difference in padding.

Non-Achitectural

From here onwards, the KPRCB does indeed seem to be private to the kernel. In contrast to 32-bit Windows, not even the HAL is known to use anything beyond the architecturally defined section.

Spin Lock Queues

Functions such as KeAcquireQueuedSpinLock that operate on the per-processor spin lock queues are exported from the HAL (originally) in 32-bit Windows but have always been kernel exports in 64-bit Windows. Another difference from 32-bit Windows is that the LockQueue is outside the architecturally defined section: the kernel itself accesses the LockQueue via the LockArray pointer in the KPCR.

Offset Definition Versions
0x0670 (5.2 to 1607);
0x06F0
KSPIN_LOCK_QUEUE LockQueue [0x21];
5.2 to early 6.0
KSPIN_LOCK_QUEUE LockQueue [0x31];
late 6.0
KSPIN_LOCK_QUEUE LockQueue [0x11];
6.1 and higher

As with 32-bit Windows, the LockQueue array is positioned such that its second element is cache-aligned. This is plainly by design. Caching is important to the 64-bit implementation, whose KeReleaseQueuedSpinLock has always prefetched its selected element. Why the first element should be in its own cache line is not known.

The array is indexed by members of the enumeration KSPIN_LOCK_QUEUE_NUMBER, which is defined first in NTDDK.H and then in WDM.H (starting with the WDK for Windows Vista).

Lookaside Lists

Broadly speaking, there are two separate types of per-processor lookaside lists. First come the system lookaside lists. These are indexed by the undocumented enumeration PP_NPAGED_LOOKASIDE_NUMBER. Its different values represent lookaside lists that cache very different fixed-size structures that each have a very specific purpose.

Offset Definition Versions Remarks
0x0880 (5.2 to early 6.0);
0x0980 (late 6.0);
0x0780 (6.1 to 1607);
0x0800
PP_LOOKASIDE_LIST PPLookasideList [0x10];
all cache-aligned

The undocumented PP_LOOKASIDE_LIST structure is a pair of pointers, P and L, to the actual lookaside lists. Ideally, they point to separate lists: the first just for the processor; the second shared. Allocations are sought first from the per-processor list, for speed, else from the shared. Allocations are freed to the per-processor list for easy re-allocation, except that if that list has reached its capacity the allocation is instead freed to the shared list.

The remaining arrays help with the efficiency of small allocations from various types of pool (NonPagedPool, PagedPool and, in version 6.2 and higher, NonPagedPoolNx). The purpose of the allocation is arbitrary. What matters is just the size: successive lists in the array are for successively larger sizes of allocation, from 0x10 to 0x0200, in increments of 0x10.

Offset Definition Versions Remarks
0x0880 (6.2 to 1607);
0x0900
GENERAL_LOOKASIDE_POOL PPNxPagedLookasideList [0x20];
6.2 and higher cache-aligned
0x0980 (5.2 to early 6.0);
0x0A80 (late 6.0);
0x0880 (6.1);
0x1480 (6.2 to 1607);
0x1500
PP_LOOKASIDE_LIST PPNPagedLookasideList [0x20];
5.2 only cache-aligned
GENERAL_LOOKASIDE_POOL PPNPagedLookasideList [0x20];
6.0 and higher cache-aligned
0x0B80 (5.2);
0x1580 (early 6.0);
0x1680 (late 6.0);
0x1480 (6.1);
0x2080 (6.2 to 1607);
0x2100
PP_LOOKASIDE_LIST PPPagedLookasideList [0x20];
5.2 only cache-aligned
GENERAL_LOOKASIDE_POOL PPPagedLookasideList [0x20];
6.0 and higher cache-aligned

Mostly Counters

Offset Definition Versions Remarks
0x0D80 (5.2);
0x2180 (early 6.0);
0x2280 (late 6.0);
0x2080 (6.1);
0x2C80 (6.2 to 1607);
0x2D00
ULONG64 volatile PacketBarrier;
5.2 to 6.1 next as LONG volatile at 0x2D00
ULONG64 PrcbPad20;
6.2 and higher  
0x0D88 (5.2);
0x2188 (early 6.0);
0x2288 (late 6.0);
0x2088 (6.1);
0x2C88 (6.2 to 1607);
0x2D08
SINGLE_LIST_ENTRY DeferredReadyListHead;
all  
0x0D90 (5.2);
0x2190 (early 6.0);
0x2290 (late 6.0);
0x2090 (6.1);
0x2C90 (6.2 to 1607);
0x2D10
LONG volatile MmPageFaultCount;
all  
0x0D94 (5.2);
0x2194 (early 6.0);
0x2294 (late 6.0);
0x2094 (6.1);
0x2C94 (6.2 to 1607);
0x2D14
LONG volatile MmCopyOnWriteCount;
all  
0x0D98 (5.2);
0x2198 (early 6.0);
0x2298 (late 6.0);
0x2098 (6.1);
0x2C98 (6.2 to 1607);
0x2D18
LONG volatile MmTransitionCount;
all  
0x0D9C (5.2)
LONG volatile MmCacheTransitionCount;
5.2 only next as ULONG at 0x3768
0x0DA0 (5.2);
0x219C (early 6.0);
0x229C (late 6.0);
0x209C (6.1);
0x2C9C (6.2 to 1607);
0x2D1C
LONG volatile MmDemandZeroCount;
all  
0x0DA4 (5.2);
0x21A0 (early 6.0);
0x22A0 (late 6.0);
0x20A0 (6.1);
0x2CA0 (6.2 to 1607);
0x02D20
LONG volatile MmPageReadCount;
all  
0x0DA8 (5.2);
0x21A4 (early 6.0);
0x22A4 (late 6.0);
0x20A4 (6.1);
0x2CA4 (6.2 to 1607);
0x2D24
LONG volatile MmPageReadIoCount;
all  
0x0DAC (5.2)
LONG volatile MmCacheReadCount;
5.2 only next as ULONG at 0x376C
0x0DB0 (5.2)
LONG volatile MmCacheIoCount;
5.2 only next as ULONG at 0x3770
0x0DB4 (5.2);
0x21A8 (early 6.0);
0x22A8 (late 6.0);
0x20A8(6.1);
0x2CA8 (6.2 to 1607);
0x2D28
LONG volatile MmDirtyPagesWriteCount;
all  
0x0DB8 (5.2);
0x21AC (early 6.0);
0x22AC (late 6.0);
0x20AC (6.1);
0x2CAC (6.2 to 1607);
0x2D2C
LONG volatile MmDirtyWriteIoCount;
all  
0x0DBC (5.2);
0x21B0 (early 6.0);
0x22B0 (late 6.0);
0x20B0 (6.1);
0x2CB0 (6.2 to 1607);
0x2D30
LONG volatile MmMappedPagesWriteCount;
all  
0x0DC0 (5.2);
0x21B4 (early 6.0);
0x22B4 (late 6.0);
0x20B4 (6.1);
0x2CB4 (6.2 to 1607);
0x2D34
LONG volatile MmMappedWriteIoCount;
all  
0x0DC4 (5.2)
LONG LookasideIrpFloat;
5.2 only next at 0x21D8
0x0DC8 (5.2);
0x21B8 (early 6.0);
0x22B8 (late 6.0);
0x20B8 (6.1);
0x2CB8 (6.2 to 1607);
0x2D38
ULONG KeSystemCalls;
all  
0x21BC (early 6.0);
0x22BC (late 6.0);
0x20BC (6.1);
0x2CBC (6.2 to 1607);
0x2D3C
ULONG KeContextSwitches;
6.0 and higher previously at 0x0DF0
0x2CC0 (6.3 to 1607)
USHORT LdtSelector;
6.3 to 1607  
0x2CC2 (6.3 to 1607);
0x2D40
USHORT PrcbPad40;
6.3 and higher  
0x21C0 (early 6.0);
0x22C0 (late 6.0);
0x20C0 (6.1);
0x2CC0 (6.2);
0x2CC4 (6.3 to 1607);
0x2D44
ULONG CcFastReadNoWait;
6.0 and higher previously at 0x2280
0x21C4 (early 6.0);
0x22C4 (late 6.0);
0x20C4 (6.1);
0x2CC4 (6.2);
0x2CC8 (6.3 to 1607);
0x2D48
ULONG CcFastReadWait;
6.0 and higher previously at 0x2284
0x21C8 (early 6.0);
0x22C8 (late 6.0);
0x20C8 (6.1);
0x2CC8 (6.2);
0x2CCC (6.3 to 1607);
0x2D4C
ULONG CcFastReadNotPossible;
6.0 and higher previously at 0x2288
0x21CC (early 6.0);
0x22CC (late 6.0);
0x20CC (6.1);
0x2CCC (6.2);
0x2CD0 (6.3 to 1607);
0x2D50
ULONG CcCopyReadNoWait;
6.0 and higher previously at 0x228C
0x21D0 (early 6.0);
0x22D0 (late 6.0);
0x20D0 (6.1);
0x2CD0 (6.2);
0x2CD4 (6.3 to 1607);
0x2D54
ULONG CcCopyReadWait;
6.0 and higher previously at 0x2290
0x21D4 (early 6.0);
0x22D4 (late 6.0);
0x20D4 (6.1);
0x2CD4 (6.2);
0x2CD8 (6.3 to 1607);
0x2D58
ULONG CcCopyReadNoWaitMiss;
6.0 and higher previously at 0x2294
0x21D8 (early 6.0);
0x22D8 (late 6.0);
0x20D8 (6.1);
0x2CD8 (6.2)
LONG LookasideIrpFloat;
6.0 to 6.2 previously at 0x0DC4;
next at 0x2D1C
0x0DCC (5.2);
0x21DC (early 6.0);
0x22DC (late 6.0);
0x20DC (6.1);
0x2CDC (6.2 to 1607);
0x2D5C
LONG volatile IoReadOperationCount;
all  
0x0DD0 (5.2);
0x21E0 (early 6.0);
0x22E0 (late 6.0);
0x20E0 (6.1);
0x2CE0 (6.2 to 1607);
0x2D60
LONG volatile IoWriteOperationCount;
all  
0x0DD4 (5.2);
0x21E4 (early 6.0);
0x22E4 (late 6.0);
0x20E4 (6.1);
0x2CE4 (6.2 to 1607);
0x2D64
LONG volatile IoOtherOperationCount;
all  
0x0DD8 (5.2);
0x21E8 (early 6.0);
0x22E8 (late 6.0);
0x20E8 (6.1);
0x2CE8 (6.2 to 1607);
0x2D68
LARGE_INTEGER IoReadTransferCount;
all  
0x0DE0 (5.2);
0x21F0 (early 6.0);
0x22F0 (late 6.0);
0x20F0 (6.1);
0x2CF0 (6.2 to 1607);
0x2D70
LARGE_INTEGER IoWriteTransferCount;
all  
0x0DE8 (5.2);
0x21F8 (early 6.0);
0x22F8 (late 6.0);
0x20F8 (6.1);
0x2CF8 (6.2 to 1607);
0x2D78
LARGE_INTEGER IoOtherTransferCount;
all  
0x0DF0 (5.2)
ULONG KeContextSwitches;
5.2 only next at 0x21BC
0x0DF4 (5.2)
UCHAR PrcbPad2 [0x0C];
5.2 only  

Cache-alignment again seeems deliberate, at least in version 5.2.

Inter-Processor Interrupts

Offset Definition Versions Remarks
0x2D00 (6.2 to 1607);
0x2D80
LONG volatile PacketBarrier;
6.2 and higher previously ULONG64 volatile at 0x2080;
cache-aligned
0x0E00 (5.2);
0x2200 (early 6.0);
0x2300 (late 6.0);
0x2100 (6.1);
0x2D04 (6.2 to 1607);
0x2D84
ULONG64 volatile TargetSet;
5.2 to 6.0  
LONG volatile TargetCount;
6.1 and higher  
0x0E08 (5.2);
0x2208 (early 6.0);
0x2308 (late 6.0);
0x2104 (6.1);
0x2D08 (6.2 to 1607);
0x2D88
ULONG volatile IpiFrozen;
all  
0x2D8C
ULONG PrcbPad30;
1709 and higher  

A substantial amount of padding, not just to the next cache line but the one after, gets put to use in Windows 8.1:

Offset Definition Versions Remarks
0x0E0C (5.2);
0x220C (early 6.0);
0x230C (late 6.0);
0x2D0C (6.2)
UCHAR PrcbPad3 [0x74];
5.2 to 6.0  
ULONG PrcbPad40 [0x1D];
6.2 only  
0x2D10 (6.3 to 1607);
0x2D90
PVOID IsrDpcStats;
6.3 and higher  
0x2D18 (6.3 to 1607);
0x2D98
ULONG DeviceInterrupts;
6.3 and higher  
0x2D1C (6.3 to 1607);
0x2D9C
LONG LookasideIrpFloat;
6.3 and higher previously at 0x2CD8
0x2D20 (6.3 to 1607);
0x2DA0
ULONG InterruptLastCount;
6.3 and higher previously at 0x2DF8
0x2D24 (6.3 to 1607);
0x2DA4
ULONG InterruptRate;
6.3 and higher previously at 0x2DFC
0x2D28 (1607);
0x2DA8
ULONG64 LastNonHrTimerExpiration;
1607 and higher  
0x2DB0
ULONG64 PrcbPad35 [2];
1709 and higher  
0x2DC0
SLIST_HEADER InterruptObjectPool;
1709 and higher previously at 0x60E0
0x2D28 (6.3 to 1511);
0x2D30 (1607);
0x2DB0 (1703);
0x2DD0
ULONG PrcbPad41 [0x16];
6.3 to 1511  
ULONG PrcbPad41 [0x14];
1607 to 1703  
ULONG64 PrcbPad41 [6];
1709 and higher  

Early versions have a REQUEST_MAILBOX for each of 64 possible processors. For Windows 7 to support more, the array was moved to the end.

Offset Definition Versions Remarks
0x0E80 (5.2);
0x2280 (early 6.0);
0x2380 (late 6.0)
REQUEST_MAILBOX RequestMailbox [0x40];
5.2 to 6.0 next at 0x4C80;
cache-aligned
0x1E80 (5.2);
0x3280 (early 6.0);
0x3380 (late 6.0)
ULONG64 volatile SenderSummary;
5.2 to 6.0  
0x1E88 (5.2);
0x3288 (early 6.0);
0x3388 (late 6.0)
UCHAR PrcbPad4 [0x78];
5.2 to 6.0  

Deferred Procedure Calls And Timing

Offset Definition Versions Remarks
0x1F00 (5.2);
0x3300 (early 6.0);
0x3400 (late 6.0);
0x2180 (6.1);
0x2D80 (6.2 to 1607);
0x2E00
KDPC_DATA DpcData [2];
all cache-aligned
0x1F40 (5.2);
0x3340 (early 6.0);
0x3440 (late 6.0);
0x21C0 (6.1);
0x2DC0 (6.2);
0x2DD0 (6.3 to 1607);
0x2E50
PVOID DpcStack;
all  
0x1F48 (5.2);
0x3348 (early 6.0);
0x3448 (late 6.0)
PVOID SavedRsp;
5.2 to early 6.0  
PVOID SparePtr0;
late 6.0 only  
0x1F50 (5.2);
0x3350 (early 6.0);
0x3450 (late 6.0);
0x21C8 (6.1);
0x2DC8 (6.2);
0x2DD8 (6.3 to 1607);
0x2E58
LONG MaximumDpcQueueDepth;
all  
0x1F54 (5.2);
0x3354 (early 6.0);
0x3454 (late 6.0);
0x21CC (6.1);
0x2DCC (6.2);
0x2DDC (6.3 to 1607);
0x2E5C
ULONG DpcRequestRate;
all  
0x1F58 (5.2);
0x3358 (early 6.0);
0x3458 (late 6.0);
0x21D0 (6.1);
0x2DD0 (6.2);
0x2DE0 (6.3 to 1607);
0x2E60
ULONG MinimumDpcRate;
all  
0x1F5C (5.2);
0x335C (early 6.0);
0x345C (late 6.0)
BOOLEAN volatile DpcInterruptRequested;
5.2 to 6.0  
0x1F5D (5.2);
0x335D (early 6.0);
0x345D (late 6.0)
BOOLEAN volatile DpcThreadRequested;
5.2 to 6.0 next as bit at 0x21DC
0x1F5E (5.2);
0x335E (early 6.0);
0x345E (late 6.0)
BOOLEAN volatile DpcRoutineActive;
5.2 to 6.0 next at 0x21DA
0x1F5F (5.2);
0x335F (early 6.0);
0x345F (late 6.0)
BOOLEAN volatile DpcThreadActive;
5.2 to 6.0 next as bit at 0x21DC
0x1F60 (5.2);
0x3360 (early 6.0);
0x3460 (late 6.0)
union {
    ULONG64 volatile TimerHand;
    ULONG64 volatile TimerRequest;
};
5.2 to 6.0 next as ULONG volatile at 0x21E0
0x1F68 (5.2);
0x3368 (early 6.0);
0x3468 (late 6.0)
LONG TickOffset;
5.2 to 6.0 next as ULONG64 at 0x4470
0x1F6C (5.2);
0x336C (early 6.0);
0x346C (late 6.0)
LONG MasterOffset;
5.2 to 6.0 next at 0x21E4
0x1F70 (5.2);
0x3370 (early 6.0);
0x3470 (late 6.0);
0x21D4 (6.1);
0x2DD4 (6.2);
0x2DE4 (6.3 to 1607);
0x2E64
ULONG DpcLastCount;
all  
0x1F74 (5.2);
0x3374 (early 6.0);
0x3474 (late 6.0);
0x21D8 (6.1);
0x2DD8 (6.2);
0x2DE8 (6.3 to 1607);
0x2E68
UCHAR ThreadDpcEnabled;
all  
0x1F75 (5.2);
0x3375 (early 6.0);
0x3475 (late 6.0);
0x21D9 (6.1);
0x2DD9 (6.2);
0x2DE9 (6.3 to 1607);
0x2E69
UCHAR volatile QuantumEnd;
all  
0x1F76 (5.2);
0x3376 (early 6.0);
0x3476 (late 6.0);
0x21DA (6.1);
0x2DDA (6.2);
0x2DEA (6.3 to 1607);
0x2E6A
UCHAR PrcbPad50;
5.2 to 6.0  
BOOLEAN volatile DpcRoutineActive;
6.1 and higher previously at 0x345E
0x1F77 (5.2);
0x3377 (early 6.0);
0x3477 (late 6.0);
0x21DB (6.1);
0x2DDB (6.2);
0x2DEB (6.3 to 1607);
0x2E6B
UCHAR volatile IdleSchedule;
all  

Windows 7 introduced, but did not completely formalise, a set of bit flags for DPC management: DpcThreadActive and DpcThreadRequested were previously BOOLEAN volatile at offsets 0x345F and 0x345D (late 6.0).

Offset Definition Versions
0x1F78 (5.2);
0x3378 (early 6.0);
0x3478 (late 6.0);
0x21DC (6.1);
0x2DDC (6.2);
0x2DEC (6.3 to 1607);
0x2E6C
LONG DpcSetEventRequest;
5.2 to 6.0
union {
    LONG volatile DpcRequestSummary;
    SHORT DpcRequestSlot [2];
    struct {
        SHORT NormalDpcState;
        union {
            USHORT volatile DpcThreadActive : 1;        // 0x0001
            SHORT ThreadDpcState;
        };
    };
};
6.1 only
union {
    LONG volatile DpcRequestSummary;
    SHORT DpcRequestSlot [2];
    struct {
        SHORT NormalDpcState;
        SHORT ThreadDpcState;
    };
    struct {
        ULONG DpcNormalProcessingActive : 1;            // 0x00000001
        ULONG DpcNormalProcessingRequested : 1;         // 0x00000002
        ULONG DpcNormalThreadSignal : 1;                // 0x00000004
        ULONG DpcNormalTimerExpiration : 1;             // 0x00000008
        ULONG DpcNormalDpcPresent : 1;                  // 0x00000010
        ULONG DpcNormalLocalInterrupt : 1;              // 0x00000020
        ULONG DpcNormalSpare : 10;
        ULONG DpcThreadActive : 1;                      // 0x00010000
        ULONG DpcThreadRequested : 1;                   // 0x00020000
        ULONG DpcThreadSpare : 14;
    };
};
6.2 and higher

Miscellany

Offset Definition Versions Remarks
0x1F7C (5.2);
0x337C (early 6.0);
0x347C (late 6.0);
0x21E0 (6.1);
0x2DE0 (6.2);
0x2DF0 (6.3 to 1607);
0x2E70
LONG PrcbPad40;
5.2 only  
ULONG KeExceptionDispatchCount;
6.0 only previously at 0x22A0;
next at 0x4734
ULONG volatile TimerHand;
6.1 only previously ULONG64 volatile in union at 0x3460
ULONG LastTimerHand;
6.2 and higher  
0x1F80 (5.2)
PVOID DpcThread;
5.2 only  
0x1F88 (5.2);
0x3380 (early 6.0);
0x3480 (late 6.0);
0x21E4 (6.1)
KEVENT DpcEvent;
5.2 to 6.0  
LONG MasterOffset;
6.1 only previously at 0x346C
0x21E8 (6.1);
0x2DE4 (6.2);
0x2DF4 (6.3 to 1607);
0x2E74
ULONG LastTick;
6.1 and higher  
0x21EC (6.1)
ULONG UnusedPad;
6.1 only  
0x2DE8 (6.2);
0x2DF8 (6.3 to 1607);
0x2E78
ULONG ClockInterrupts;
6.2 and higher  
0x2DEC (6.2);
0x2DFC (6.3 to 1607);
0x2E7C
ULONG ReadyScanTick;
6.2 and higher  
0x2DF0 (6.2)
UCHAR BalanceState;
6.2 only  
0x21F0 (6.1);
0x2DF1 (6.2)
ULONG64 PrcbPad50 [2];
6.1 only  
UCHAR PrcbPad50 [7];
6.2 only  
0x2DF8 (6.2)
ULONG InterruptLastCount;
6.2 only next at 0x2D20
0x2DFC (6.2)
ULONG InterruptRate;
6.2 only next at 0x2D24
0x2E00 (10.0 to 1607);
0x2E80
PVOID InterruptObject [0x0100];
10.0 and higher cache-aligned
0x2200 (6.1);
0x2E00 (6.2 to 6.3);
0x3600 (10.0 to 1607);
0x3680
KTIMER_TABLE TimerTable;
6.1 and higher cache-aligned
0x4400 (6.1);
0x5000 (6.2 to 6.3);
0x5800 (10.0 to 1607);
0x5880
KGATE DpcGate;
6.1 and higher  
0x3398 (early 6.0);
0x3498 (late 6.0);
0x4418 (6.1);
0x5018 (6.2 to 6.3);
0x5818 (10.0 to 1607);
0x5898
PVOID PrcbPad51;
6.0 only  
PVOID PrcbPad52;
6.1 and higher  
0x1FA0 (5.2);
0x33A0 (early 6.0);
0x34A0 (late 6.0);
0x4420 (6.1);
0x5020 (6.2 to 6.3);
0x5820 (10.0 to 1607);
0x58A0
KDPC CallDpc;
all cache-aligned

Padding to the next cache line is still not completely put to use.

Offset Definition Versions Remarks
0x33E0 (early 6.0);
0x34E0 (late 6.0);
0x4460 (6.1);
0x5060 (6.2 to 6.3);
0x5860 (10.0 to 1607);
0x58E0
LONG ClockKeepAlive;
6.0 and higher  
0x33E4 (early 6.0);
0x34E4 (late 6.0);
0x4464 (6.1)
UCHAR ClockCheckSlot;
6.0 to 6.1  
0x33E5 (early 6.0);
0x34E5 (late 6.0);
0x4465 (6.0 to 6.1)
UCHAR ClockPollCycle;
6.0 to 6.1  
0x33E6 (early 6.0);
0x34E6 (late 6.0)
UCHAR PrcbPad6 [2];
6.0 only  
0x5064 (6.2 to 6.3);
0x5864 (10.0 to 1607);
0x58E4
UCHAR PrcbPad60 [2];
6.2 and higher  
0x4466 (6.1);
0x5066 (6.2 to 6.3);
0x5866 (10.0 to 1607);
0x58E6
USHORT NmiActive;
6.1 and higher  
0x33E8 (early 6.0);
0x34E8 (late 6.0);
0x4468 (6.1);
0x5068 (6.2 to 6.3);
0x5868 (10.0 to 1607);
0x58E8
LONG DpcWatchdogPeriod;
6.0 and higher  
0x33EC (early 6.0);
0x34EC (late 6.0);
0x446C (6.1);
0x506C (6.2 to 6.3);
0x586C (10.0 to 1607);
0x58EC
LONG DpcWatchdogCount;
6.0 and higher  
0x4470 (6.0)
ULONG64 TickOffset;
6.1 only previously LONG at 0x3468
0x4478 (6.1);
0x5070 (6.2 to 6.3);
0x5870 (10.0 to 1607);
0x58F0
LONG volatile KeSpinLockOrdering;
6.1 and higher  
0x1FE0 (5.2);
0x33F0 (early 6.0);
0x34F0 (late 6.0);
0x447C (6.1);
0x5074 (6.2 to 6.3);
0x5874
ULONG64 PrcbPad7 [4];
5.2 only  
ULONG64 PrcbPad70 [2];
6.0 only  
ULONG PrcbPad70;
6.1 only  
ULONG PrcbPad70 [1];
6.2 and higher  
0x58F4
ULONG DpcWatchdogProfileCumulativeDpcThreshold;
1703 and higher  
0x5078 (6.2 to 6.3);
0x5878 (10.0 to 1607);
0x58F8
PVOID CachedPtes;
6.2 and higher  

Scheduling

Offset Definition Versions Remarks
0x2000 (5.2);
0x3400 (early 6.0);
0x3500 (late 6.0);
0x4480 (6.1);
0x5080 (6.2 to 6.3);
0x5880 (10.0 to 1607);
0x5900
LIST_ENTRY WaitListHead;
all cache-aligned
0x3410 (early 6.0);
0x3510 (late 6.0);
0x4490 (6.1);
0x5090 (6.2 to 6.3);
0x5890 (10.0 to 1607);
0x5910
KSPIN_LOCK WaitLock;
6.0 and higher  
0x2010 (5.2);
0x3418 (early 6.0);
0x3518 (late 6.0);
0x4498 (6.1);
0x5098 (6.2 to 6.3);
0x5898 (10.0 to 1607);
0x5918
ULONG ReadySummary;
all  
0x509C (6.3);
0x589C (10.0 to 1607);
0x591C
LONG AffinitizedSelectionMask;
6.3 and higher  
0x2014 (5.2);
0x341C (early 6.0);
0x351C (late 6.0);
0x449C (6.1);
0x509C (6.2);
0x50A0 (6.3);
0x58A0 (10.0 to 1607);
0x5920
ULONG QueueIndex;
all  
0x50A0 (6.2)
ULONG ReadyQueueWeight;
6.2 only  
0x50A4 (6.3);
0x58A4 (10.0 to 1607);
0x5924
ULONG PrcbPad75;
6.2 only  
ULONG PrcbPad75 [3];
6.3 and higher  
0x44A0 (6.1);
0x50A8 (6.2);
0x50B0 (6.3);
0x58B0 (10.0 to 1607);
0x5930
KDPC TimerExpirationDpc;
6.1 and higher  
0x3420 (early 6.0);
0x3520 (late 6.0);
0x44E0 (6.1)
ULONG64 PrcbPad71 [0x0C];
6.0 only  
ULONG64 PrcbPad72 [4];
6.1 only  
0x50E8 (6.2)
KPRCB *BuddyPrcb;
6.2 only  
0x50F0 (6.2 to 6.3);
0x58F0 (10.0 to 1607);
0x5970
RTL_RB_TREE ScbQueue;
6.2 and higher  
0x2018 (5.2);
0x3480 (early 6.0);
0x3580 (late 6.0);
0x4500 (6.1);
0x5100 (6.2 to 6.3);
0x5900 (10.0 to 1607);
0x5980
LIST_ENTRY DispatcherReadyListHead [0x20];
all  
0x2218 (5.2);
0x3680 (early 6.0);
0x3780 (late 6.0);
0x4700 (6.1);
0x5300 (6.2 to 6.3);
0x5B00 (10.0 to 1607);
0x5B80
ULONG InterruptCount;
all  
0x221C (5.2);
0x3684 (early 6.0);
0x3784 (late 6.0);
0x4704 (6.1);
0x5304 (6.2 to 6.3);
0x5B04 (10.0 to 1607);
0x5B84
ULONG KernelTime;
all  
0x2220 (5.2);
0x3688 (early 6.0);
0x3788 (late 6.0);
0x4708 (6.1);
0x5308 (6.2 to 6.3);
0x5B08 (10.0 to 1607);
0x5B88
ULONG UserTime;
all  
0x2224 (5.2);
0x368C (early 6.0);
0x378C (late 6.0);
0x470C (6.1);
0x530C (6.2 to 6.3);
0x5B0C (10.0 to 1607);
0x5B8C
ULONG DpcTime;
all  
0x2228 (5.2);
0x3690 (early 6.0);
0x3790 (late 6.0);
0x4710 (6.1);
0x5310 (6.2 to 6.3);
0x5B10 (10.0 to 1607);
0x5B90
ULONG InterruptTime;
all  
0x222C (5.2);
0x3694 (early 6.0);
0x3794 (late 6.0);
0x4714 (6.1);
0x5314 (6.2 to 6.3);
0x5B14 (10.0 to 1607);
0x5B94
ULONG AdjustDpcThreshold;
all  
0x2230 (5.2);
0x3698 (early 6.0);
0x3798 (late 6.0)
UCHAR SkipTick;
5.2 to 6.0  
0x2231 (5.2);
0x3699 (early 6.0);
0x3799 (late 6.0);
0x4718 (6.1);
0x5318 (6.2 to 6.3);
0x5B18 (10.0 to 1607);
0x5B98
UCHAR DebuggerSavedIRQL;
all  
0x2232 (5.2);
0x369A (early 6.0);
0x379A (late 6.0)
UCHAR PollSlot;
5.2 to 6.0  
0x2233 (5.2);
0x369B (early 6.0);
0x379B (late 6.0);
0x4719 (6.1)
UCHAR PrcbPad8 [0x0D];
5.2 only  
UCHAR PrcbPad80 [5];
6.0 only  
UCHAR PrcbPad80 [7];
6.1 only  
0x5319 (6.2 to 6.3);
0x5B19 (10.0 to 1607);
0x5B99
BOOLEAN GroupSchedulingOverQuota;
6.2 and higher  
0x531A (6.2 to 6.3);
0x5B1A (10.0 to 1607);
0x5B9A
BOOLEAN volatile DeepSleep;
6.2 and higher  
0x531B (6.2 to 6.3);
0x5B1B (10.0 to 1607);
0x5B9B
UCHAR PrcbPad80 [1];
6.2 to 6.3  
UCHAR PrcbPad80 [5];
10.0 to 1703  
UCHAR PrcbPad80;
1709 and higher  
0x531C (6.2 to 6.3)
ULONG ScbOffset;
6.2 to 6.3 next at 0x0658
0x36A0 (early 6.0);
0x37A0 (late 6.0);
0x4720 (6.1);
0x5320 (6.2 to 6.3);
0x5B20 (10.0 to 1607);
0x5BA0 (1703);
0x5B9C
ULONG DpcTimeCount;
6.0 and higher  
0x36A4 (early 6.0);
0x37A4 (late 6.0);
0x4724 (6.1);
0x5324 (6.2 to 6.3);
0x5B24 (10.0 to 1607);
0x5BA4 (1703);
0x5BA0
ULONG DpcTimeLimit;
6.0 and higher  
0x36A8 (early 6.0);
0x37A8 (late 6.0);
0x4728 (6.1);
0x5328 (6.2 to 6.3);
0x5B28 (10.0 to 1607);
0x5BA8 (1703);
0x5BA4
ULONG PeriodicCount;
6.0 and higher  
0x36AC (early 6.0);
0x37AC (late 6.0);
0x472C (6.1);
0x532C (6.2 to 6.3);
0x5B2C (10.0 to 1607);
0x5BAC (1703);
0x5BA8
ULONG PeriodicBias;
6.0 and higher  
0x36B0 (early 6.0);
0x37B0 (late 6.0)
ULONG64 PrcbPad81 [2];
6.0 only  
0x4730 (6.1);
0x5330 (6.2 to 6.3);
0x5B30 (10.0 to 1607);
0x5BB0 (1703);
0x5BAC
ULONG AvailableTime;
6.1 and higher  
0x4734 (6.1);
0x5334 (6.2 to 6.3);
0x5B34 (10.0 to 1607);
0x5BB4 (1703);
0x5BB0
ULONG KeExceptionDispatchCount;
6.1 and higher previously at 0x347C
0x5BB8 (1703);
0x5BB4
ULONG ReadyThreadCount;
1703 and higher  
0x5BB8
ULONG64 ReadyQueueExpectedRunTime;
1709 and higher previously at 0x5C00
0x2240 (5.2);
0x36C0 (early 6.0);
0x37C0 (late 6.0);
0x4738 (6.1);
0x5338 (6.2)
KNODE *ParentNode;
5.2 to 6.2 next at 0x0640
0x2248 (5.2);
0x26C8 (early 6.0);
0x37C8 (late 6.0)
ULONG64 MultiThreadProcesserSet;
5.2 to 6.0  
0x2250 (5.2);
0x36D0 (early 6.0);
0x37D0 (late 6.0)
KPRCB *MultiThreadSetMaster;
5.2 to 6.0  
0x2258 (5.2)
LONG Sleeping;
5.2 only next at 0x36F4
0x36D8 (early 6.0);
0x37D8 (late 6.0);
0x4740 (6.1);
0x5340 (6.2);
0x5338 (6.3);
0x5B38 (10.0 to 1607);
0x5BC0
ULONG64 StartCycles;
6.0 and higher  
0x5B40 (10.0 to 1607);
0x5BC8
ULONG64 TaggedCyclesStart;
10.0 and higher  
0x5B48 (10.0 to 1607);
0x5BD0
ULONG64 TaggedCycles [2];
10.0 and higher  
0x4748 (6.1)
ULONG64 PrcbPad82 [3];
6.1 only  
0x5348 (6.2);
0x5340 (6.3);
0x5B58 (10.0 to 1607);
0x5BE0
ULONG64 GenerationTarget;
6.2 and higher  
0x5350 (6.2);
0x5348 (6.3);
0x5B60 (10.0 to 1607);
0x5BE8
ULONG64 AffinitizedCycles;
6.2 and higher  
0x5BF0
ULONG64 ImportantCycles;
1703 and higher  
0x5BF8
ULONG64 UnimportantCycles;
1703 and higher  
0x5C00 (1703)
ULONG64 ReadyQueueExpectedRunTime;
1703 only next at 0x5BB8
0x5358 (6.2);
0x5350 (6.3);
0x5B68 (10.0 to 1607);
0x5C08 (1703)
ULONG64 PrcbPad81;
6.2 only  
ULONG64 PrcbPad81 [2];
6.3 only  
ULONG PrcbPad81 [0x1D];
10.0 to 1607  
ULONG PrcbPad81 [0x15];
1703 only  
0x225C (5.2)
ULONG PrcbPad90 [1];
5.2 only  
0x2260 (5.2)
ULONG DebugDpcTime;
5.2 only  
0x5C5C (1703);
0x5C00
ULONG DpcWatchdogProfileSingleDpcThreshold;
1703 and higher  
0x36E0 (early 6.0);
0x37E0 (late 6.0);
0x4760 (6.1);
0x5360 (6.2 to 6.3);
0x5BDC (10.0 to 1607);
0x5C60 (1703);
0x5C04
LONG volatile MmSpinLockOrdering;
6.0 and higher  
0x5C08
PVOID volatile CachedStack;
1709 and higher  
0x2264 (5.2);
0x36E4 (early 6.0);
0x37E4 (late 6.0);
0x4764 (6.1);
0x5364 (6.2 to 6.3);
0x5BE0 (10.0 to 1607);
0x5C64 (1703);
0x5C10
ULONG PageColor;
all  
0x2268 (5.2);
0x36E8 (early 6.0);
0x37E8 (late 6.0);
0x4768 (6.1);
0x5368 (6.2 to 6.3);
0x5BE4 (10.0 to 1607);
0x5C68 (1703);
0x5C14
ULONG NodeColor;
all  
0x226C (5.2);
0x36EC (early 6.0);
0x37EC (late 6.0);
0x476C (6.1);
0x536C (6.2 to 6.3);
0x5BE8 (10.0 to 1607);
0x5C6C (1703);
0x5C18
ULONG NodeShiftedColor;
all  
0x2270 (5.2);
0x36F0 (early 6.0);
0x37F0 (late 6.0);
0x4770 (6.1);
0x5370 (6.2 to 6.3);
0x5BEC (10.0 to 1607);
0x5C70 (1703);
0x5C1C
ULONG SecondaryColorMask;
all  
0x2274 (5.2)
UCHAR PrcbPad9 [0x0C];
5.2 only  
0x36F4 (early 6.0);
0x37F4 (late 6.0)
LONG Sleeping;
6.0 only previously at 0x2258
0x4774 (6.1);
0x5374 (6.2 to 6.3);
0x5BF0 (10.0 to 1607);
0x5C74 (1703);
0x5C20
ULONG PrcbPad83;
6.1 to 1703  
ULONG64 PrcbPad81 [3];
1709 only  
UCHAR PrcbPad81 [7];
1803 and higher  
0x5C27
UCHAR TbFlushListActive;
1803 and higher  
0x5C28
ULONG64 PrcbPad82 [2];
1803 and higher  
0x36F8 (early 6.0);
0x37F8 (late 6.0);
0x4778 (6.1);
0x5378 (6.2 to 6.3);
0x5BF8 (10.0 to 1607);
0x5C78 (1703);
0x5C38
ULONG64 CycleTime;
6.0 and higher  
0x5C80 (1703);
0x5C40
ULONG64 Cycles [4][2];
1703 and higher  
0x5C40 (10.0 to 1607);
0x5CC0 (1703)
ULONG PrcbPad84 [0x10];
10.0 to 1703  

Counters

Windows Vista added numerous counters, mostly to do with caching by the file system, to an original handful. For some reason, the originals were moved to another area of counters nearer the start.

Offset Definition Versions Remarks
0x2280 (5.2)
ULONG CcFastReadNoWait;
5.2 only next at 0x21C0
0x2284 (5.2)
ULONG CcFastReadWait;
5.2 only next at 0x21C4
0x2288 (5.2)
ULONG CcFastReadNotPossible;
5.2 only next at 0x21C8
0x228C (5.2)
ULONG CcCopyReadNoWait;
5.2 only next at 0x21CC
0x2290 (5.2)
ULONG CcCopyReadWait;
5.2 only next at 0x21D0
0x2294 (5.2)
ULONG CcCopyReadNoWaitMiss;
5.2 only next at 0x21D4
0x3700 (early 6.0);
0x3800 (late 6.0);
0x4780 (6.1);
0x5380 (6.2 to 6.3);
0x5C80 (10.0 to 1607);
0x5D00 (1703);
0x5C80
ULONG CcFastMdlReadNoWait;
6.0 and higher  
0x3704 (early 6.0);
0x3804 (late 6.0);
0x4784 (6.1);
0x5384 (6.2 to 6.3);
0x5C84 (10.0 to 1607);
0x5D04 (1703);
0x5C84
ULONG CcFastMdlReadWait;
6.0 and higher  
0x3708 (early 6.0);
0x3808 (late 6.0);
0x4788 (6.1);
0x5388 (6.2 to 6.3);
0x5C88 (10.0 to 1607);
0x5D08 (1703);
0x5C88
ULONG CcFastMdlReadNotPossible;
6.0 and higher  
0x370C (early 6.0);
0x380C (late 6.0);
0x478C (6.1);
0x538C (6.2 to 6.3);
0x5C8C (10.0 to 1607);
0x5D0C (1703);
0x5C8C
ULONG CcMapDataNoWait;
6.0 and higher  
0x3710 (early 6.0);
0x3810 (late 6.0);
0x4790 (6.1);
0x5390 (6.2 to 6.3);
0x5C90 (10.0 to 1607);
0x5D10 (1703);
0x5C90
ULONG CcMapDataWait;
6.0 and higher  
0x3714 (early 6.0);
0x3814 (late 6.0);
0x4794 (6.1);
0x5394 (6.2 to 6.3);
0x5C94 (10.0 to 1607);
0x5D14 (1703);
0x5C94
ULONG CcPinMappedDataCount;
6.0 and higher  
0x3718 (early 6.0);
0x3818 (late 6.0);
0x4798 (6.1);
0x5398 (6.2 to 6.3);
0x5C98 (10.0 to 1607);
0x5D18 (1703);
0x5C98
ULONG CcPinReadNoWait;
6.0 and higher  
0x371C (early 6.0);
0x381C (late 6.0);
0x479C (6.1);
0x539C (6.2 to 6.3);
0x5C9C (10.0 to 1607);
0x5D1C (1703);
0x5C9C
ULONG CcPinReadWait;
6.0 and higher  
0x3720 (early 6.0);
0x3820 (late 6.0);
0x47A0 (6.1);
0x53A0 (6.2 to 6.3);
0x5CA0 (10.0 to 1607);
0x5D20 (1703);
0x5CA0
ULONG CcMdlReadNoWait;
6.0 and higher  
0x3724 (early 6.0);
0x3824 (late 6.0);
0x47A4 (6.1);
0x53A4 (6.2 to 6.3);
0x5CA4 (10.0 to 1607);
0x5D24 (1703);
0x5CA4
ULONG CcMdlReadWait;
6.0 and higher  
0x3728 (early 6.0);
0x3828 (late 6.0);
0x47A8 (6.1);
0x53A8 (6.2 to 6.3);
0x5CA8 (10.0 to 1607);
0x5D28 (1703);
0x5CA8
ULONG CcLazyWriteHotSpots;
6.0 and higher  
0x372C (early 6.0);
0x382C (late 6.0);
0x47AC (6.1);
0x53AC (6.2 to 6.3);
0x5CAC (10.0 to 1607);
0x5D2C (1703);
0x5CAC
ULONG CcLazyWriteIos;
6.0 and higher  
0x3730 (early 6.0);
0x3830 (late 6.0);
0x47B0 (6.1);
0x53B0 (6.2 to 6.3);
0x5CB0 (10.0 to 1607);
0x5D30 (1703);
0x5CB0
ULONG CcLazyWritePages;
6.0 and higher  
0x3734 (early 6.0);
0x3834 (late 6.0);
0x47B4 (6.1);
0x53B4 (6.2 to 6.3);
0x5CB4 (10.0 to 1607);
0x5D34 (1703);
0x5CB4
ULONG CcDataFlushes;
6.0 and higher  
0x3738 (early 6.0);
0x3838 (late 6.0);
0x47B8 (6.1);
0x53B8 (6.2 to 6.3);
0x5CB8 (10.0 to 1607);
0x5D38 (1703);
0x5CB8
ULONG CcDataPages;
6.0 and higher  
0x373C (early 6.0);
0x383C (late 6.0);
0x47BC (6.1);
0x53BC (6.2 to 6.3);
0x5CBC (10.0 to 1607);
0x5D3C (1703);
0x5CBC
ULONG CcLostDelayedWrites;
6.0 and higher  
0x3740 (early 6.0);
0x3840 (late 6.0);
0x47C0 (6.1);
0x53C0 (6.2 to 6.3);
0x5CC0 (10.0 to 1607);
0x5D40 (1703);
0x5CC0
ULONG CcFastReadResourceMiss;
6.0 and higher  
0x3744 (early 6.0);
0x3844 (late 6.0);
0x47C4 (6.1);
0x53C4 (6.2 to 6.3);
0x5CC4 (10.0 to 1607);
0x5D44 (1703);
0x5CC4
ULONG CcCopyReadWaitMiss;
6.0 and higher  
0x3748 (early 6.0);
0x3848 (late 6.0);
0x47C8 (6.1);
0x53C8 (6.2 to 6.3);
0x5CC8 (10.0 to 1607);
0x5D48 (1703);
0x5CC8
ULONG CcFastMdlReadResourceMiss;
6.0 and higher  
0x374C (early 6.0);
0x384C (late 6.0);
0x47CC (6.1);
0x53CC (6.2 to 6.3);
0x5CCC (10.0 to 1607);
0x5D4C (1703);
0x5CCC
ULONG CcMapDataNoWaitMiss;
6.0 and higher  
0x3750 (early 6.0);
0x3850 (late 6.0);
0x47D0 (6.1);
0x53D0 (6.2 to 6.3);
0x5CD0 (10.0 to 1607);
0x5D50 (1703);
0x5CD0
ULONG CcMapDataWaitMiss;
6.0 and higher  
0x3754 (early 6.0);
0x3854 (late 6.0);
0x47D4 (6.1);
0x53D4 (6.2 to 6.3);
0x5CD4 (10.0 to 1607);
0x5D54 (1703);
0x5CD4
ULONG CcPinReadNoWaitMiss;
6.0 and higher  
0x3758 (early 6.0);
0x3858 (late 6.0);
0x47D8 (6.1);
0x53D8 (6.2 to 6.3);
0x5CD8 (10.0 to 1607);
0x5D58 (1703);
0x5CD8
ULONG CcPinReadWaitMiss;
6.0 and higher  
0x375C (early 6.0);
0x385C (late 6.0);
0x47DC (6.1);
0x53DC (6.2 to 6.3);
0x5CDC (10.0 to 1607);
0x5D5C (1703);
0x5CDC
ULONG CcMdlReadNoWaitMiss;
6.0 and higher  
0x3760 (early 6.0);
0x3860 (late 6.0);
0x47E0 (6.1);
0x53E0 (6.2 to 6.3);
0x5CE0 (10.0 to 1607);
0x5D60 (1703);
0x5CE0
ULONG CcMdlReadWaitMiss;
6.0 and higher  
0x3764 (early 6.0);
0x3864 (late 6.0);
0x47E4 (6.1);
0x53E4 (6.2 to 6.3);
0x5CE4 (10.0 to 1607);
0x5D64 (1703);
0x5CE4
ULONG CcReadAheadIos;
6.0 and higher  
0x3768 (early 6.0);
0x3868 (late 6.0);
0x47E8 (6.1);
0x53E8 (6.2 to 6.3);
0x5CE8 (10.0 to 1607);
0x5D68 (1703);
0x5CE8
ULONG MmCacheTransitionCount;
6.0 and higher previously LONG volatile at 0x0D9C
0x376C (early 6.0);
0x386C (late 6.0);
0x47EC (6.1);
0x53EC (6.2 to 6.3);
0x5CEC (10.0 to 1607);
0x5D6C (1703);
0x5CEC
ULONG MmCacheReadCount;
6.0 and higher previously LONG volatile at 0x0DAC
0x3770 (early 6.0);
0x3870 (late 6.0);
0x47F0 (6.1);
0x53F0 (6.2 to 6.3);
0x5CF0 (10.0 to 1607);
0x5D70 (1703);
0x5CF0
ULONG MmCacheIoCount;
6.0 and higher previously LONG volatile at 0x0DB0
0x3774 (early 6.0);
0x3874 (late 6.0);
0x47F4 (6.1);
0x53F4 (6.2 to 6.3);
0x5CF4 (10.0 to 1607);
0x5D74 (1703);
0x5CF4
ULONG PrcbPad91 [3];
6.0 only  
ULONG PrcbPad91 [1];
6.1 only  
ULONG PrcbPad91 [3];
6.2 to 1709  
ULONG PrcbPad91;
1803 and higher  
0x47F8 (6.1)
ULONG64 RuntimeAccumulation;
6.1 only  
0x5CF8
PVOID MmFlushList;
1803 and higher  

Windows Vista brought forward the PowerState to a cache boundary.

Offset Definition Versions Remarks
0x3780 (early 6.0);
0x3880 (late 6.0);
0x4800 (6.1);
0x5400 (6.2 to 6.3);
0x5D00 (10.0 to 1607);
0x5D80 (1703);
0x5D00
PROCESSOR_POWER_STATE PowerState;
6.0 and higher previously at 0x22D0;
cache-aligned
0x5F00
PVOID HyperPte;
1709 and higher previously at 0x60C0
0x55C8 (6.2);
0x55E0 (6.3);
0x5ED0 (10.0 to 1607);
0x5F58 (1703);
0x5F08
PVOID ScbList [2];
6.2 and higher  
0x5F68 (1703);
0x5F18
KDPC ForceIdleDpc;
1703 and higher  
0x4900 (6.1);
0x55D8 (6.2);
0x55F0 (6.3);
0x5EE0 (10.0 to 1607);
0x5FA8 (1703)
UCHAR PrcbPad92 [0x10];
6.1 only  
ULONG PrcbPad92 [0x16];
6.2 only  
ULONG PrcbPad92 [0x13];
6.3 only  
ULONG PrcbPad92 [7];
10.0 to1607  
ULONG PrcbPad92 [0x12];
1703 only  
0x2298 (5.2);
0x38B8 (early 6.0);
0x3998 (late 6.0);
0x4910 (6.1);
0x5630 (6.2);
0x563C (6.3);
0x5EFC (10.0 to 1607);
0x5FF0 (1703)
ULONG KeAlignmentFixupCount;
5.2 to 1703 next at 0x6038
0x229C (5.2)
ULONG KeDcacheFlushCount;
5.2 only  
0x22A0 (5.2)
ULONG KeExceptionDispatchCount;
5.2 only next at 0x337C
0x22A4 (5.2)
ULONG KeFirstLevelTbFills;
5.2 only  
0x22A8 (5.2)
ULONG KeFloatingEmulationCount;
5.2 only  
0x22AC (5.2)
ULONG KeIcacheFlushCount;
5.2 only  
0x22B0 (5.2)
ULONG KeSecondLevelTbFills;
5.2 only  
0x22B4 (5.2);
0x38BC (early 6.0);
0x399C (late 6.0)
UCHAR VendorString [0x0D];
5.2 to 6.0 next at 0x4BB8
0x22C1 (5.2);
0x38C9 (early 6.0);
0x39A9 (late 6.0)
UCHAR PrcbPad10 [2];
5.2 only  
UCHAR PrcbPad10 [3];
6.0 only  
0x22C4 (5.2);
0x38CC (early 6.0);
0x39AC (late 6.0)
ULONG FeatureBits;
5.2 to 6.0 next at 0x4BC8
0x22C8 (5.2);
0x38D0 (early 6.0);
0x39B0 (late 6.0)
LARGE_INTEGER UpdateSignature;
5.2 to 6.0 next at 0x4BD0
0x22D0 (5.2)
PROCESSOR_POWER_STATE PowerState;
5.2 only next at 0x3780
0x38D8 (early 6.0);
0x39B8 (late 6.0);
0x4918 (6.1);
0x5638 (6.2);
0x5640 (6.3);
0x5F00 (10.0 to 1607);
0x5FF8 (1703);
0x5F58
KDPC DpcWatchdogDpc;
6.0 and higher  
0x3918 (early 6.0);
0x39F8 (late 6.0);
0x4958 (6.1);
0x5678 (6.2);
0x5680 (6.3);
0x5F40 (10.0 to 1607);
0x6038 (1703);
0x5F98
KTIMER DpcWatchdogTimer;
6.0 and higher  
0x2440 (5.2);
0x3958 (early 6.0);
0x3A38 (late 6.0);
0x4998 (6.1);
0x56B8 (6.2);
0x56C0 (6.3);
0x5F80 (10.0 to 1607);
0x6078 (1703);
0x5FD8
CACHE_DESCRIPTOR Cache [5];
all  
0x247C (5.2);
0x3994 (early 6.0);
0x3A74 (late 6.0);
0x49D4 (6.1);
0x56F4 (6.2);
0x56FC (6.3);
0x5FBC (10.0 to 1607);
0x60B4 (1703);
0x6014
ULONG CacheCount;
all last member in 5.2

Appended For Windows Vista

Offset Definition Versions Remarks
0x3998 (early 6.0);
0x3A78 (late 6.0);
0x49D8 (6.1);
0x56F8 (6.2);
0x5700 (6.3);
0x5FC0 (10.0 to 1607);
0x60B8 (1703);
0x6018
ULONG volatile CachedCommit;
6.0 and higher  
0x399C (early 6.0);
0x3A7C (late 6.0);
0x49DC (6.1);
0x56FC (6.2);
0x5704 (6.3);
0x5FC4 (10.0 to 1607);
0x60BC (1703);
0x601C
ULONG volatile CachedResidentAvailable;
6.0 and higher  
0x39A0 (early 6.0);
0x3A80 (late 6.0);
0x49E0 (6.1);
0x5700 (6.2);
0x5708 (6.3);
0x5FC8 (10.0 to 1607);
0x60C0
PVOID HyperPte;
6.0 to 1703 next at 0x5F00
0x39A8 (early 6.0);
0x3A88 (late 6.0);
0x49E8 (6.1);
0x5708 (6.2);
0x5710 (6.3);
0x5FD0 (10.0 to 1607);
0x60C8 (1703);
0x6020
PVOID WheaInfo;
6.0 and higher  
0x39B0 (early 6.0);
0x3A90 (late 6.0);
0x49F0 (6.1);
0x5710 (6.2);
0x5718 (6.3);
0x5FD8 (10.0 to 1607);
0x60D0 (1703);
0x6028
PVOID EtwSupport;
6.0 and higher  
0x39C0 (early 6.0);
0x3AA0 (late 6.0);
0x4A00 (6.1);
0x5720 (6.2 to 6.3);
0x5FE0 (10.0 to 1607);
0x60E0
SLIST_HEADER InterruptObjectPool;
6.0 to 1703 next at 0x2DC0
0x6030
PVOID ExSaPageArray;
1709 and higher previously at 0x6978
0x6038
ULONG KeAlignmentFixupCount;
1709 and higher previously at 0x5FF0
0x603C
ULONG PrcbPad95;
1709 and higher  
0x39D0 (early 6.0);
0x3AB0 (late 6.0);
0x4A10 (6.1);
0x5730 (6.2 to 6.3);
0x5FF0 (10.0 to 1607);
0x60F0 (1703);
0x6040
LARGE_INTEGER HypercallPagePhysical;
early 6.0 only  
SLIST_HEADER HypercallPageList;
late 6.0 and higher  
0x6050
ULONGLONG *StatisticsPage;
1709 and higher previously at 0x6110
0x39D8 (early 6.0);
0x3AC0 (late 6.0);
0x4A20 (6.1);
0x5740 (6.2 to 6.3);
0x6000 (10.0 to 1607);
0x6100 (1703);
0x6080
PVOID HypercallPageVirtual;
6.0 to 6.3  
PVOID HypercallCachedPages;
10.0 and higher  
0x3AC8 (late 6.0);
0x4A28 (6.1);
0x5748 (6.2 to 6.3);
0x6008 (10.0 to 1607);
0x6108 (1703);
0x6088
PVOID VirtualApicAssist;
late 6.0 and higher  
0x3AD0 (late 6.0);
0x4A30 (6.1);
0x5750 (6.2 to 6.3);
0x6010 (10.0 to 1607);
0x6110 (1703)
ULONGLONG *StatisticsPage;
late 6.0 to 1703 next at 0x6050
0x39E0 (early 6.0);
0x3AD8 (late 6.0);
0x4A38 (6.1)
PVOID RateControl;
6.0 to 6.1  
0x39E8 (early 6.0);
0x3AE0 (late 6.0);
0x4A40 (6.1)
ULONG64 CacheProcessorMask [5];
6.0 to 6.1 next as ULONG array at 0x5800
0x3A10 (early 6.0);
0x3B08 (late 6.0);
0x4A68 (6.1);
0x5758 (6.2 to 6.3);
0x6018 (10.0 to 1607);
0x6118 (1703);
0x6090
KAFFINITY PackageProcessorSet;
6.0 only  
KAFFINITY_EX PackageProcessorSet;
6.1 and higher  
0x6138
ULONG64 PrcbPad86;
1709 and higher  
0x5800 (6.2)
ULONG CacheProcessorMask [5];
6.2 only previously as ULONG64 array at 0x4A40;
next at 0x5828
0x5800 (6.3);
0x60C0 (10.0 to 1607);
0x61C0 (1703);
0x6140
ULONG64 SharedReadyQueueMask;
6.3 and higher  
0x5808 (6.3);
0x60C8 (10.0 to 1607);
0x61C8 (1703);
0x6148
KSHARED_READY_QUEUE *SharedReadyQueue;
6.3 and higher  
0x60D0 (10.0 to 1607);
0x61D0 (1703);
0x6150
ULONG SharedQueueScanOwner;
10.0 and higher  
0x60D4 (10.0 to 1607);
0x61D4 (1703);
0x6154
ULONG ScanSiblingIndex;
10.0 and higher previously at 0x5850
0x5810 (6.3);
0x60D8 (10.0 to 1607);
0x61D8 (1703);
0x6158
ULONG64 CoreProcessorSet;
6.3 and higher previously at 0x5838
0x5828 (6.2);
0x5818 (6.3);
0x60E0 (10.0 to 1607);
0x61E0 (1703);
0x6160
ULONG64 ScanSiblingMask;
6.2 and higher  
0x5820 (6.3);
0x60E8 (10.0 to 1607);
0x61E8 (1703);
0x6168
ULONG64 LLCMask;
6.3 and higher  
0x5828 (6.3);
0x60F0 (10.0 to 1607);
0x61F0 (1703);
0x6170
ULONG64 CacheProcessorMask [5];
6.3 and higher previously at 0x5800
0x5830 (6.2);
0x5850 (6.3)
ULONG ScanSiblingIndex;
6.2 to 6.3 next at 0x60D4
0x5854 (6.3)
ULONG SharedReadyQueueOffset;
6.3 only  
0x5834 (6.2)
ULONG LLCLevel;
6.2 only  
0x3A18 (early 6.0);
0x3B10 (late 6.0);
0x4A90 (6.1);
0x5838 (6.2)
ULONG64 CoreProcessorSet;
6.0 to 6.2 last member in 6.0;
next at 0x5810
0x4A98 (6.1)
PVOID PebsIndexAddress;
6.1 only  
0x4AA0 (6.1)
ULONG64 PrcbPad93 [0x0C];
6.1 only

Again, trouble is taken to pad to a cache boundary. Some of the padding was put to use in Windows 8.

Offset Definition Versions
0x5840 (6.2);
0x5858 (6.3);
0x6118 (10.0 to 1607);
0x6218 (1703);
0x6198
PROCESSOR_PROFILE_CONTROL_AREA *ProcessorProfileControlArea;
6.2 and higher
0x5848 (6.2);
0x5860 (6.3);
0x6120 (10.0 to 1607);
0x6220 (1703);
0x61A0
PVOID ProfileEventIndexAddress;
6.2 and higher
0x6228 (1703);
0x61A8
PVOID *DpcWatchdogProfile;
1703 and higher
0x6230 (1703);
0x61B0
PVOID *DpcWatchdogProfileCurrentEmptyCapture;
1703 and higher
0x61B8
PVOID SchedulerAssist;
1709 and higher

Inserted For Windows 7

Windows 7 defines numerous performance counters for synchronisation.

Offset Definition Versions Remarks
0x4B00 (6.1)
ULONG SpinLockAcquireCount;
6.1 only cache-aligned
0x4B04 (6.1)
ULONG SpinLockContentionCount;
6.1 only  
0x4B08 (6.1)
ULONG SpinLockSpinCount;
6.1 only  
0x4B0C (6.1)
ULONG IpiSendRequestBroadcastCount;
6.1 only  
0x4B10 (6.1)
ULONG IpiSendRequestRoutineCount;
6.1 only  
0x4B14 (6.1)
ULONG IpiSendSoftwareInterruptCount;
6.1 only  
0x4B18 (6.1)
ULONG ExInitializeResourceCount;
6.1 only  
0x4B1C (6.1)
ULONG ExReInitializeResourceCount;
6.1 only  
0x4B20 (6.1)
ULONG ExDeleteResourceCount;
6.1 only  
0x4B24 (6.1)
ULONG ExecutiveResourceAcquiresCount;
6.1 only  
0x4B28 (6.1)
ULONG ExecutiveResourceContentionsCount;
6.1 only  
0x4B2C (6.1)
ULONG ExecutiveResourceReleaseExclusiveCount;
6.1 only  
0x4B30 (6.1)
ULONG ExecutiveResourceReleaseSharedCount;
6.1 only  
0x4B34 (6.1)
ULONG ExecutiveResourceConvertsCount;
6.1 only  
0x4B38 (6.1)
ULONG ExAcqResExclusiveAttempts;
6.1 only  
0x4B3C (6.1)
ULONG ExAcqResExclusiveAcquiresExclusive;
6.1 only  
0x4B40 (6.1)
ULONG ExAcqResExclusiveAcquiresExclusiveRecursive;
6.1 only  
0x4B44 (6.1)
ULONG ExAcqResExclusiveWaits;
6.1 only  
0x4B48 (6.1)
ULONG ExAcqResExclusiveNotAcquires;
6.1 only  
0x4B4C (6.1)
ULONG ExAcqResSharedAttempts;
6.1 only  
0x4B50 (6.1)
ULONG ExAcqResSharedAcquiresExclusive;
6.1 only  
0x4B54 (6.1)
ULONG ExAcqResSharedAcquiresShared;
6.1 only  
0x4B58 (6.1)
ULONG ExAcqResSharedAcquiresSharedRecursive;
6.1 only  
0x4B5C (6.1)
ULONG ExAcqResSharedWaits;
6.1 only  
0x4B60 (6.1)
ULONG ExAcqResSharedNotAcquires;
6.1 only  
0x4B64 (6.1)
ULONG ExAcqResSharedStarveExclusiveAttempts;
6.1 only  
0x4B68 (6.1)
ULONG ExAcqResSharedStarveExclusiveAcquiresExclusive;
6.1 only  
0x4B6C (6.1)
ULONG ExAcqResSharedStarveExclusiveAcquiresShared;
6.1 only  
0x4B70 (6.1)
ULONG ExAcqResSharedStarveExclusiveAcquiresSharedRecursive;
6.1 only  
0x4B74 (6.1)
ULONG ExAcqResSharedStarveExclusiveWaits;
6.1 only  
0x4B78 (6.1)
ULONG ExAcqResSharedStarveExclusiveNotAcquires;
6.1 only  
0x4B7C (6.1)
ULONG ExAcqResSharedWaitForExclusiveAttempts;
6.1 only  
0x4B80 (6.1)
ULONG ExAcqResSharedWaitForExclusiveAcquiresExclusive;
6.1 only  
0x4B84 (6.1)
ULONG ExAcqResSharedWaitForExclusiveAcquiresShared;
6.1 only  
0x4B88 (6.1)
ULONG ExAcqResSharedWaitForExclusiveAcquiresSharedRecursive;
6.1 only  
0x4B8C (6.1)
ULONG ExAcqResSharedWaitForExclusiveWaits;
6.1 only  
0x4B90 (6.1)
ULONG ExAceResSharedWaitForExclusiveNotAcquires;
6.1 only  
0x4B94 (6.1)
ULONG ExSetResOwnerPointerExclusive;
6.1 only  
0x4B98 (6.1)
ULONG ExSetResOwnerPointerSharedNew;
6.1 only  
0x4B9C (6.1)
ULONG ExSetResOwnerPointerSharedOld;
6.1 only  
0x4BA0 (6.1)
ULONG ExTryToAcqExclusiveAttempts;
6.1 only  
0x4BA4 (6.1)
ULONG ExTryToAcqExclusiveAcquires;
6.1 only  
0x4BA8 (6.1)
ULONG ExBoostExclusiveOwner;
6.1 only  
0x4BAC (6.1)
ULONG ExBoostSharedOwners;
6.1 only  
0x4BB0 (6.1)
ULONG ExEtwSynchTrackingNotificationsCount;
6.1 only  
0x4BB4 (6.1)
ULONG ExEtwSynchTrackingNotificationsAccountedCount;
6.1 only  

Windows 8 tidies all the preceding counters into one cache-aligned SYNCH_COUNTERS structure.

Offset Definition Versions Remarks
0x61C0
SYNCH_COUNTERS SynchCounters;
1709 and higher previously at 0x6280;
cache-aligned
0x5850 (6.2);
0x5858 (6.3);
0x6128 (10.0 to 1607);
0x6238 (1703);
0x6278
ULONG PrcbPad94 [6];
6.2 only  
ULONG PrcbPad94 [3];
6.3 only  
ULONG64 PrcbPad94 [0x0B];
10.0 to 1607  
ULONG64 PrcbPad94 [0x0A];
1703 only  
ULONG64 PrcbPad94;
1709 and higher  
0x5880 (6.2 to 6.3);
0x6180 (10.0 to 1607);
0x6280 (1703)
SYNCH_COUNTERS SynchCounters;
6.2 to 1703 next at 0x61C0;
cache-aligned
0x5938 (6.3);
0x6238 (10.0 to 1607);
0x6338 (1703)
ULONG64 PteBitCache;
6.3 to 1703 next at 0x62B0
0x5940 (6.3);
0x6240 (10.0 to 1607);
0x6340 (1703)
ULONG PteBitOffset;
6.3 to 1703 next at 0x62B8
0x5938 (6.2);
0x5948 (6.3);
0x6248 (10.0 to 1607);
0x6348 (1703);
0x6280
FILESYSTEM_DISK_COUNTERS FsCounters;
6.2 and higher  
0x4BB8 (6.1);
0x5948 (6.2);
0x5958 (6.3);
0x6258 (10.0 to 1607);
0x6358 (1703);
0x6290
UCHAR VendorString [0x0D];
6.1 and higher previously at 0x399C
0x4BC5 (6.1);
0x5955 (6.2);
0x5965 (6.3);
0x6265 (10.0 to 1607);
0x6365 (1703);
0x629D
UCHAR PrcbPad10 [3];
6.1 to 1607  
UCHAR PrcbPad10 [2];
1703 only  
UCHAR PrcbPad10 [3];
1709 and higher  
0x6367 (1703)
UCHAR PendingVirtualLittle;
1703 only  
0x4BC8 (6.1);
0x5958 (6.2);
0x5968 (6.3);
0x6268 (10.0 to 1607);
0x6368 (1703);
0x62A0
ULONG FeatureBits;
6.1 to 6.2 previously at 0x39AC
ULONG64 FeatureBits;
6.3 and higher
0x5970 (6.3);
0x6270 (10.0 to 1607);
0x6370 (1703)
ULONG PrcbPad11;
6.3 only  
ULONG PrcbPad110;
10.0 to 1703  
0x4BD0 (6.1);
0x5960 (6.2);
0x5978 (6.3);
0x6278 (10.0 to 1607);
0x6378 (1703);
0x62A8
LARGE_INTEGER UpdateSignature;
6.1 and higher previously at 0x39B0
0x62B0
ULONG64 PteBitCache;
1709 and higher previously at 0x6338
0x62B8 
ULONG PteBitOffset;
1709 and higher previously at 0x6340
0x62BC
ULONG PrcbPad105;
1709 and higher  
0x4BD8 (6.1);
0x5968 (6.2);
0x5980 (6.3);
0x6280 (10.0 to 1607);
0x6380 (1703);
0x62C0
CONTEXT *Context;
6.1 and higher  
0x4BE0 (6.1);
0x5970 (6.2);
0x5988 (6.3);
0x6288 (10.0 to 1607);
0x6388 (1703);
0x62C8
ULONG ContextFlags;
6.1 only  
ULONG ContextFlagsInit;
6.2 and higher  
0x62CC
ULONG PrcbPad115;
1709 and higher  
0x4BE8 (6.1);
0x5978 (6.2);
0x5990 (6.3);
0x6290 (10.0 to 1607);
0x6390 (1703);
0x62D0
XSAVE_AREA *ExtendedState;
6.1 and higher  

Inserted for Windows 8 and 8.1

Offset Definition Versions
0x5998 (6.3);
0x6298 (10.0 to 1607);
0x6398 (1703);
0x62D8
PVOID IsrStack;
6.3 and higher
0x5980 (6.2);
0x59A0 (6.3);
0x62A0 (10.0 to 1607);
0x63A0 (1703);
0x62E0
KENTROPY_TIMING_STATE EntropyTimingState;
6.2 and higher
0x6430
ULONG64 PrcbPad110;
1803 and higher
0x6438
ULONG64 PrcbPad111 [7];
1803 and higher
0x5AF0 (6.3);
0x63F0 (10.0 to 1607);
0x64F0 (1703);
0x6430 (1709);
0x6470
SINGLE_LIST_ENTRY AbSelfIoBoostsList;
6.3 and higher
0x5AF8 (6.3);
0x63F8 (10.0 to 1607);
0x64F8 (1703);
0x6438 (1709);
0x6478
SINGLE_LIST_ENTRY AbPropagateBoostsList;
6.3 and higher
0x5B00 (6.3);
0x6400 (10.0 to 1607);
0x6500 (1703);
0x6440 (1709);
0x6480
KDPC AbDpc;
6.3 and higher

Inserted For Windows 10

Offset Definition Versions Remarks
0x6440 (10.0 to 1607);
0x6540 (1703);
0x6480 (1709);
0x64C0
IOP_IRP_STACK_PROFILER IoIrpStackProfilerCurrent;
10.0 and higher  
0x6494 (10.0 to 1607);
0x6594 (1703);
0x64D4 (1709);
0x6514
IOP_IRP_STACK_PROFILER IoIrpStackProfilerPrevious;
10.0 and higher  
0x6528 (1709);
0x6568
KSECURE_FAULT_INFORMATION SecureFault;
1709 and higher previously at 0x6980
0x6538 (1709);
0x6578
ULONG64 PrcbPad120;
1709 and higher  
0x6500 (10.0 to 1607);
0x6600 (1703);
0x6540 (1709);
0x6580
KSHARED_READY_QUEUE LocalSharedReadyQueue;
10.0 and higher  
0x67B0 (1709);
0x67F0
ULONG64 PrcbPad125 [2];
1709 and higher  
0x67C0 (1709);
0x6800
ULONG TimerExpirationTraceCount;
1709 and higher previously at 0x6970
0x67C4 (1709);
0x6804
ULONG PrcbPad127;
1709 and higher  
0x6760 (10.0 to 1607);
0x6870 (1703);
0x67C8 (1709);
0x6808
KTIMER_EXPIRATION_TRACE TimerExpirationTrace [0x10];
10.0 and higher  
0x6860 (10.0 to 1607);
0x6970 (1703)
ULONG TimerExpirationTraceCount;
10.0 to 1703 next at 0x67C0
0x6868 (10.0 to 1607);
0x6978
PVOID ExSaPageArray;
10.0 to 1703 next at 0x6030
0x6980 (1703)
KSECURE_FAULT_INFORMATION SecureFault;
1703 only next at 0x6528
0x68C8 (1709);
0x6908
ULONG64 PrcbPad128 [7];
1709 and higher  

Appended for Windows 7

The mailboxes for inter-processor communications were moved to the end of the KPRCB in Windows 7 so that the array can accommodate arbitrarily many processors but still be in the KPRCB. Both the pointer and the array are cache-aligned without explicit padding in most versions.

Offset Definition Versions Remarks
0x4C00 (6.1);
0x5B00 (6.2);
0x5B40 (6.3);
0x6880 (10.0 to 1607);
0x69C0 (1703);
0x6900 (1709);
0x6940
REQUEST_MAILBOX *Mailbox;
6.1 and higher cache-aligned
0x6908 (1709);
0x6948
ULONG64 PrcbPad130 [7];
1709 and higher  
0x6980
KLOCK_QUEUE_HANDLE SelfmapLockHandle [4];
1803 and higher cache-aligned
0x69E0
UCHAR PrcbPad135 [0x04A0];
1803 and higher  
0x6E80
ULONG64 KernelDirectoryTableBase;
1803 and higher page-aligned
0x6E88
ULONG64 RspBaseShadow;
1803 and higher  
0x6E90
ULONG64 UserRspShadow;
1803 and higher  
0x6E98
ULONG ShadowFlags;
1803 and higher  
0x6E9C
ULONG PrcbPad139;
1803 and higher  
0x6EA0
ULONG64 PrcbPad140 [0x01FC];
1803 and higher  
0x4C80 (6.1);
0x5B40 (6.2);
0x5B80 (6.3);
0x68C0 (10.0 to 1607);
0x6A00 (1703);
0x6940 (1709);
0x7E80
REQUEST_MAILBOX RequestMailbox [ANYSIZE_ARRAY];
6.1 and higher previously at 0x2380;
last member in 6.1;
last member in 6.2;
last member in 6.3;
last member in 10.0;
page-aligned in 1803 and higher