Geoff Chappell, Software Analyst
SKETCH OF HOW RESEARCH MIGHT CONTINUE AND RESULTS BE PRESENTED
The EPROCESS_QUOTA_ENTRY is the kernel’s record of a resource that is subject to a quota. It is thought to exist only in the EPROCESS_QUOTA_BLOCK, which has an array of them, one for each type of resource.
The EPROCESS_QUOTA_ENTRY is not documented. Microsoft’s names for it and for its original members are known from type information in symbol files for the kernel in Windows XP and Windows Server 2003.
Whatever may be thought from the following table of changing sizes, the EPROCESS_QUOTA_ENTRY has in some sense not changed much. There has only ever been one addition. The huge increase for version 6.1 is from cache-alignment.
Version | Size (x86) | Size (x64) |
---|---|---|
5.1 to 5.2 | 0x10 | 0x20 |
6.0 | 0x18 | 0x30 |
6.1 and higher | 0x80 | 0x80 |
In the following table of offsets and definitions, the Limit appears twice because version 6.1 swapped Limit and Peak while cache-aligning the former.
Offset (x86) | Offset (x64) | Definition | Versions | Remarks |
---|---|---|---|---|
0x00 | 0x00 |
SIZE_T Usage; |
5.1 and higher | |
0x04 (5.1 to 6.0) | 0x08 (5.2 to 6.0) |
SIZE_T Limit; |
5.1 to 6.0 | next at 0x40 |
0x08 (5.1 to 6.0); 0x04 |
0x10 (5.2 to 6.0); 0x08 |
SIZE_T Peak; |
5.1 and higher | |
0x40 | 0x40 |
SIZE_T Limit; |
6.1 and higher | previously at 0x04 and 0x08 |
0x0C (5.1 to 6.0); 0x44 |
0x18 (5.2 to 6.0); 0x48 |
SIZE_T Return; |
5.1 and higher | |
0x10 (6.0); 0x48 |
0x20 (6.0); 0x50 |
LIST_ENTRY ExpansionLink; |
6.0 and higher |
Microsoft’s name for the LIST_ENTRY is known from the KDEXTS debugger extension’s parsing of the structure for the !quota command. This member was added for version 6.0 to optimise quota expansion. Earlier versions keep all quota blocks in a global list. Version 6.0 instead has global lists of the quota entries for each resource type that supports quota expansion, i.e., the non-paged and paged pools.
Version 6.0 tracks the CPU rate as another quota type but the corresponding EPROCESS_QUOTA_ENTRY in the QuotaEntry array of the EPROCESS_QUOTA_BLOCK is modified. It is 0x30 and 0x38 bytes in 32-bit and 64-bit Windows Vista, respectively.
Offset (x86) | Offset (x64) | Definition | Versions |
---|---|---|---|
0x00 | 0x00 |
ULONGLONG Usage; |
6.0 only |
0x08 | 0x08 |
ULONGLONG Limit; |
6.0 only |
0x10 | 0x10 | unknown ULONGLONG | 6.0 only |
0x18 | 0x18 | unknown RATE_QUOTA_LIMIT | 6.0 only |
0x1C | unknown dword | 6.0 only | |
0x20 | unaccounted | 6.0 only | |
0x28 | 0x28 | unknown LIST_ENTRY | 6.0 only |
The RATE_QUOTA_LIMIT is declared in NTDDK.H, apparently to help with interpreting the QUOTA_LIMITS_EX as input and output for the ProcessQuotaLimits case of the NtSetInformationProcess and NtQueryInformationProcess functions. Note, however, that its interpretation changed significantly after version 6.0, such that the definition that is specific to version 6.0 does not survive in NTDDK.H for later versions. In all versions the RATE_QUOTA_LIMIT is a union of ULONG bit fields with a ULONG named RateData:
Mask | Definition | Versions |
---|---|---|
0x0000000F (6.0) |
ULONG RatePhase; |
6.0 only |
0xFFFFFFF0 (6.0); 0x0000007F |
ULONG RatePercent; |
6.0 and higher |
ULONG Reserved0; |
6.1 and higher |
The RatePhase takes values from the PS_RATE_PHASE enumeration: