CURRENT WORK ITEM - PREVIEW ONLY

RTL_USER_PROCESS_PARAMETERS

The RTL_USER_PROCESS_PARAMETERS structure (formally _RTL_USER_PROCESS_PARAMETERS) is the low-level packaging of the numerous arguments and parameters that can be specified to such Win32 API functions as CreateProcess.

By the phrase “low-level packaging” I mean very deliberately that the structure is not specifically a packaging for the transition to and from kernel mode. Ask almost anyone in the last decade or more for a potted description of the RTL_USER_PROCESS_PARAMETERS, and you can expect to hear that these are parameters that are passed from user mode to kernel mode for handling the NtCreateUserProcess and ZwCreateUserProcess functions, and that the kernel creates a copy in the created process’s address space where it is then available in user mode through the created process’s PEB. This, however, is not the history. Even now, it is not the full story. The clue is in the name, specifically in the RTL prefix.

For the first decade and more of Windows history, the RTL_USER_PROCESS_PARAMETERS structure does not cross between user and kernel modes as anything other than an uninterpreted blob that the creating process copies into the created process’s address space. The structure exists only as input to the RtlCreateUserProcess function. This Run Time Library (RTL) function is exported by name from NTDLL in all Windows versions, right from the beginning with version 3.10. It also exists in all versions of the kernel, but only as an internal routine which the kernel uses for starting the first user-mode process (and which is in a section that the kernel discards soon afterwards).

Variability

Presumably because of its role as input to an API function, albeit an undocumented one, the RTL_USER_PROCESS_PARAMETERS structure is strikingly stable. Indeed, while the RtlCreateUserProcess function was the only means of creating a user-mode process, its input structure did not change at all. Since then, the structure’s only variability is that new members are appended:

Version Size (x86) Size (x64)
3.10 to 5.2 0x0290 0x03F0
6.0 0x0294 0x03F8
6.1 0x0298 0x0400
6.2 to 6.3 0x02A0 0x0410
10.0 to 1803 0x02A4 0x0410
1809 0x02AC 0x0420
1903 0x02BC 0x0440
2004 0x02C0 0x0440

Layout

These sizes, and the offsets, names and types of members in the table below, are from Microsoft’s public symbol files for the kernel starting with Windows 2000 SP3.

For versions that predate the availability of type information in symbol files, continuity with the known definition for later versions is confirmed by inspection of the implementations and uses of RtlCreateUserProcess. For a handful of these early versions, the continuity can be established more readily. For instance, the import libraries GDISRVL.LIB and SHELL32.LIB that Microsoft supplied with the Device Driver Kit (DDK) for Windows NT 3.51 and 4.0, respectively, have an early form of type information, including for RTL_USER_PROCESS_PARAMETERS.

Offset (x86) Offset (x64) Definition Versions
0x00 0x00
ULONG MaximumLength;
all
0x04 0x04
ULONG Length;
all
0x08 0x08
ULONG Flags;
all
0x0C 0x0C
ULONG DebugFlags;
all
0x10 0x10
HANDLE ConsoleHandle;
all
0x14 0x18
ULONG ConsoleFlags;
all
0x18 0x20
HANDLE StandardInput;
all
0x1C 0x28
HANDLE StandardOutput;
all
0x20 0x30
HANDLE StandardError;
all
0x24 0x38
CURDIR CurrentDirectory;
all
0x30 0x50
UNICODE_STRING DllPath;
all
0x38 0x60
UNICODE_STRING ImagePathName;
all
0x40 0x70
UNICODE_STRING CommandLine;
all
0x48 0x80
PVOID Environment;
all
0x4C 0x88
ULONG StartingX;
all
0x50 0x8C
ULONG StartingY;
all
0x54 0x90
ULONG CountX;
all
0x58 0x94
ULONG CountY;
all
0x5C 0x98
ULONG CountCharsX;
all
0x60 0x9C
ULONG CountCharsY;
all
0x64 0xA0
ULONG FillAttribute;
all
0x68 0xA4
ULONG WindowFlags;
all
0x6C 0xA8
ULONG ShowWindowFlags;
all
0x70 0xB0
UNICODE_STRING WindowTitle;
all
0x78 0xC0
UNICODE_STRING DesktopInfo;
all
0x80 0xD0
UNICODE_STRING ShellInfo;
all
0x88 0xE0
UNICODE_STRING RuntimeData;
all
0x90 0xF0
RTL_DRIVE_LETTER_CURDIR CurrentDirectores [0x20];
all
0x0290 0x03F0
ULONG_PTR volatile EnvironmentSize;
6.0 to 6.1
ULONG_PTR EnvironmentSize;
6.2 and higher
0x0294 0x03F8
ULONG_PTR volatile EnvironmentVersion;
6.1 only
ULONG_PTR EnvironmentVersion;
6.2 and higher
0x0298 0x0400
PVOID PackageDependencyData;
6.2 and higher
0x029C 0x0408
ULONG ProcessGroupId;
6.2 and highe
0x02A0 0x040C
ULONG LoaderThreads;
10.0 and higher
0x02A4 0x0410
UNICODE_STRING RedirectionDllName;
1809 and higher
0x02AC 0x0420
UNICODE_STRING HeapPartitionName;
1903 and higher
0x02B4 0x0430
ULONGLONG *DefaultThreadpoolCpuSetMasks;
1903 and higher
0x02B8 0x0438
ULONG DefaultThreadpoolCpuSetMaskCount;
1903 and higher
0x02BC 0x043C
ULONG DefaultThreadpoolThreadMaximum;
2004 and higher

The spelling of CurrentDirectores is Microsoft’s.