SKETCH OF HOW RESEARCH MIGHT CONTINUE AND RESULTS BE PRESENTED

ESILO

The ESILO (formally _ESILO) arguably has the highest profile of all kernel-mode structures for which no type information was ever disclosed in public symbol files. Note the past tense: the ESILO is known only in the original Windows 10.

The Silo Object

The high profile is that the ESILO truly is an object in the sense of being managed by the Object Manager such that it can be exposed through a HANDLE with access rights. Indeed, this apparently seemed important enough at the time that the access rights are defined in WINNT.H for user-mode programming:

Value Name
0x00000001 SILO_OBJECT_ASSIGN_PROCESS
0x00000002 SILO_OBJECT_SET_ATTRIBUTES
0x00000004 SILO_OBJECT_QUERY
0x00000008 SILO_OBJECT_TERMINATE
0x00000010 SILO_OBJECT_SET_SECURITY_ATTRIBUTES

These definitions even persist to the WINNT.H for the 1511 release, by which time there is no silo object that can be created, opened, closed or otherwise accessed through a handle.

Even for the original release of Windows 10, the silo object’s existence was precarious. Notably, it is subordinate to the job object (represented by the EJOB structure). The only known way to create a silo object is through the JobObjectCreateSilo information class (0x23) of the NtSetInformationJobObject function. There is no input or output for this information class. It just creates a silo for the given job object to hold as its Container, not because the silo in any sense contains the job but because setting a silo object into a job object is the way that Microsoft elevates the long-standing job object from managing a collection of processes into acting like what the rest of the world had for some time been calling a container.

For some suggestion that the silo object was already on the way out even for the original Windows 10, see that the corresponding WINNT.H also defines a SILOOBJECTINFOCLASS, as if to fit the pattern of an information class to pass to native API functions that allow for querying and setting properties of the silo object. Historians who care to look may find that such functions, perhaps named something like NtQueryInformationSiloObject, exist in pre-release builds of Windows 10. What shows in the actual release is that no native API functions work with silo objects and the information classes that WINNT.H defines for SILOBOJECTINFOCLASS are already all folded into the long-standing JOBOBJECTINFOCLASS.

Layout

The ESILO is 0x98 or 0x0110 bytes in 32-bit and 64-bit Windows 10, respectively.

Offset (x86) Offset (x64) Definition Remarks
0x00 0x00 unknown KEVENT  
0x10 0x18
HANDLE SiloIdNumber;
 
0x14 0x20 unknown LIST_ENTRY links all silos;
list head is internal variable
0x1C 0x30 unknown ERESOURCE next in SILO_CONTEXT
0x54 0x98
ESILO *ParentSilo;
next in SILO_CONTEXT
0x58 0xA0 unknown LIST_ENTRY links silos that share parent;
list head is at 0x70 and 0xC8 in parent
0x60 0xB0
ULONG NumberOfChildSilos;
next in SILO_CONTEXT
0x64 0xB4
ULONG NumberOfProcesses;
 
0x68 0xB8 unknown LIST_ENTRY list head for attached processes;
links through SiloEntry in EPROCESS
0x70 0xC8 unknown LIST_ENTRY list head for child silos;
links through 0x58 and 0xA0 in children
0x78 0xD8 unknown LIST_ENTRY links structures for objects inserted into silo:
see PsInsertSiloObjectFromJob
0x80 0xE8 unknown KEVENT  
0x90 0x0100
ESERVERSILO_GLOBALS *ServerSiloGlobals;
next in SILO_CONTEXT
0x94 0x0108 unknown 32-bit flags  

For a few members, names and types are proposed above by inferring a correspondence with members of other structures for which Microsoft’s names and types are known with certainty. Notably, when the SILOOBJECT_BASIC_INFORMATION structure (defined in WINNT.H) is filled as output for the JobObjectSiloBasicInformation case of NtQueryInformationJobObject, the SiloIdNumber, NumberOfChildSilos and NumberOfProcesses are copied directly from the ESILO and it’s at least plausible that Microsoft’s programmers use the same names and types on both sides of the equals signs. Confidence can of course not be high. For some caution see that although HANDLE is natural for the silo identifier since it is allocated from a handle table, the SYSTEM_ROOT_SILO_INFORMATION that is the output from the SystemRootSiloInformation case of ZwQuerySystemInformation gets the identifier as a ULONG_PTR.