JIURL play Win2k process thread of articles PEB: JIURL Home: http://jiurl.yeah.net Date: 2003-7-30
PEB, Process Environment Block, Process Environment Block. Located in the user address space. At address 0x7ffdf000. So the user process can directly access its own PEB structure. The eProcess structure offset 1B0 at the process of the process of Win2K Build 2195 also points to the PEB structure. In undocumented.ntinternals.net (need to note that this is an unofficial site) we can find the definition of PEB and its related structure. We first list the definition of the structure and will be described.
typedef struct _PEB {BOOLEAN InheritedAddressSpace; BOOLEAN ReadImageFileExecOptions; BOOLEAN BeingDebugged; BOOLEAN Spare; HANDLE Mutant; PVOID ImageBaseAddress; PPEB_LDR_DATA LoaderData; PRTL_USER_PROCESS_PARAMETERS ProcessParameters; PVOID SubSystemData; PVOID ProcessHeap; PVOID FastPebLock; PPEBLOCKROUTINE FastPebLockRoutine; PPEBLOCKROUTINE FastPebUnlockRoutine; ULONG EnvironmentUpdateCount; PPVOID KernelCallbackTable; PVOID EventLogSection; PVOID EventLog; PPEB_FREE_BLOCK FreeList; ULONG TlsExpansionCounter; PVOID TlsBitmap; ULONG TlsBitmapBits [0x2]; PVOID ReadOnlySharedMemoryBase; PVOID ReadOnlySharedMemoryHeap; PPVOID ReadOnlyStaticServerData; PVOID AnsiCodePageData; PVOID OemCodePageData; PVOID UnicodeCaseTableData; ULONG NumberOfProcessors; ULONG NtGlobalFlag; BYTE spare2 [0x4]; LARGE_INTEGER CriticalSectionTimeout; ULONG HeapSegmentReserve; ULONG HeapSegmentCommit; ULONG HeapDeCommitTotalFreeThreshold; ULONG HeapDeCommitFreeBlockThreshold; ULONG NumberOfHeaps; ULONG MaximumNumberOfHeaps; PPVOID * ProcessHeaps; PVO ID GdiSharedHandleTable; PVOID ProcessStarterHelper; PVOID GdiDCAttributeList; PVOID LoaderLock; ULONG OSMajorVersion; ULONG OSMinorVersion; ULONG OSBuildNumber; ULONG OSPlatformId; ULONG ImageSubSystem; ULONG ImageSubSystemMajorVersion; ULONG ImageSubSystemMinorVersion; ULONG GdiHandleBuffer [0x22]; ULONG PostProcessInitRoutine; ULONG TlsExpansionBitmap; BYTE TlsExpansionBitmapBits [0x80] ; ULONG SessionId;} PEB, * PPEB; typedef void (* PPEBLOCKROUTINE) (PVOID PebLock); typedef struct _PEB_LDR_DATA {ULONG Length; BOOLEAN Initialized; PVOID SsHandle; LIST_ENTRY InLoadOrderModuleList; LIST_ENTRY InMemoryOrderModuleList; LIST_ENTRY InInitializationOrderModuleList;} PEB_LDR_DATA, * PPEB_LDR_DATA; typedef Struct _ldr_module {list_entry inloadordermoduleList;
LIST_ENTRY InMemoryOrderModuleList; LIST_ENTRY InInitializationOrderModuleList; PVOID BaseAddress; PVOID EntryPoint; ULONG SizeOfImage; UNICODE_STRING FullDllName; UNICODE_STRING BaseDllName; ULONG Flags; SHORT LoadCount; SHORT TlsIndex; LIST_ENTRY HashTableEntry; ULONG TimeDateStamp;} LDR_MODULE, * PLDR_MODULE; typedef struct _UNICODE_STRING {USHORT Length; USHORT MaximumLength; PWSTR Buffer;} UNICODE_STRING, * PUNICODE_STRING; typedef struct _RTL_USER_PROCESS_PARAMETERS {ULONG MaximumLength; ULONG Length; ULONG Flags; ULONG DebugFlags; PVOID ConsoleHandle; ULONG ConsoleFlags; HANDLE StdInputHandle; HANDLE StdOutputHandle; HANDLE StdErrorHandle; UNICODE_STRING currentDirectoryPath; HANDLE CurrentDirectoryHandle; UNICODE_STRING DllPath ; UNICODE_STRING ImagePathName; UNICODE_STRING CommandLine; PVOID Environment; ULONG StartingPositionLeft; ULONG StartingPositionTop; ULONG Width; ULONG Height; ULONG charWidth; ULONG CharHeight; ULONG ConsoleTextAttributes; ULONG WindowFlags; ULONG ShowWindowFlags; UNICODE_STRING WindowTitle; UN ICODE_STRING DesktopName; UNICODE_STRING ShellInfo; UNICODE_STRING RuntimeData; RTL_DRIVE_LETTER_CURDIR DLCurrentDirectory [0x20];} RTL_USER_PROCESS_PARAMETERS, * PRTL_USER_PROCESS_PARAMETERS; typedef struct _RTL_DRIVE_LETTER_CURDIR {USHORT Flags; USHORT Length; ULONG TimeStamp; UNICODE_STRING DosPath;} RTL_DRIVE_LETTER_CURDIR, * PRTL_DRIVE_LETTER_CURDIR; typedef struct _PEB_FREE_BLOCK {_PEB_FREE_BLOCK * Next Ulong size;} PEB_FREE_BLOCK, * PPEB_FREE_BLOCK; I wrote a program called JIURLPEBSEE to analyze the PEB of the specified process. Here I combine some of the contents of the PEB and its related structures in conjunction with JIURLPEBSEE.
ProcessId (Decimal): 516Explorer.exe: PEB at 0x7ffdf000LoaderData: 0x00071e90ProcessParameters: 0x00020000ProcessHeap: 0x00070000NumberOfHeaps: 11MaximumNumberOfHeaps: 16 * ProcessHeaps: 0x77fce3807ffdf000: 00000000 ffffffff 00400000 00071e907ffdf010: 00020000 00000000 00070000 77fcd1707ffdf020: 77f8aa4c 77f8aa7d 00000001 77e143807ffdf030: 00000000 00000000 00000000 000000007ffdf040: 77fcd1a8 03cfffff 00000000 7f6f00007ffdf050: 7f6f0000 7f6f0688 7ffa0000 7ffa00007ffdf060: 7ffd1000 00000001 00000000 000000007ffdf070: 079b8000 ffffe86d 00100000 000020007ffdf080: 00010000 00001000 0000000b 000000107ffdf090: 77fce380 00350000 00000000 000000147ffdf0a0: 77fcd348 00000005 00000000 000008937ffdf0b0: 00000002 00000002 00000004 000000007ffdf0c0: 00000000 00000000 00000002 000000007ffdf0d0: 00000004 00000000 b51003ba 391001e47ffdf0e0: 00000000 00000000 00000000 0000007FFDF0F0: 00000000 000,000 000000000 000,000007ffdf100 000000000000000000000000000 0000-00 0000-00 0000-00 0000-00-00 0000-00 0000-00 0000-00-00 0000-00 0000 0007ffdf120: 8204019c 7004019b cf04019e a104019d7ffdf130: 00000000 00000000 00000000 000000007ffdf140: 00000000 00000000 00000000 000000007ffdf150: 77fcdcc0 00000000 00000000 000000007ffdf160: 00000000 00000000 00000000 000000007ffdf170: 00000000 00000000 00000000 000000007ffdf180: 00000000 00000000 00000000 000000007ffdf190: 00000000 00000000 00000000 000000007ffdf1a0: 00000000 00000000 00000000 000000007ffdf1b0: 00000000 00000000 00000000 000000007ffdf1c0: 00000000 00000000 00000000 000000007ffdf1d0: 00000000 00000000 00000000 000200007ffdf1e0: 7f6f06c2 00000000 00000000 000000007ffdf1f0: 00000000 00000000 00000000 000000007ffdf200: 00000000 00000000 00000000 00000000 ... we have to analyze the process Explorer.exe.
LoaderData is a pointer to PEB_LDR_DATA, through PEB_LDR_DATA, we can find all modules loaded by the process. ProcessParameters is a pointer to RTL_USER_PROCESS_PARAMETERS, and RTL_User_Process_Parameters is a parameter of some processes. The process usually has multiple users. ProcessHeap is the first address of the process stack (default). Numberofheaps is the number of stacks of current processes. MaximumNumberofheaps is the maximum number of piles of the process. * ProcessHeaps is the first address of a plug-in array, and each array element is 4 bytes, which is a pile of pointers. LoaderData at 0x00071e90Length: 36 BytesInitialized: 1SsHandle: 0x00000000InLoadOrderModuleListFlink: 0x00071ec0 Blink: 0x000a0508InMemoryOrderModuleListFlink: 0x00071ec8 Blink: 0x000a0510InInitializationOrderModuleListFlink: 0x00071f48 Blink: 0x000a0518Module at 0x00071ec0FullDllName: D: /WINNT/Explorer.exeBaseDllName: Explorer.exeBaseAddress: 0x00400000SizeOfImage: 0x0003c000Module at 0x00071f38FullDllName: D: / WINNT / System32 / ntdll.dllBaseDllName: ntdll.dllBaseAddress: 0x77f80000SizeOfImage: 0x00079000Module at 0x00072470FullDllName: D: /WINNT/system32/ADVAPI32.DLLBaseDllName: ADVAPI32.DLLBaseAddress: 0x77d90000SizeOfImage: 0x0005a000 ... from PEB can find PEB_LDR_DATA, PEB_LDR_DATA has three two-way The head of the loop linked list is InlineorderModuleList, INMEMORYORDERMODULIST, ININITIRIZATIONORDERModuleList. Each chain item is an LDR_Module structure.
ProcessParameters at 0x00020000MaximumLength: 0x00001000Length: 0x00000838 ... Environment at 0x0001000000010000: 004c0041 0055004c 00450053 00530052 ALLUSERS00010010: 00520050 0046004f 004c0049 003d0045 PROFILE = .00010020: 003a0049 0044005c 0063006f 006d0075 I.:./.Docum00010030: 006e0065 00730074 00610020 0064006e ents .and 00010040: 00530020 00740065 00690074 0067006e .Setting ... 00010340: 00640075 00000065 0069006c 003d0062 ude..lib = .00010350: 003a0047 004d005c 00630069 006f0072 G.:./.Micro00010360: 006f0073 00740066 00560020 00730069 soft .Vis00010370: 00610075 0020006c 00740053 00640075 ual .stud ... 00010A70: 0070006D 00540000 1..Temp..th....00010b80: 003a0044 0054005C 004E0049 0054004E D.:/.winnt000B90: 00000000000000 0000000000000000 ... ............. 00010ff0: 00000000 00000000 00000000 00000000 ................ PVOID environment RTL_USER_PROCESS_PARAMETERS in; indicates the address of the environment variable. From the structural definition, it can be seen as a parameter like stdinputhandle, imagepathname. ProcessHeaps at 0x77fce380ProcessHeaps [0]: 0x00070000ProcessHeaps [1]: 0x00170000ProcessHeaps [2]: 0x008c0000ProcessHeaps [3]: 0x00cd0000ProcessHeaps [4]: 0x00ed0000ProcessHeaps [5]: 0x00f10000ProcessHeaps [6]: 0x01290000ProcessHeaps [7]: 0x013e0000ProcessHeaps [8]: 0x01ce0000ProcessHeaps [9 ]: 0x01f50000ProcessHeaps [10]: 0x03bf000077fce380: 00070000 00170000 008c0000 00cd000077fce390: 00ed0000 00f10000 01290000 013e000077fce3a0: 01ce0000 01f50000 03bf0000 0000000077fce3b0: 00000000 00000000 00000000 00000000 from ProcessHeaps array, we can each find a heap process. In order to facilitate the content of a process address space, I wrote a program called JIURLPROCESSMSEE to get the contents of the specified process address space. We can also find the definition of PEB and its related structure using KD (kernel modulator).
kd>! strct PEB! strct PEBstruct _PEB (sizeof = 488) 000 byte InheritedAddressSpace 001 byte ReadImageFileExecOptions 002 byte BeingDebugged 003 byte SpareBool 004 void * Mutant 008 void * ImageBaseAddress 00c struct _PEB_LDR_DATA * Ldr 010 struct _RTL_USER_PROCESS_PARAMETERS * processParameters 014 void * SubSystemData 018 void * ProcessHeap 01c void * FastPebLock 020 void * FastPebLockRoutine 024 void * FastPebUnlockRoutine 028 uint32 EnvironmentUpdateCount 02c void * KernelCallbackTable 030 uint32 SystemReserved [2] 038 struct _PEB_FREE_BLOCK * FreeList 03c uint32 TlsExpansionCounter 040 void * TlsBitmap 044 uint32 TlsBitmapBits [2] 04c void * ReadOnlySharedMemoryBase 050 void * ReadOnlySharedMemoryHeap 054 void ** ReadOnlyStaticServerData 058 void * AnsiCodePageData 05c void * OemCodePageData 060 void * UnicodeCaseTableData 064 uint32 NumberOfProcessors 068 uint32 NTGLOBALFLAG 070 Union _large_integer criticalsectionTIMEOMEOMEOMEOMEOMEOMEOMEOMEOMEOMET 070 uint32 lowpart 074 int32 highpart 070 struct __unnamed3 u 070 uint32 lowpart 0 74 int32 HighPart 070 int64 QuadPart 078 uint32 HeapSegmentReserve 07c uint32 HeapSegmentCommit 080 uint32 HeapDeCommitTotalFreeThreshold 084 uint32 HeapDeCommitFreeBlockThreshold 088 uint32 NumberOfHeaps 08c uint32 MaximumNumberOfHeaps 090 void ** ProcessHeaps 094 void * GdiSharedHandleTable 098 void * ProcessStarterHelper 09c uint32 GdiDCAttributeList 0a0 void * LoaderLock 0a4 uint32 OSMajorVersion 0a8 uint32 OSMinorVersion 0ac uint16 OSBuildNumber 0ae uint16 OSCSDVersion 0b0 uint32 OSPlatformId 0b4 uint32 ImageSubsystem
0b8 uint32 ImageSubsystemMajorVersion 0bc uint32 ImageSubsystemMinorVersion 0c0 uint32 ImageProcessAffinityMask 0c4 uint32 GdiHandleBuffer [34] 14c function * PostProcessInitRoutine 150 void * TlsExpansionBitmap 154 uint32 TlsExpansionBitmapBits [32] 1d4 uint32 SessionId 1d8 void * AppCompatInfo 1dc struct _UNICODE_STRING CSDVersion 1dc uint16 Length 1de uint16 MaximumLength 1e0 uint16 * Bufferkd>! strct PEB_LDR_DATA! strct PEB_LDR_DATAstruct _PEB_LDR_DATA (sizeof = 36) 00 uint32 Length 04 byte Initialized 08 void * SsHandle 0c struct _LIST_ENTRY InLoadOrderModuleList 0c struct _LIST_ENTRY * Flink 10 struct _LIST_ENTRY * Blink 14 struct _LIST_ENTRY InMemoryOrderModuleList 14 struct _LIST_ENTRY * Flink 18 struct _LIST_ENTRY * Blink 1c struct _LIST_ENTRY InInitializationOrderModuleList 1c struct _LIST_ENTRY * Flink 20 struct _LIST_ENTRY * Blinkkd>! strct RTL_USER_PROCESS_PARAMETERS! strct RTL_USER_PROCESS_PARAMETERSstruct _RTL_USER_PROCESS_PARAMETERS (sizeof = 656) 000 UINT32 MAXIMUMUMUMLENGTH 004 UINT32 Length h 008 uint32 Flags 00c uint32 DebugFlags 010 void * ConsoleHandle 014 uint32 ConsoleFlags 018 void * StandardInput 01c void * StandardOutput 020 void * StandardError 024 struct _CURDIR CurrentDirectory 024 struct _UNICODE_STRING DosPath 024 uint16 Length 026 uint16 MaximumLength 028 uint16 * Buffer 02c void * Handle 030 struct _UNICODE_STRING DllPath 030 uint16 Length 032 uint16 MaximumLength 034 uint16 * Buffer 038 struct _UNICODE_STRING ImagePathName 038 uint16 Length 03a uint16 MaximumLength 03c uint16 * Buffer