SYSTEM_PROCESS_INFORMATION

The SYSTEM_PROCESS_INFORMATION structure is what a successful call to ZwQuerySystemInformation or NtQuerySystemInformation produces at the start of its output buffer and irregularly throughout the buffer when given the information class SystemProcessInformation (0x05), SystemExtendedProcessInformation (0x39) or SystemFullProcessInformation (0x94).

These information classes produce descriptions not just of the running processes but also of those processes’ threads. A quick summary is that the information for each process is:

The totality of the output for all processes is a sequence of these variable-size sets, one per process. In each set, the NextEntryOffset member at the beginning of the SYSTEM_PROCESS_INFORMATION tells how many bytes to advance from that SYSTEM_PROCESS_INFORMATION to the next, or is zero in the last.

Documentation Status

The SYSTEM_PROCESS_INFORMATION structure is defined in WINTERNL.H from the Software Development Kit (SDK). The definition there is greatly reduced, defining just the NextEntryOffset, UniqueProcessId, HandleCount, PeakPagefileUsage and PrivatePageCount members.

Documentation of NtQuerySystemInformation describes the SystemProcessInformation case as returning “an array of SYSTEM_PROCESS_INFORMATION structures, one for each process running in the system”, with no mention of what information lies in between.

Separate documentation of ZwQuerySystemInformation presents a SYSTEM_PROCESS_INFORMATION that differs slightly from the WINTERNL.H definition in showing the NumberOfThreads member too, again without noting the connection with information between the “documented” structures.

Layout

The SYSTEM_PROCESS_INFORMATION is 0xB8 or 0x0100 bytes in 32-bit and 64-bit Windows 10, respectively. Other versions are not yet studied methodically for this note, but it is known that the structure was originally only 0x88 bytes.

Offset (x86) Offset (x64) Definition
0x00 0x00
ULONG NextEntryOffset;
0x04 0x04
ULONG NumberOfThreads;
0x08 0x08
LARGE_INTEGER WorkingSetPrivateSize;
0x10 0x10
ULONG HardFaultCount;
0x14 0x14
ULONG NumberOfThreadsHighWatermark;
0x18 0x18
ULONGLONG CycleTime;
0x20 0x20
LARGE_INTEGER CreateTime;
0x28 0x28
LARGE_INTEGER UserTime;
0x30 0x30
LARGE_INTEGER KernelTime;
0x38 0x38
UNICODE_STRING ImageName;
0x40 0x48
LONG BasePriority;
0x44 0x50
PVOID UniqueProcessId;
0x48 0x58
PVOID InheritedFromUniqueProcessId;
0x4C 0x60
ULONG HandleCount;
0x50 0x64
ULONG SessionId;
0x54 0x68
ULONG_PTR UniqueProcessKey;
0x58 0x70
ULONG_PTR PeakVirtualSize;
0x5C 0x78
ULONG_PTR VirtualSize;
0x60 0x80
ULONG PageFaultCount;
0x64 0x88
ULONG_PTR PeakWorkingSetSize;
0x68 0x90
ULONG_PTR WorkingSetSize;
0x6C 0x98
ULONG_PTR QuotaPeakPagedPoolUsage;
0x70 0xA0
ULONG_PTR QuotaPagedPoolUsage;
0x74 0xA8
ULONG_PTR QuotaPeakNonPagedPoolUsage;
0x78 0xB0
ULONG_PTR QuotaNonPagedPoolUsage;
0x7C 0xB8
ULONG_PTR PagefileUsage;
0x80 0xC0
ULONG_PTR PeakPagefileUsage;
0x84 0xC8
ULONG_PTR PrivatePageCount;
0x88 0xD0
LARGE_INTEGER ReadOperationCount;
0x90 0xD8
LARGE_INTEGER WriteOperationCount;
0x98 0xE0
LARGE_INTEGER OtherOperationCount;
0xA0 0xE8
LARGE_INTEGER ReadTransferCount;
0xA8 0xF0
LARGE_INTEGER WriteTransferCount;
0xB0 0xF8
LARGE_INTEGER OtherTransferCount;

Variable-Size Data

Some of the members are specially important to the process’s description beyond the SYSTEM_PROCESS_INFORMATION.

Immediately following the SYSTEM_PROCESS_INFORMATION is an array of zero or more SYSTEM_THREAD_INFORMATION structures if the information class is SystemProcessInformation, else SYSTEM_EXTENDED_THREAD_INFORMATION structures. Either way, the NumberOfThreads member tells how many.

The process’s name may be present as a null-terminated Unicode string. Its address and size are in the ImageName member. This is the full name if the information class is SystemFullProcessInformation. For the older information classes, this name is an extract, beginning after the last backslash.

Information Class Variations

The UniqueProcessKey is undefined for SystemProcessInformation. For the newer information classes it is set identically with UniqueProcessId.