//
// [TEB/PEB/SEH SUMMARY]
// This file contains the undocumented TEB (Thread Environment Block) and PEB (Process Environment Block)
// definitions for the Intel x86 32-bit Windows operating systems starting from NT 3.51 through Windows 10. The TEB
// is also known as the TIB (Thread Information Block), especially under the Windows 9.x operating systems.
//
// Additionally I have added the definitions for the partially documented Win32 SEH (Structured Exception Handling)
// that are not only referenced by the TEB, but are normally strewn across both C headers and assembler includes.
// These definitions also include the constants specific to the Visual C++ compiler's implementation of Win32
// SEH beyond the facilities provided by the Windows operating systems. The TEB and PEB are declared near the
// bottom of this file, with all referenced structures recursively defined above them for completeness sake.
//
// Should you be writing low level code, you might find all of these definitions in one spot a handy reference. If
// you wanted to use this C header file in your own code, you'd probably want to remove the redundant definitions
// (almost all except for the TEB and PEB structures) as they are defined automatically as a result of including
// windows.h. If you won't be including windows.h or are compiling with GCC under Linux, no changes are
// necessary.
//
// [WINDOWS COMPATIBILITY]
// Both the TEB and PEB structures support Windows NT 3.51 thru Windows 10
//
// [HOW TO ACCESS THESE STRUCTURES]
// The pointers to these structures can be obtained using the following x86 assembly code:
// mov eax, fs:[18h] //eax = TEB
// mov eax, fs:[30h] //eax = PEB
//
// Or, by using the following Visual C++ compiler intrinsics:
// void* pTeb = __readfsdword(0x18);
// void* pPeb = __readfsdword(0x30);
//
// [BUGS]
// This header file is meant mostly for documentation purposes as an alternative to the various tables found
// online; therefore it may contain bugs such that certain members might not be at the offsets stated in the
// comments because I may have forgotten to pad prior members so that everything lines up. However, I did attempt
// to have all the members line up as documented by each member's offset (see comment to right of each member), so
// please report any bugs or additions to: http://bytepointer.com/contact.htm
//
// [STYLE USED IN THIS FILE]
// I modified the structures included in this file either from the original official forms found in the Windows
// headers or from various sources online, although the result is functionally equivalent. The modifications were
// made according to the following scheme for simplicity and clarity:
//
// - array size values are in hex (base-16)
//
// - I avoided creating extraneous pointer types either standalone or as part of the trailing portions of structure
// definitions. These take the format Pxxxx where xxxx is the type. Microsoft has historically declared Pxxxx
// definitions for practically every Windows structure in place of the type identifier with a trailing asterisk.
// I've always found the trailing asterisk signifying a pointer type to be clearer than the Pxxxx alternative
// because you can quickly spot them at a glance (especially when syntax hilighting kicks in).
//
// - Windows headers use many aliases for 8, 16, 32 and 64-bit values (UCHAR, ULONG, ULONG_PTR, LONG, LONGLONG, etc.)
// which are inconsistent at times. I tend to prefer the explicitly specific assembler names: BYTE, WORD, DWORD and
// QWORD as they are more platform independent names for unsigned values. Because I don't feel like the signed
// integer types consisting of the term LONG (especially the recursive LONGLONG) don't convey size well, I avoid
// using them. My naming scheme is therefore:
//
// BYTE-SIZE 1 2 4 8
// unsigned integer types: BYTE, WORD, DWORD and QWORD
// signed integer types: CHAR, INT16, INT32 and INT64
//
// NOTE: void* and DWORD may be used interchangeably on 32-bit operating systems, however I attempted
// to use void* (or typed structure pointer where possible) where I was sure the member was to
// hold a pointer. Otherwise and where members were to hold padding ints (of any size), I
// avoided the use of pointer types even when originally declared to be of type PVOID. Also I
// retained the use of some aliases, such as BOOLEAN, NTSTATUS, HANDLE, etc. only for the
// purpose of preserving the meaning of the associated structure members.
//
// [MICROSOFT FIRST DOCUMENTS THE TEB and PEB]
// Starting with the release of Visual Studio .NET (2002), Microsoft released a new header, winternl.h
// with the Platform SDK. Within this new header was the first public documentation for the TEB and PEB.
// Microsoft, being legally forced to disclose this information, only released 2 members of the PEB
// (BeingDebugged,SessionId) and 3 members of the TEB (TlsSlots,ReservedForOle,TlsExpansionSlots).
// The original portion of the winternl.h header file is shown below along with Microsoft's usual stern
// warnings about not using these fields because Windows might change.
//
// //
// // The PEB and TEB structures are subject to changes between Windows
// // releases, thus the fields offsets may change as well as the Reserved
// // fields. The Reserved fields are reserved for use only by the Windows
// // operating systems. Do not assume a maximum size for the structures.
// //
//
// // Instead of using the BeingDebugged field, use the Win32 APIs
// // IsDebuggerPresent, CheckRemoteDebuggerPresent
// // Instead of using the SessionId field, use the Win32 APIs
// // GetCurrentProcessId and ProcessIdToSessionId
// // Sample x86 assembly code that gets the SessionId (subject to change
// // between Windows releases, use the Win32 APIs to make your application
// // resilient to changes)
// // mov eax,fs:[00000018]
// // mov eax,[eax+0x30]
// // mov eax,[eax+0x1d4]
// //
// typedef struct _PEB {
// BYTE Reserved1[2];
// BYTE BeingDebugged;
// BYTE Reserved2[229];
// PVOID Reserved3[59];
// ULONG SessionId;
// } PEB, *PPEB;
//
// // Instead of using the Tls fields, use the Win32 TLS APIs
// // TlsAlloc, TlsGetValue, TlsSetValue, TlsFree
// //
// // Instead of using the ReservedForOle field, use the COM API
// // CoGetContextToken
// //
// typedef struct _TEB {
// BYTE Reserved1[1952];
// PVOID Reserved2[412];
// PVOID TlsSlots[64];
// BYTE Reserved3[8];
// PVOID Reserved4[26];
// PVOID ReservedForOle; // Windows 2000 only
// PVOID Reserved5[4];
// PVOID TlsExpansionSlots;
// } TEB;
// typedef TEB *PTEB;
//
// [REFERENCES]
// The information below was compiled from various sources:
// http://www.geoffchappell.com/studies/windows/win32/ntdll/structs/teb/index.htm
// http://www.geoffchappell.com/studies/windows/win32/ntdll/structs/peb/index.htm
// http://terminus.rewolf.pl/terminus/structures/ntdll/_TEB32_x86.html
// https://en.wikipedia.org/wiki/Win32_Thread_Information_Block
// http://www.nirsoft.net/kernel_struct/vista/index.html
// Microsoft's Platform SDK headers / MSDN
//
// [CHANGELIST]
// 2020-05-30: -bugfix: removed implied pointer ("*") from exception handler function typedefs
//
// 2020-05-11: -added #ifdef-#undef's for CONTEXT_i386, CONTEXT_i486, and EXCEPTION_CONTINUE_EXECUTION for Win10 SDK compatibility
//
// 2018-10-23: -bugfix: PEB_LDR_DATA struct had "Initialized" member as one BYTE instead of array of 4 BYTE's; also added offsets
//
// 2018-09-17: -extended PEB for some Win10 members: TppWorkerpListLock, TppWorkerpList, WaitOnAddressHashTable
//
// 2018-04-14: -offset 0x3 into PEB structure contained a byte bitfield whose last member (SpareBits) erroneously used two bits instead of one;
// this caused the bitfield to occupy an extra byte to fit 9 bits; this member has been fixed and now occupies 1 bit.
// credit: Chris Eagle
//
// 2018-05-02: -now can be compiled alongside windows.h (without changes) or by defining WANT_ALL_WINDOWS_H_DEFINITIONS so this file can be used standalone
// -this file may also be included alongside tebpeb64.h which can be found at http://bytepointer.com/resources/tebpeb64.h
// -increased PEB size to 0x258 for [at least] Windows 10: member addition dwSystemCallMode at offset 0x254
// REFERENCE: https://www.malwaretech.com/2015/07/windows-10-system-call-stub-changes.html
//
// 2017-07-29: initial public release (first stable version)
//
//disable some Visual C++ warnings
#ifdef _MSC_VER
//when compiling as C
#pragma warning (disable:4214) //Warning Level 4: C4214: nonstandard extension used : bit field types other than int
//"#pragma pack(1)" not needed as Microsoft has designed all structure members to be on natural boundaries
#ifndef STDCALL
#define STDCALL __stdcall
#endif
#ifndef CDECL
#define CDECL __cdecl
#endif
#else
//assume GCC
#ifndef STDCALL
#define STDCALL __attribute__ ((stdcall))
#endif
#ifndef CDECL
#define CDECL __attribute__ ((cdecl))
#endif
#endif
//UNCOMMENT line below if you are not including windows.h
//#define WANT_ALL_WINDOWS_H_DEFINITIONS
#ifdef WANT_ALL_WINDOWS_H_DEFINITIONS
//
// Base types
//
typedef unsigned char BYTE;
typedef char CHAR;
typedef unsigned short WORD;
typedef short INT16;
typedef unsigned long DWORD;
typedef long INT32;
typedef BYTE BOOLEAN;
typedef void* HANDLE;
typedef WORD WCHAR;
typedef DWORD LCID;
typedef DWORD KAFFINITY;
#endif //#ifdef WANT_ALL_WINDOWS_H_DEFINITIONS
//always declare NTSTATUS and 64-bit types
typedef INT32 NTSTATUS;
#ifdef _MSC_VER
//Visual C++
typedef unsigned __int64 QWORD;
typedef __int64 INT64;
#else
//GCC
typedef unsigned long long QWORD;
typedef long long INT64;
#endif
#ifdef WANT_ALL_WINDOWS_H_DEFINITIONS
//
// General-purpose structures
//
typedef union _LARGE_INTEGER
{
struct
{
DWORD LowPart;
INT32 HighPart;
} u;
INT64 QuadPart;
} LARGE_INTEGER;
typedef union _ULARGE_INTEGER
{
struct
{
DWORD LowPart;
DWORD HighPart;
} u;
QWORD QuadPart;
} ULARGE_INTEGER;
typedef struct _GUID
{
DWORD Data1;
WORD Data2;
WORD Data3;
BYTE Data4[8];
} GUID;
typedef struct LIST_ENTRY LIST_ENTRY;
struct LIST_ENTRY
{
LIST_ENTRY* Flink;
LIST_ENTRY* Blink;
};
typedef struct RTL_CRITICAL_SECTION RTL_CRITICAL_SECTION;
typedef struct _RTL_CRITICAL_SECTION_DEBUG
{
WORD Type;
WORD CreatorBackTraceIndex;
RTL_CRITICAL_SECTION* CriticalSection;
LIST_ENTRY ProcessLocksList;
DWORD EntryCount;
DWORD ContentionCount;
DWORD Flags;
WORD CreatorBackTraceIndexHigh;
WORD SpareUSHORT;
} RTL_CRITICAL_SECTION_DEBUG;
struct RTL_CRITICAL_SECTION
{
RTL_CRITICAL_SECTION_DEBUG* DebugInfo;
INT32 LockCount;
INT32 RecursionCount;
HANDLE OwningThread;
HANDLE LockSemaphore;
DWORD SpinCount;
};
#endif //WANT_ALL_WINDOWS_H_DEFINITIONS
typedef struct _CLIENT_ID
{
DWORD ProcessId;
DWORD ThreadId;
} CLIENT_ID;
typedef struct _PROCESSOR_NUMBER
{
WORD Group;
BYTE Number;
BYTE Reserved;
} PROCESSOR_NUMBER;
typedef struct _STRING
{
WORD Length;
WORD MaximumLength;
CHAR* Buffer;
} STRING;
typedef struct _UNICODE_STRING
{
WORD Length;
WORD MaximumLength;
WCHAR* Buffer;
} UNICODE_STRING;
//
// Exception-specific structures and definitions
//
#ifdef CONTEXT_i386
#undef CONTEXT_i386
#endif
#ifdef CONTEXT_i486
#undef CONTEXT_i486
#endif
//context flags
#define CONTEXT_i386 0x00010000 // this assumes that i386 and
#define CONTEXT_i486 0x00010000 // i486 have identical context records
#define CONTEXT_CONTROL (CONTEXT_i386 | 0x00000001L) // SS:SP, CS:IP, FLAGS, BP
#define CONTEXT_INTEGER (CONTEXT_i386 | 0x00000002L) // AX, BX, CX, DX, SI, DI
#define CONTEXT_SEGMENTS (CONTEXT_i386 | 0x00000004L) // DS, ES, FS, GS
#define CONTEXT_FLOATING_POINT (CONTEXT_i386 | 0x00000008L) // 387 state
#define CONTEXT_DEBUG_REGISTERS (CONTEXT_i386 | 0x00000010L) // DB 0-3,6,7
#define CONTEXT_EXTENDED_REGISTERS (CONTEXT_i386 | 0x00000020L) // cpu specific extensions
#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS)
#define CONTEXT_ALL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS | CONTEXT_EXTENDED_REGISTERS)
//exception flags
#define EXCEPTION_NONCONTINUABLE 0x1 // Noncontinuable exception
#define EXCEPTION_UNWINDING 0x2 // Unwind is in progress; same as EH_UNWINDING
#define EXCEPTION_EXIT_UNWIND 0x4 // Exit unwind is in progress; same as EH_EXIT_UNWIND
#define EXCEPTION_STACK_INVALID 0x8 // Stack out of limits or unaligned
#define EXCEPTION_NESTED_CALL 0x10 // Nested exception handler call
#define EXCEPTION_TARGET_UNWIND 0x20 // Target unwind in progress
#define EXCEPTION_COLLIDED_UNWIND 0x40 // Collided exception handler call
#define EXCEPTION_UNWIND (EXCEPTION_UNWINDING | EXCEPTION_EXIT_UNWIND | EXCEPTION_TARGET_UNWIND | EXCEPTION_COLLIDED_UNWIND)
#define IS_UNWINDING(Flag) ((Flag & EXCEPTION_UNWIND) != 0)
#define IS_DISPATCHING(Flag) ((Flag & EXCEPTION_UNWIND) == 0)
#define IS_TARGET_UNWIND(Flag) (Flag & EXCEPTION_TARGET_UNWIND)
//msvc exception filter expression return codes
#ifdef EXCEPTION_CONTINUE_EXECUTION
#undef EXCEPTION_CONTINUE_EXECUTION
#endif
#define EXCEPTION_EXECUTE_HANDLER 1 //same as FILTER_ACCEPT
#define EXCEPTION_CONTINUE_SEARCH 0 //same as FILTER_CONTINUE_SEARCH
#define EXCEPTION_CONTINUE_EXECUTION -1 //same as FILTER_DISMISS
#ifdef WANT_ALL_WINDOWS_H_DEFINITIONS
//exception handler (disposition) return values
typedef enum _EXCEPTION_DISPOSITION
{
ExceptionContinueExecution, //0; same as DISPOSITION_DISMISS, _XCPT_CONTINUE_EXECUTION
ExceptionContinueSearch, //1; same as DISPOSITION_CONTINUE_SEARCH, _XCPT_CONTINUE_SEARCH
ExceptionNestedException, //2; same as DISPOSITION_NESTED_EXCEPTION
ExceptionCollidedUnwind //3; same as DISPOSITION_COLLIDED_UNWIND
} EXCEPTION_DISPOSITION;
#define EXCEPTION_MAXIMUM_PARAMETERS 15
typedef struct EXCEPTION_RECORD EXCEPTION_RECORD;
struct EXCEPTION_RECORD //size=0x50
{
DWORD ExceptionCode; //0x00
DWORD ExceptionFlags; //0x04 - see possible values above
EXCEPTION_RECORD* ExceptionRecord; //0x08
void* ExceptionAddress; //0x0C
DWORD NumberParameters; //0x10
DWORD ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS]; //0x14
};
#define SIZE_OF_80387_REGISTERS 80
typedef struct _FLOATING_SAVE_AREA //size=0x70
{
DWORD ControlWord; //0x00
DWORD StatusWord; //0x04
DWORD TagWord; //0x08
DWORD ErrorOffset; //0x0C
DWORD ErrorSelector; //0x10
DWORD DataOffset; //0x14
DWORD DataSelector; //0x18
BYTE RegisterArea[SIZE_OF_80387_REGISTERS]; //0x1C
DWORD Cr0NpxState; //0x6C
} FLOATING_SAVE_AREA;
#define MAXIMUM_SUPPORTED_EXTENSION 512
typedef struct _CONTEXT //size=0x2CC
{
//determines which groups of members are valid
DWORD ContextFlags; //0x00 - see possible values above
//following member group valid when CONTEXT_DEBUG_REGISTERS set
DWORD Dr0; //0x04
DWORD Dr1; //0x08
DWORD Dr2; //0x0C
DWORD Dr3; //0x10
DWORD Dr6; //0x14
DWORD Dr7; //0x18
//following member valid when CONTEXT_FLOATING_POINT set
FLOATING_SAVE_AREA FloatSave; //0x1C
//following member group valid when CONTEXT_SEGMENTS set
DWORD SegGs; //0x8C
DWORD SegFs; //0x90
DWORD SegEs; //0x94
DWORD SegDs; //0x98
//following member group valid when CONTEXT_INTEGER set
DWORD Edi; //0x9C
DWORD Esi; //0xA0
DWORD Ebx; //0xA4
DWORD Edx; //0xA8
DWORD Ecx; //0xAC
DWORD Eax; //0xB0
//following member group valid when CONTEXT_CONTROL set
DWORD Ebp; //0xB4
DWORD Eip; //0xB8
DWORD SegCs; //0xBC
DWORD EFlags; //0xC0
DWORD Esp; //0xC4
DWORD SegSs; //0xC8
//following member valid when CONTEXT_EXTENDED_REGISTERS set
BYTE ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION]; //0xCC
} CONTEXT;
//used with UnhandledExceptionFilter()/SetUnhandledExceptionFilter() and newer Vectored Exception handling functions
typedef struct _EXCEPTION_POINTERS
{
EXCEPTION_RECORD* ExceptionRecord;
CONTEXT* ContextRecord;
} EXCEPTION_POINTERS;
#endif //WANT_ALL_WINDOWS_H_DEFINITIONS
typedef struct EXCEPTION_REGISTRATION EXCEPTION_REGISTRATION;
//dispatcher context is reserved for exception handler implementation (e.g. compilers)
typedef struct _DISPATCHER_CONTEXT
{
EXCEPTION_REGISTRATION* RegistrationPointer;
} DISPATCHER_CONTEXT;
//exception handler signatures
typedef EXCEPTION_DISPOSITION (CDECL ExceptionHandler)(EXCEPTION_RECORD* ExceptionRecord, EXCEPTION_REGISTRATION* EstablisherFrame, CONTEXT* ContextRecord, DISPATCHER_CONTEXT* DispatcherContext); //same as EXCEPTION_ROUTINE and _except_handler
typedef INT32 (STDCALL TopLevelExceptionFilter)(EXCEPTION_POINTERS* ExceptionInfo); //same as TOP_LEVEL_EXCEPTION_FILTER for SetUnhandledExceptionFilter();
typedef INT32 (STDCALL VectoredExceptionHandler)(EXCEPTION_POINTERS* ExceptionInfo); //same as PVECTORED_EXCEPTION_HANDLER and above signature used with AddVectoredExceptionHandler(), RemoveVectoredExceptionHandler() for XP/WS03 and up
//stack exception frame a.k.a. EXCEPTION_REGISTRATION_RECORD
struct EXCEPTION_REGISTRATION
{
EXCEPTION_REGISTRATION* prev;
ExceptionHandler* handler;
};
#define EXCEPTION_CHAIN_END ((EXCEPTION_REGISTRATION*)-1)
//
// PEB-specific structures
//
//forward declarations for unknown structures
typedef struct _ACTIVATION_CONTEXT_DATA {void* dummy;} ACTIVATION_CONTEXT_DATA; //XP and up
typedef struct _ASSEMBLY_STORAGE_MAP {void* dummy;} ASSEMBLY_STORAGE_MAP; //XP and up
typedef struct _FLS_CALLBACK_INFO {void* dummy;} FLS_CALLBACK_INFO; //WS03 and up
typedef struct _RTL_DRIVE_LETTER_CURDIR
{
WORD Flags;
WORD Length;
DWORD TimeStamp;
STRING DosPath;
} RTL_DRIVE_LETTER_CURDIR;
typedef struct _PEB_LDR_DATA
{
DWORD Length; //0x00
BYTE Initialized[4]; //0x04
void* SsHandle; //0x08
LIST_ENTRY InLoadOrderModuleList; //0x0C
LIST_ENTRY InMemoryOrderModuleList; //0x14
LIST_ENTRY InInitializationOrderModuleList; //0x1C
void* EntryInProgress; //0x24
} PEB_LDR_DATA;
typedef struct PEB_FREE_BLOCK PEB_FREE_BLOCK;
struct PEB_FREE_BLOCK
{
PEB_FREE_BLOCK* Next;
DWORD Size;
};
typedef struct _RTL_USER_PROCESS_PARAMETERS
{
DWORD MaximumLength; //0x00
DWORD Length; //0x04
DWORD Flags; //0x08
DWORD DebugFlags; //0x0C
void* ConsoleHandle; //0x10
DWORD ConsoleFlags; //0x14
HANDLE StdInputHandle; //0x18
HANDLE StdOutputHandle; //0x1C
HANDLE StdErrorHandle; //0x20
UNICODE_STRING CurrentDirectoryPath; //0x24
HANDLE CurrentDirectoryHandle; //0x2C
UNICODE_STRING DllPath; //0x30
UNICODE_STRING ImagePathName; //0x38
UNICODE_STRING CommandLine; //0x40
void* Environment; //0x48
DWORD StartingPositionLeft; //0x4C
DWORD StartingPositionTop; //0x50
DWORD Width; //0x54
DWORD Height; //0x58
DWORD CharWidth; //0x5C
DWORD CharHeight; //0x60
DWORD ConsoleTextAttributes; //0x64
DWORD WindowFlags; //0x68
DWORD ShowWindowFlags; //0x6C
UNICODE_STRING WindowTitle; //0x70
UNICODE_STRING DesktopName; //0x78
UNICODE_STRING ShellInfo; //0x80
UNICODE_STRING RuntimeData; //0x88
RTL_DRIVE_LETTER_CURDIR DLCurrentDirectory[0x20]; //0x90
} RTL_USER_PROCESS_PARAMETERS;
//
// PEB (Process Environment Block) 32-bit
//
// The size of this structure is OS dependent:
// 0x0098 NT 3.51
// 0x0150 NT 4.0
// 0x01E8 Win2k
// 0x020C XP
// 0x0230 WS03
// 0x0238 Vista
// 0x0240 Win7_BETA
// 0x0248 Win6
// 0x0250 Win8
// 0x045C Win10
//
typedef struct _PEB
{
BOOLEAN InheritedAddressSpace; //0x0000
BOOLEAN ReadImageFileExecOptions; //0x0001
BOOLEAN BeingDebugged; //0x0002
union
{
BOOLEAN SpareBool; //0x0003 (NT3.51-late WS03)
struct
{
BYTE ImageUsesLargePages : 1; //0x0003:0 (WS03_SP1+)
BYTE IsProtectedProcess : 1; //0x0003:1 (Vista+)
BYTE IsLegacyProcess : 1; //0x0003:2 (Vista+)
BYTE IsImageDynamicallyRelocated : 1; //0x0003:3 (Vista+)
BYTE SkipPatchingUser32Forwarders : 1; //0x0003:4 (Vista_SP1+)
BYTE IsPackagedProcess : 1; //0x0003:5 (Win8_BETA+)
BYTE IsAppContainer : 1; //0x0003:6 (Win8_RTM+)
BYTE SpareBit : 1; //0x0003:7
} bits;
} byte3;
HANDLE Mutant; //0x0004
void* ImageBaseAddress; //0x0008
PEB_LDR_DATA* Ldr; //0x000C (all loaded modules in process)
RTL_USER_PROCESS_PARAMETERS* ProcessParameters; //0x0010
void* SubSystemData; //0x0014
void* ProcessHeap; //0x0018
RTL_CRITICAL_SECTION* FastPebLock; //0x001C
union
{
void* FastPebLockRoutine; //0x0020 (NT3.51-Win2k)
void* SparePtr1; //0x0020 (early WS03)
void* AtlThunkSListPtr; //0x0020 (late WS03+)
} dword20;
union
{
void* FastPebUnlockRoutine; //0x0024 (NT3.51-XP)
void* SparePtr2; //0x0024 (WS03)
void* IFEOKey; //0x0024 (Vista+)
} dword24;
union
{
DWORD EnvironmentUpdateCount; //0x0028 (NT3.51-WS03)
struct
{
DWORD ProcessInJob : 1; //0x0028:0 (Vista+)
DWORD ProcessInitializing : 1; //0x0028:1 (Vista+)
DWORD ProcessUsingVEH : 1; //0x0028:2 (Vista_SP1+)
DWORD ProcessUsingVCH : 1; //0x0028:3 (Vista_SP1+)
DWORD ProcessUsingFTH : 1; //0x0028:4 (Win7_BETA+)
DWORD ReservedBits0 : 27; //0x0028:5 (Win7_BETA+)
} vista_CrossProcessFlags;
} struct28;
union
{
void* KernelCallbackTable; //0x002C (Vista+)
void* UserSharedInfoPtr; //0x002C (Vista+)
} dword2C;
DWORD SystemReserved; //0x0030 (NT3.51-XP)
//Microsoft seems to keep changing their mind with DWORD 0x34
union
{
DWORD SystemReserved2; //0x0034 (NT3.51-Win2k)
struct
{
DWORD ExecuteOptions : 2; //0x0034:0 (XP-early WS03)
DWORD SpareBits : 30; //0x0034:2 (XP-early WS03)
} xpBits;
DWORD AtlThunkSListPtr32; //0x0034 (late XP,Win7+)
DWORD SpareUlong; //0x0034 (late WS03-Vista)
struct
{
DWORD HeapTracingEnabled : 1; //0x0034:0 (Win7_BETA)
DWORD CritSecTracingEnabled : 1; //0x0034:1 (Win7_BETA)
DWORD SpareTracingBits : 30; //0x0034:2 (Win7_BETA)
} win7_TracingFlags;
} dword34;
union
{
PEB_FREE_BLOCK* FreeList; //0x0038 (NT3.51-early Vista)
DWORD SparePebPtr0; //0x0038 (last Vista)
void* ApiSetMap; //0x0038 (Win7+)
} dword38;
DWORD TlsExpansionCounter; //0x003C
void* TlsBitmap; //0x0040
DWORD TlsBitmapBits[2]; //0x0044
void* ReadOnlySharedMemoryBase; //0x004C
union
{
void* ReadOnlyShareMemoryHeap; //0x0050 (NT3.51-WS03)
void* HotpatchInformation; //0x0050 (Vista+)
} dword50;
void** ReadOnlyStaticServerData; //0x0054
void* AnsiCodePageData; //0x0058
void* OemCodePageData; //0x005C
void* UnicodeCaseTableData; //0x0060
DWORD NumberOfProcessors; //0x0064
DWORD NtGlobalFlag; //0x0068
LARGE_INTEGER CriticalSectionTimeout; //0x0070
DWORD HeapSegmentReserve; //0x0078
DWORD HeapSegmentCommit; //0x007C
DWORD HeapDeCommitTotalFreeThreshold; //0x0080
DWORD HeapDeCommitFreeBlockThreshold; //0x0084
DWORD NumberOfHeaps; //0x0088
DWORD MaximumNumberOfHeaps; //0x008C
void** ProcessHeaps; //0x0090
void* GdiSharedHandleTable; //0x0094
//end of NT 3.51 members / members that follow available on NT 4.0 and up
void* ProcessStarterHelper; //0x0098
DWORD GdiDCAttributeList; //0x009C
union
{
struct
{
void* LoaderLock; //0x00A0 (NT4)
} nt4;
struct
{
RTL_CRITICAL_SECTION* LoaderLock; //0x00A0 (Win2k+)
} win2k;
} dwordA0;
DWORD OSMajorVersion; //0x00A4
DWORD OSMinorVersion; //0x00A8
WORD OSBuildNumber; //0x00AC
WORD OSCSDVersion; //0x00AE
DWORD OSPlatformId; //0x00B0
DWORD ImageSubsystem; //0x00B4
DWORD ImageSubsystemMajorVersion; //0x00B8
DWORD ImageSubsystemMinorVersion; //0x00BC
union
{
KAFFINITY ImageProcessAffinityMask; //0x00C0 (NT4-early Vista)
KAFFINITY ActiveProcessAffinityMask; //0x00C0 (late Vista+)
} dwordC0;
DWORD GdiHandleBuffer[0x22]; //0x00C4
void* PostProcessInitRoutine; //0x014C / void (*PostProcessInitRoutine) (void);
//members that follow available on Windows 2000 and up
void* TlsExpansionBitmap; //0x0150
DWORD TlsExpansionBitmapBits[0x20]; //0x0154
DWORD SessionId; //0x01D4
ULARGE_INTEGER AppCompatFlags; //0x01D8
ULARGE_INTEGER AppCompatFlagsUser; //0x01E0
void* pShimData; //0x01E8
void* AppCompatInfo; //0x01EC
UNICODE_STRING CSDVersion; //0x01F0
//members that follow available on Windows XP and up
ACTIVATION_CONTEXT_DATA* ActivationContextData; //0x01F8
ASSEMBLY_STORAGE_MAP* ProcessAssemblyStorageMap; //0x01FC
ACTIVATION_CONTEXT_DATA* SystemDefaultActivationContextData; //0x0200
ASSEMBLY_STORAGE_MAP* SystemAssemblyStorageMap; //0x0204
DWORD MinimumStackCommit; //0x0208
//members that follow available on Windows Server 2003 and up
FLS_CALLBACK_INFO* FlsCallback; //0x020C
LIST_ENTRY FlsListHead; //0x0210
void* FlsBitmap; //0x0218
DWORD FlsBitmapBits[4]; //0x021C
DWORD FlsHighIndex; //0x022C
//members that follow available on Windows Vista and up
void* WerRegistrationData; //0x0230
void* WerShipAssertPtr; //0x0234
//members that follow available on Windows 7 BETA and up
union
{
void* pContextData; //0x0238 (prior to Windows 8)
void* pUnused; //0x0238 (Windows 8)
} dword238;
void* pImageHeaderHash; //0x023C
//members that follow available on Windows 7 RTM and up
struct //TracingFlags
{
DWORD HeapTracingEnabled :1; //0x0240:0
DWORD CritSecTracingEnabled :1; //0x0240:1
DWORD LibLoaderTracingEnabled :1; //0x0240:2
DWORD SpareTracingBits :29; //0x0240:3
} dword240;
DWORD dummy02; //0x0244
//members that follow available on Windows 8 and up
QWORD CsrServerReadOnlySharedMemoryBase; //0x0248
//members that follow available on Windows 10 and up
DWORD TppWorkerpListLock; //0x0250
union //conflicting reports about what 0x254 points to
{
LIST_ENTRY TppWorkerpList; //0x0254
DWORD dwSystemCallMode; //0x0254 / set to 2 under 64-bit Windows in a 32-bit process (WOW64)
} dword254;
void* WaitOnAddressHashTable[128]; //0x025C
} PEB;
//
// TEB-specific structures
//
//GDI_TEB_BATCH - size=0x04E0
typedef struct _GDI_TEB_BATCH
{
union
{
DWORD Offset;
struct
{
DWORD Offset : 31; //0x00:00 Win 8.1 Update 1+
DWORD HasRenderingCommand : 1; //0x00:31 Win 8.1 Update 1+
} bits;
} dword0;
DWORD HDC;
DWORD Buffer[0x136];
} GDI_TEB_BATCH;
typedef struct _TEB_ACTIVE_FRAME_CONTEXT
{
DWORD Flags;
CHAR* FrameName;
} TEB_ACTIVE_FRAME_CONTEXT;
typedef struct TEB_ACTIVE_FRAME TEB_ACTIVE_FRAME;
struct TEB_ACTIVE_FRAME
{
DWORD Flags;
TEB_ACTIVE_FRAME* Previous;
TEB_ACTIVE_FRAME_CONTEXT* Context;
};
//
// TEB (Thread Environment Block) a.k.a. TIB (Thread Information Block) 32-bit
//
// The size of this structure is OS dependent:
// 0x0F28 NT 3.51
// 0x0F88 NT 4.0
// 0x0FA4 Win2k
// 0x0FB4 prior to XP SP2
// 0x0FB8 XP SP2/WS03+
// 0x0FBC WS03 SP1+
// 0x0FF8 Vista/WS08
// 0x0FE4 Win7/WS08 R2
// 0x0FE8 Win8-Win8.1/WS12
// 0x1000 Win10
//
typedef struct TEB TEB;
struct TEB
{
//NT_TIB structure portion
EXCEPTION_REGISTRATION* ExceptionList; //0x0000 / Current Structured Exception Handling (SEH) frame
void* StackBase; //0x0004 / Bottom of stack (high address)
void* StackLimit; //0x0008 / Ceiling of stack (low address)
void* SubSystemTib; //0x000C
union
{
void* FiberData; //0x0010
DWORD Version; //0x0010
} dword10;
void* ArbitraryUserPointer; //0x0014
TEB* Self; //0x0018
//NT_TIB ends (NT subsystem independent part)
void* EnvironmentPointer; //0x001C
CLIENT_ID ClientId; //0x0020
// ClientId.ProcessId //0x0020 / value retrieved by GetCurrentProcessId()
// ClientId.ThreadId //0x0024 / value retrieved by GetCurrentThreadId()
void* ActiveRpcHandle; //0x0028
void* ThreadLocalStoragePointer; //0x002C
PEB* ProcessEnvironmentBlock; //0x0030
DWORD LastErrorValue; //0x0034
DWORD CountOfOwnedCriticalSections; //0x0038
void* CsrClientThread; //0x003C
void* Win32ThreadInfo; //0x0040
DWORD User32Reserved[0x1A]; //0x0044
DWORD UserReserved[5]; //0x00AC
void* WOW32Reserved; //0x00C0 / user-mode 32-bit (WOW64) -> 64-bit context switch function prior to kernel-mode transition
LCID CurrentLocale; //0x00C4
DWORD FpSoftwareStatusRegister; //0x00C8
union
{
DWORD SystemReserved1[0x36]; //0x00CC (NT 3.51-Win8)
struct
{
DWORD Reserved1[0x16]; //0x00CC
void* pKThread; //0x0124 / pointer to KTHREAD (ETHREAD) structure
DWORD Reserved2[0x1F]; //0x0128
} kernelInfo;
struct
{
DWORD ReservedForDebuggerInstrumentation[0x10]; //0x00CC (Win10 PRE-RTM+)
DWORD SystemReserved1[0x26]; //0x010C (Win10 PRE-RTM+)
} win10;
} dwordCC;
NTSTATUS ExceptionCode; //0x01A4
union
{
BYTE SpareBytes1[0x2C]; //0x01A8 (NT3.51-Win2k)
struct
{
BYTE ActivationContextStack[0x14]; //0x01A8 (XP-early WS03)
BYTE SpareBytes1[0x18]; //0x01BC (XP-early WS03)
} xp;
struct
{
void* ActivationContextStackPointer; //0x01A8 (WS03+)
union
{
BYTE SpareBytes1[0x24]; //0x01AC (WS03-Win8.1)
struct
{
void* InstrumentationCallbackSp; //0x01AC (Win10+)
void* InstrumentationCallbackPreviousPc; //0x01B0 (Win10+)
void* InstrumentationCallbackPreviousSp; //0x01B4 (Win10+)
BOOLEAN InstrumentationCallbackDisabled; //0x01B8 (Win10+)
BYTE SpareBytes[0x17]; //0x01B9 (Win10+)
} win10;
} dword1AC;
union
{
BYTE SpareBytes2[4]; //0x01D0 (WS03)
DWORD TxFsContext; //0x01D0 (Vista+)
} dword1D0;
} lateWs03;
} dword1A8;
GDI_TEB_BATCH GdiTebBatch; //0x01D4
CLIENT_ID RealClientId; //0x06B4
HANDLE GdiCachedProcessHandle; //0x06BC
DWORD GdiClientPID; //0x06C0
DWORD GdiClientTID; //0x06C4
void* GdiThreadLocalInfo; //0x06C8
DWORD Win32ClientInfo[0x3E]; //0x06CC
void* glDispatchTable[0xE9]; //0x07C4
DWORD glReserved1[0x1D]; //0x0B68
void* glReserved2; //0x0BDC
void* glSectionInfo; //0x0BE0
void* glSection; //0x0BE4
void* glTable; //0x0BE8
void* glCurrentRC; //0x0BEC
void* glContext; //0x0BF0
NTSTATUS LastStatusValue; //0x0BF4
UNICODE_STRING StaticUnicodeString; //0x0BF8
WCHAR StaticUnicodeBuffer[0x105]; //0x0C00
void* DeallocationStack; //0x0E0C
void* TlsSlots[0x40]; //0x0E10
LIST_ENTRY TlsLinks; //0x0F10
void* Vdm; //0x0F18
void* ReservedForNtRpc; //0x0F1C
void* DbgSsReserved[2]; //0x0F20
//end of NT 3.51 members / members that follow available on NT 4.0 and up
union
{
DWORD ThreadErrorMode; //0x0F28 (OS?) / RtlSetThreadErrorMode
DWORD HardErrorsAreDisabled; //0x0F28 (NT4-XP)
DWORD HardErrorMode; //0x0F28 (WS03+)
} dwordF28;
union
{
struct
{
DWORD Instrumentation[0x10]; //0x0F2C (NT4-early WS03)
} nt;
struct
{
union
{
struct
{
DWORD Instrumentation[0x0E]; //0x0F2C (late WS03+)
void* SubProcessTag; //0x0F64 (late WS03+)
} beforeVista;
struct
{
DWORD Instrumentation[9]; //0x0F2C (Vista+)
GUID ActivityId; //0x0F50 (Vista+)
void* SubProcessTag; //0x0F60 (Vista+)
union
{
DWORD EtwLocalData; //0x0F64 (WIN8 PRE-RTM)
DWORD PerflibData; //0x0F64 (WIN8 RTM+)
} win8;
} vista;
} dwordF2C;
void* EtwTraceData; //0x0F68 (late WS03+)
} ws03;
} dwordF2C;
void* WinSockData; //0x0F6C
DWORD GdiBatchCount; //0x0F70
union
{
struct
{
union
{
struct
{
BOOLEAN InDbgPrint; //0x0F74 (NT4-WS03)
BOOLEAN FreeStackOnTermination; //0x0F75 (NT4-WS03)
BOOLEAN HasFiberData; //0x0F76 (NT4-WS03)
} beforeVista;
union
{
BOOLEAN SpareBool0; //0x0F74 (Vista)
BOOLEAN SpareBool1; //0x0F75 (Vista)
BOOLEAN SpareBool2; //0x0F76 (Vista)
} vista;
} u;
BOOLEAN IdealProcessor; //0x0F77 (NT4-Vista)
} beforeWin7;
PROCESSOR_NUMBER CurrentIdealProcessor; //0x0F74 (Win7+)
} dwordF74;
union
{
DWORD Spare3; //0x0F78 (NT4-early WS03)
DWORD GuaranteedStackBytes; //0x0F78 (late WS03+)
} dwordF78;
void* ReservedForPerf; //0x0F7C
void* ReservedForOle; //0x0F80
DWORD WaitingOnLoaderLock; //0x0F84
//members that follow available on Windows 2000 and up
union
{
struct
{
//Wx86ThreadState structure
DWORD* CallBx86Eip; //0x0F88 (Win2k-early WS03)
void* DeallocationCpu; //0x0F8C (Win2k-early WS03)
BYTE UseKnownWx86Dll; //0x0F90 (Win2k-early WS03)
CHAR OleStubInvoked; //0x0F91 (Win2k-early WS03)
BYTE Padding[2]; //0x0F92
} beforeLateWs03;
struct
{
union
{
void* SparePointer1; //0x0F88 (late WS03)
void* SavedPriorityState; //0x0F88 (Vista+)
} dwordF88;
union
{
void* SoftPatchPtr1; //0x0F8C (late WS03-Win7)
void* ReservedForCodeCoverage; //0x0F8C (Win8+)
} dwordF8C;
union
{
void* SoftPatchPtr2; //0x0F90 (late WS03)
void* ThreadPoolData; //0x0F90 (Vista+)
} dwordF90;
} lateWs03;
} dwordF88;
void* TlsExpansionSlots; //0x0F94
union
{
LCID ImpersonationLocale; //0x0F98 (Win2k-Vista)
DWORD MuiGeneration; //0x0F98 (Win7+)
} dwordF98;
DWORD IsImpersonating; //0x0F9C
void* NlsCache; //0x0FA0
//members that follow available on Windows XP and up
void* pShimData; //0x0FA4
union
{
DWORD HeapVirtualAffinity; //0x0FA8 (XP-Win7)
struct
{
WORD HeapVirtualAffinity; //0x0FA8 (Win8+)
WORD LowFragHeapDataSlot; //0x0FAA (Win8+)
} win8;
} dwordFA8;
HANDLE CurrentTransactionHandle; //0x0FAC
TEB_ACTIVE_FRAME* ActiveFrame; //0x0FB0
//members that follow available on Windows XP SP2 and up
union
{
void* FlsData; //0x0FB4 (WS03+)
struct
{
BOOLEAN SafeThunkCall; //0x0FB4 (XP SP2)
BOOLEAN BooleanSpare[3]; //0x0FB5 (XP SP2)
} xpSp2;
} dwordFB4;
union
{
struct
{
BOOLEAN SafeThunkCall; //0x0FB8 (late WS03)
BOOLEAN BooleanSpare[3]; //0x0FB9 (late WS03)
} ws03;
void* PreferredLanguages; //0x0FB8 (Vista+)
} dwordFB8;
//members that follow available on Windows Vista and up
void* UserPrefLanguages; //0x0FBC
void* MergedPrefLanguages; //0x0FC0
DWORD MuiImpersonation; //0x0FC4
union
{
volatile WORD CrossTebFlags; //0x0FC8
struct
{
WORD SpareCrossTebBits : 16; //0x0FC8
} bits;
} wordFC8;
union
{
WORD SameTebFlags; //0x0FCA
struct
{
WORD SafeThunkCall : 1; //0x0FCA:0x00
WORD InDebugPrint : 1; //0x0FCA:0x01
WORD HasFiberData : 1; //0x0FCA:0x02
WORD SkipThreadAttach : 1; //0x0FCA:0x03
WORD WerInShipAssertCode : 1; //0x0FCA:0x04
WORD RanProcessInit : 1; //0x0FCA:0x05
WORD ClonedThread : 1; //0x0FCA:0x06
WORD SuppressDebugMsg : 1; //0x0FCA:0x07
WORD DisableUserStackWalk : 1; //0x0FCA:0x08
WORD RtlExceptionAttached : 1; //0x0FCA:0x09
WORD InitialThread : 1; //0x0FCA:0x0A
WORD SessionAware : 1; //0x0FCA:0x0B
} bits;
} wordFCA;
void* TxnScopeEnterCallback; //0x0FCC
void* TxnScopeExitCallback; //0x0FD0
void* TxnScopeContext; //0x0FD4
DWORD LockCount; //0x0FD8
union
{
struct
{
DWORD ProcessRundown; //0x0FDC (Vista)
QWORD LastSwitchTime; //0x0FE0 (Vista)
QWORD TotalSwitchOutTime; //0x0FE8 (Vista)
LARGE_INTEGER WaitReasonBitMap; //0x0FF0 (Vista)
} vista;
//end of Vista members
struct
{
union
{
DWORD SpareUlong0; //0x0FDC (Win7-Win8)
INT32 WowTebOffset; //0x0FDC (Win10+)
} dwordFDC;
void* ResourceRetValue; //0x0FE0 (Win7+)
//end of Windows 7 members (TEB shrunk after Vista)
void* ReservedForWdf; //0x0FE4 (Win8+)
//end of Windows 8 members
} afterVista;
} dwordFDC;
//members that follow available on Windows 10 and up (currently unknown)
BYTE ReservedForWin10[0x18]; //0x0FE8
}; //struct TEB