SYSTEM_LOOKASIDE_INFORMATION

An array of SYSTEM_LOOKASIDE_INFORMATION structures is what a successful call to ZwQuerySystemInformation or NtQuerySystemInformation produces in its output buffer when given the information class SystemLookasideInformation (0x2D). Each structure describes one of the kernel’s typically very many lookaside lists.

Documentation Status

The SYSTEM_LOOKASIDE_INFORMATION structure is defined in WINTERNL.H from the Software Development Kit (SDK). The definition there has the whole structure as one array of bytes, named Reserved1. Documentation of NtQuerySystemInformation describes the structure as “opaque” and suggests that whatever is produced in it for the SystemLookasideInformation case “can be used to generate an unpredictable seed for a random number generator.”

An irony about the documentation’s reluctance to say much is that what little it does say is even more unhelpful than it might at first seem. The caller who is not told that the function can produce an array of these structures will, unsurprisingly, not to think to provide an information buffer that can receive more than one structure. Indeed, the documentation talks only in the singular. What gets produced for this one structure is in practice utterly useless as the supposed “unpredictable seed” because it will almost always be exactly the same—not just from time to time but even on different computers. The reason is that the enumeration begins with a lookaside list for optimising non-paged pool allocations of up to eight bytes (and specifically then by code that runs on the boot processor), and these are so rare that this lookaside list typically shows no activity since its initialisation.

Layout

The SYSTEM_LOOKASIDE_INFORMATION is 0x20 bytes in 32-bit and 64-bit Windows.

Offset Definition
0x00
USHORT CurrentDepth;
0x02
USHORT MaximumDepth;
0x04
ULONG TotalAllocates;
0x08
ULONG AllocateMisses;
0x0C
ULONG TotalFrees;
0x10
ULONG FreeMisses;
0x14
ULONG Type;
0x18
ULONG Tag;
0x1C
ULONG Size;

Though the members are mostly just copied from corresponding members in the lookaside list (whose layout is documented), some interpretation does occur. The reported CurrentDepth is in fact the Depth from the SLIST_HEADER that acts as the lookaside list’s cache. Confusingly, the MaximumDepth in the information is not the MaximumDepth from the lookaside list itself but just its plain Depth.

The lookaside lists that optimise pool allocations are worked on only by the Executive’s code for pool management and have the slightly different implementation of counting AllocateHits and FreeHits where other lookaside lists count AllocateMisses and FreeMisses. For these lists, the “misses” counts in the information are computed by subtracting the hits from the totals.

For the general lookaside lists, as initialised by exported functions such as ExInitializeLookasideEx, the reported Type is specifically NonPagedPool or PagedPool. Put another way, other bits that may have been specified for the pool type are not disclosed. This seems now like it must be an oversight, but it may have been deliberate in the days when the ExInitializeNPagedLookasideList and ExInitializePagedLookasideList functions were documented as requiring that their Flags argument be zero.