In computing the Process Environment Block (abbreviated PEB) is a data structure in the Windows NT operating system family. It is an opaque data structure that is used by the operating system internally, most of whose fields are not intended for use by anything other than the operating system.[1] Microsoft notes, in its MSDN Library documentation — which documents only a few of the fields — that the structure "may be altered in future versions of Windows".[2] The PEB contains data structures that apply across a whole process, including global context, startup parameters, data structures for the program image loader, the program image base address, and synchronization objects used to provide mutual exclusion for process-wide data structures.[1]
The PEB is closely associated with the kernel mode EPROCESS
data structure, as well as with per-process data structures managed within the address space of the Client-Server Runtime Sub-System process. However, (like the CSRSS data structures) the PEB is not a kernel mode data structure itself. It resides in the application mode address space of the process that it relates to. This is because it is designed to be used by the application-mode code in the operating system libraries, such as NTDLL, that executes outside of kernel mode, such as the code for the program image loader and the heap manager.[3]
In WinDbg, the command that dumps the contents of a PEB is the !peb
command, which is passed the address of the PEB within a process' application address space. That information, in turn, is obtained by the !process
command, which displays the information from the EPROCESS
data structure, one of whose fields is the address of the PEB.[3]
Field | meaning | notes |
---|---|---|
BeingDebugged |
Whether the process is being debugged | Microsoft recommends not using this field but using the official Win32 CheckRemoteDebuggerPresent() library function instead.[2]
|
Ldr | A pointer to a PEB_LDR_DATA structure providing information about loaded modules |
Contains the base address of kernel32 and ntdll. |
ProcessParameters | A pointer to a RTL_USER_PROCESS_PARAMETERS structure providing information about process startup parameters |
The RTL_USER_PROCESS_PARAMETERS structure is also mostly opaque and not guaranteed to be consistent across multiple versions of Windows.[4]
|
PostProcessInitRoutine | A pointer to a callback function called after DLL initialization but before the main executable code is invoked | This callback function is used on Windows 2000, but is not guaranteed to be used on later versions of Windows NT.[2] |
SessionId | The session ID of the Terminal Services session that the process is part of | The NtCreateUserProcess() system call initializes this by calling the kernel's internal MmGetSessionId() function.[3]
|
The contents of the PEB are initialized by the NtCreateUserProcess()
system call, the Native API function that implements part of, and underpins, the Win32 CreateProcess()
, CreateProcessAsUser()
, CreateProcessWithTokenW()
, and CreateProcessWithLogonW()
library functions that are in the kernel32.dll and advapi32.dll libraries as well as underpinning the fork()
function in the Windows NT POSIX library, posix.dll.[3]
For Windows NT POSIX processes, the contents of a new process' PEB are initialized by NtCreateUserProcess()
as simply a direct copy of the parent process' PEB, in line with how the fork()
function operates. For Win32 processes, the initial contents of a new process' PEB are mainly taken from global variables maintained within the kernel. However, several fields may instead be taken from information provided within the process' image file, in particular information provided in the IMAGE_OPTIONAL_HEADER32
data structure within the PE file format (PE+ or PE32+ in 64 bit executable images).[3]
Field | is initialized from | overridable by PE information? |
---|---|---|
NumberOfProcessors |
KeNumberOfProcessors |
No |
NtGlobalFlag |
NtGlobalFlag |
No |
CriticalSectionTimeout |
MmCriticalSectionTimeout |
No |
HeapSegmentReserve |
MmHeapSegmentReserve |
No |
HeapSegmentCommit |
MmHeapSegmentCommit |
No |
HeapDeCommitTotalFreeThreshold |
MmHeapDeCommitTotalFreeThreshold |
No |
HeapDeCommitFreeBlockThreshold |
MmHeapDeCommitFreeBlockThreshold |
No |
MinimumStackCommit |
MmMinimumStackCommitInBytes |
No |
ImageProcessAffinityMask |
KeActiveProcessors |
ImageLoadConfigDirectory.ProcessAffinityMask
|
OSMajorVersion |
NtMajorVersion |
OptionalHeader.Win32VersionValue & 0xFF
|
OSMinorVersion |
NtMinorVersion |
(OptionalHeader.Win32VersionValue >> 8) & 0xFF
|
OSBuildNumber |
NtBuildNumber & 0x3FFF combined with CmNtCSDVersion |
(OptionalHeader.Win32VersionValue >> 16) & 0x3FFF combined with ImageLoadConfigDirectory.CmNtCSDVersion
|
OSPlatformId |
VER_PLATFORM_WIN32_NT |
(OptionalHeader.Win32VersionValue >> 30) ^ 0x2
|
The WineHQ project provides a fuller PEB definition in its version of winternl.h.[5] Later versions of Windows have adjusted the number and purpose of some fields.[6]
Nagar1997
was invoked but never defined (see the help page).MSDN1
was invoked but never defined (see the help page).Internals5
was invoked but never defined (see the help page).MSDN3
was invoked but never defined (see the help page).