[Debugging Technology] View PEB and TEB in user mode

Overview: View processes PEB and TEB in user mode (exe attached or started for debugging through windbg)

0x01 View TEB and PEB in user mode

During dual-machine debugging, you can directly use !PEB PID and !TEB TID to obtain relevant information about processes and threads. These two commands will be invalid in user mode. The reason is that the user mode does not support the !TEB and !PEB commands of uppercase.

The commands to obtain teb and peb during user mode debugging are in lowercase.

#Get peb
!peb

# Get teb
!teb

In addition, here is another way of thinking. We all know that the TEB structure stores the address of PEB, so we can obtain PEB-related information through TEB.

Here we take notepad.exe as an example.

0x02 Demo

Preparatory steps

  1. Run notepad.exe, Win + R enter notepad and press Enter.
  2. Run windbg and attach to the process notepad.exe.

Start debugging

View current thread

Use ~. to view the current thread (actually you can view any thread here, because the current process has only one PEB, and all TEB points to The same PEB)

0:007> ~.
. 7 Id: b8f4.d5a0 Suspend: 1 Teb: 000000a3`b61d1000 Unfrozen
      Start: ntdll!DbgUiRemoteBreakin (00007ff9`ab83c9c0)
      Priority: 0 Priority class: 32 Affinity: ff

You can see that the address of Teb is

000000

a

3

b

61

d

1000

000000a3`b61d1000

000000a3b61d1000

View TEB

dt ntdll!_Teb 000000a3`b61d1000

The output is as follows, you can see that the offset of 0x060 is _PEB:

0:007> dt ntdll!_Teb 000000a3`b61d1000
    + 0x000 NtTib : _NT_TIB
    + 0x038 EnvironmentPointer: (null)
    + 0x040 ClientId : _CLIENT_ID
    + 0x050 ActiveRpcHandle: (null)
    + 0x058 ThreadLocalStoragePointer: (null)
    + 0x060 ProcessEnvironmentBlock: 0x000000a3`b61b8000 _PEB
    + 0x068 LastErrorValue: 0
    + 0x06c CountOfOwnedCriticalSections : 0
    + 0x070 CsrClientThread: (null)
    + 0x078 Win32ThreadInfo: (null)
    + 0x080 User32Reserved: [26] 0
    + 0x0e8 UserReserved: [5] 0
    + 0x100 WOW32Reserved: (null)
    + 0x108 CurrentLocale : 0x804
    + 0x10c FpSoftwareStatusRegister: 0
    + 0x110 ReservedForDebuggerInstrumentation : [16] (null)
    + 0x190 SystemReserved1 : [30] (null)
    + 0x280 PlaceholderCompatibilityMode : 0 ''
    + 0x281 PlaceholderHydrationAlwaysExplicit : 0 ''
    + 0x282 PlaceholderReserved : [10] ""
    + 0x28c ProxiedProcessId : 0
    + 0x290 _ActivationStack : _ACTIVATION_CONTEXT_STACK
    + 0x2b8 WorkingOnBehalfTicket : [8] ""
    + 0x2c0ExceptionCode: 0n0
    + 0x2c4 Padding0 : [4] ""
    + 0x2c8 ActivationContextStackPointer: 0x000000a3`b61d1290 _ACTIVATION_CONTEXT_STACK
    + 0x2d0 InstrumentationCallbackSp : 0
    + 0x2d8 InstrumentationCallbackPreviousPc : 0
    + 0x2e0 InstrumentationCallbackPreviousSp : 0
    + 0x2e8 TxFsContext: 0xfffe
    + 0x2ec InstrumentationCallbackDisabled : 0 ''
    + 0x2ed UnalignedLoadStoreExceptions : 0 ''
    + 0x2ee Padding1 : [2] ""
    + 0x2f0 GdiTebBatch : _GDI_TEB_BATCH
    + 0x7d8 RealClientId : _CLIENT_ID
    + 0x7e8 GdiCachedProcessHandle: (null)
    + 0x7f0GdiClientPID: 0
    + 0x7f4 GdiClientTID: 0
    + 0x7f8 GdiThreadLocalInfo: (null)
    + 0x800 Win32ClientInfo: [62] 0
    + 0x9f0 glDispatchTable : [233] (null)
    + 0x1138 glReserved1 : [29] 0
    + 0x1220 glReserved2: (null)
    + 0x1228 glSectionInfo: (null)
    + 0x1230 glSection: (null)
    + 0x1238 glTable: (null)
    + 0x1240 glCurrentRC: (null)
    + 0x1248 glContext: (null)
    + 0x1250 LastStatusValue : 0
    + 0x1254 Padding2 : [4] ""
    + 0x1258 StaticUnicodeString : _UNICODE_STRING ""
    + 0x1268 StaticUnicodeBuffer : [261] ""
    + 0x1472 Padding3 : [6] ""
    + 0x1478 DeallocationStack : 0x000000a3`b6400000 Void
    + 0x1480 TlsSlots : [64] (null)
    + 0x1680 TlsLinks : _LIST_ENTRY [ 0x00000000`00000000 - 0x00000000`00000000 ]
    + 0x1690 Vdm : (null)
    + 0x1698 ReservedForNtRpc: (null)
    + 0x16a0 DbgSsReserved: [2] (null)
    + 0x16b0 HardErrorMode: 0
    + 0x16b4 Padding4 : [4] ""
    + 0x16b8 Instrumentation: [11] (null)
    + 0x1710 ActivityId : _GUID {00000000-0000-0000-0000-000000000000}
    + 0x1720 SubProcessTag: (null)
    + 0x1728 PerflibData: (null)
    + 0x1730 EtwTraceData: (null)
    + 0x1738 WinSockData: (null)
    + 0x1740 GdiBatchCount : 0
    + 0x1744 CurrentIdealProcessor : _PROCESSOR_NUMBER
    + 0x1744 IdealProcessorValue : 0x3030000
    + 0x1744 ReservedPad0 : 0 ''
    + 0x1745 ReservedPad1 : 0 ''
    + 0x1746 ReservedPad2 : 0x3 ''
    + 0x1747 IdealProcessor : 0x3 ''
    + 0x1748 GuaranteedStackBytes : 0
    + 0x174c Padding5 : [4] ""
    + 0x1750 ReservedForPerf: (null)
    + 0x1758 ReservedForOle: (null)
    + 0x1760 WaitingOnLoaderLock : 0
    + 0x1764 Padding6 : [4] ""
    + 0x1768 SavedPriorityState: (null)
    + 0x1770 ReservedForCodeCoverage : 0
    + 0x1778 ThreadPoolData: (null)
    + 0x1780 TlsExpansionSlots: (null)
    + 0x1788 DeallocationBStore: (null)
    + 0x1790 BStoreLimit: (null)
    + 0x1798 MuiGeneration : 0
    + 0x179c IsImpersonating : 0
    + 0x17a0 NlsCache: (null)
    + 0x17a8 pShimData: (null)
    + 0x17b0HeapData: 0
    + 0x17b4 Padding7 : [4] ""
    + 0x17b8 CurrentTransactionHandle: (null)
    + 0x17c0 ActiveFrame: (null)
    + 0x17c8 FlsData: (null)
    + 0x17d0 PreferredLanguages : (null)
    + 0x17d8 UserPrefLanguages: (null)
    + 0x17e0 MergedPrefLanguages : (null)
    + 0x17e8 MuiImpersonation : 0
    + 0x17ec CrossTebFlags : 0
    + 0x17ec SpareCrossTebBits : 0y0000000000000000 (0)
    + 0x17ee SameTebFlags : 8
    + 0x17ee SafeThunkCall : 0y0
    + 0x17eeInDebugPrint: 0y0
    + 0x17eeHasFiberData: 0y0
    + 0x17ee SkipThreadAttach : 0y1
    + 0x17ee WerInShipAssertCode : 0y0
    + 0x17eeRanProcessInit: 0y0
    + 0x17ee ClonedThread : 0y0
    + 0x17eeSuppressDebugMsg: 0y0
    + 0x17ee DisableUserStackWalk : 0y0
    + 0x17ee RtlExceptionAttached : 0y0
    + 0x17eeInitialThread: 0y0
    + 0x17eeSessionAware: 0y0
    + 0x17ee LoadOwner: 0y0
    + 0x17ee LoaderWorker: 0y0
    + 0x17ee SkipLoaderInit : 0y0
    + 0x17ee SpareSameTebBits : 0y0
    + 0x17f0 TxnScopeEnterCallback: (null)
    + 0x17f8 TxnScopeExitCallback: (null)
    + 0x1800 TxnScopeContext: (null)
    + 0x1808 LockCount : 0
    + 0x180cWowTebOffset: 0n0
    + 0x1810 ResourceRetValue: (null)
    + 0x1818 ReservedForWdf: (null)
    + 0x1820 ReservedForCrt : 0
    + 0x1828 EffectiveContainerId : _GUID {00000000-0000-0000-0000-000000000000}

View PEB

dt ntdll!_PEB 0xa3b61b8000

# Or use the dx command
dx -r1 ((ntdll!_PEB *)0xa3b61b8000)

The output is as shown below. Now you can see the PEB of notepad. The analysis and viewing of the ProcessParameters variables in the PEB structure are supplemented later.

0:007> dt ntdll!_PEB 0xa3b61b8000
    + 0x000 InheritedAddressSpace : 0 ''
    + 0x001 ReadImageFileExecOptions : 0 ''
    + 0x002 BeingDebugged : 0x1 ''
    + 0x003 BitField : 0x84 ''
    + 0x003 ImageUsesLargePages : 0y0
    + 0x003 IsProtectedProcess : 0y0
    + 0x003 IsImageDynamicallyRelocated : 0y1
    + 0x003 SkipPatchingUser32Forwarders : 0y0
    + 0x003 IsPackagedProcess : 0y0
    + 0x003 IsAppContainer: 0y0
    + 0x003 IsProtectedProcessLight : 0y0
    + 0x003 IsLongPathAwareProcess: 0y1
    + 0x004 Padding0 : [4] ""
    + 0x008 Mutant : 0xffffffff`ffffffff Void
    + 0x010 ImageBaseAddress : 0x00007ff7`7ef80000 Void
    + 0x018 Ldr : 0x00007ff9`ab8db4c0 _PEB_LDR_DATA
    + 0x020 ProcessParameters : 0x000001a6`50d52540 _RTL_USER_PROCESS_PARAMETERS
    + 0x028 SubSystemData : 0x00007ff9`9f7af1d0 Void
    + 0x030 ProcessHeap: 0x000001a6`50d50000 Void
    + 0x038 FastPebLock: 0x00007ff9`ab8db0e0 _RTL_CRITICAL_SECTION
    + 0x040 AtlThunkSListPtr : (null)
    + 0x048 IFEOKey: (null)
    + 0x050 CrossProcessFlags : 1
    + 0x050 ProcessInJob: 0y1
    + 0x050 ProcessInitializing : 0y0
    + 0x050 ProcessUsingVEH : 0y0
    + 0x050 ProcessUsingVCH : 0y0
    + 0x050 ProcessUsingFTH : 0y0
    + 0x050 ProcessPreviouslyThrottled : 0y0
    + 0x050 ProcessCurrentlyThrottled : 0y0
    + 0x050 ProcessImagesHotPatched : 0y0
    + 0x050 ReservedBits0 : 0y000000000000000000000000 (0)
    + 0x054 Padding1 : [4] ""
    + 0x058 KernelCallbackTable : 0x00007ff9`a9a80070 Void
    + 0x058 UserSharedInfoPtr : 0x00007ff9`a9a80070 Void
    + 0x060 SystemReserved: 0
    + 0x064 AtlThunkSListPtr32: 0
    + 0x068 ApiSetMap : 0x000001a6`50c80000 Void
    + 0x070 TlsExpansionCounter: 0
    + 0x074 Padding2 : [4] ""
    + 0x078 TlsBitmap : 0x00007ff9`ab8db440 Void
    + 0x080 TlsBitmapBits : [2] 0xffffffff
    + 0x088 ReadOnlySharedMemoryBase : 0x00007df4`3dce0000 Void
    + 0x090 SharedData: (null)
    + 0x098 ReadOnlyStaticServerData : 0x00007df4`3dce0750 -> (null)
    + 0x0a0 AnsiCodePageData : 0x00007df5`3fe30000 Void
    + 0x0a8 OemCodePageData : 0x00007df5`3fe30000 Void
    + 0x0b0 UnicodeCaseTableData : 0x00007df5`3fe60028 Void
    + 0x0b8 NumberOfProcessors : 8
    + 0x0bc NtGlobalFlag : 0
    + 0x0c0 CriticalSectionTimeout : _LARGE_INTEGER 0xffffe86d`079b8000
    + 0x0c8 HeapSegmentReserve: 0x100000
    + 0x0d0 HeapSegmentCommit: 0x2000
    + 0x0d8 HeapDeCommitTotalFreeThreshold : 0x10000
    + 0x0e0 HeapDeCommitFreeBlockThreshold : 0x1000
    + 0x0e8 NumberOfHeaps : 6
    + 0x0ec MaximumNumberOfHeaps : 0x10
    + 0x0f0 ProcessHeaps : 0x00007ff9`ab8d9d40 -> 0x000001a6`50d50000 Void
    + 0x0f8 GdiSharedHandleTable : 0x000001a6`51120000 Void
    + 0x100 ProcessStarterHelper: (null)
    + 0x108 GdiDCAttributeList : 0x14
    + 0x10c Padding3: [4] ""
    + 0x110 LoaderLock: 0x00007ff9`ab8d55c8 _RTL_CRITICAL_SECTION
    + 0x118 OSMajorVersion : 0xa
    + 0x11cOSMinorVersion: 0
    + 0x120 OSBuildNumber : 0x4a65
    + 0x122 OSCSDVersion : 0
    + 0x124 OSPlatformId : 2
    + 0x128 ImageSubsystem : 2
    + 0x12c ImageSubsystemMajorVersion : 0xa
    + 0x130 ImageSubsystemMinorVersion : 0
    + 0x134 Padding4 : [4] ""
    + 0x138 ActiveProcessAffinityMask : 0xff
    + 0x140 GdiHandleBuffer : [60] 0
    + 0x230 PostProcessInitRoutine: (null)
    + 0x238 TlsExpansionBitmap : 0x00007ff9`ab8db420 Void
    + 0x240 TlsExpansionBitmapBits : [32] 1
    + 0x2c0SessionId: 1
    + 0x2c4 Padding5 : [4] ""
    + 0x2c8 AppCompatFlags : _ULARGE_INTEGER 0x0
    + 0x2d0 AppCompatFlagsUser : _ULARGE_INTEGER 0x0
    + 0x2d8 pShimData : 0x000001a6`50cc0000 Void
    + 0x2e0 AppCompatInfo: (null)
    + 0x2e8 CSDVersion : _UNICODE_STRING ""
    + 0x2f8 ActivationContextData : 0x000001a6`50cb0000 _ACTIVATION_CONTEXT_DATA
    + 0x300 ProcessAssemblyStorageMap : 0x000001a6`50d5b5c0 _ASSEMBLY_STORAGE_MAP
    + 0x308 SystemDefaultActivationContextData : 0x000001a6`50ca0000 _ACTIVATION_CONTEXT_DATA
    + 0x310 SystemAssemblyStorageMap: (null)
    + 0x318 MinimumStackCommit: 0
    + 0x320 SparePointers: [4] (null)
    + 0x340 SpareUlongs : [5] 0
    + 0x358 WerRegistrationData : 0x000001a6`52e00000 Void
    + 0x360 WerShipAssertPtr: (null)
    + 0x368 pUnused: (null)
    + 0x370 pImageHeaderHash: (null)
    + 0x378 TracingFlags : 0
    + 0x378 HeapTracingEnabled : 0y0
    + 0x378 CritSecTracingEnabled : 0y0
    + 0x378 LibLoaderTracingEnabled : 0y0
    + 0x378 SpareTracingBits : 0y00000000000000000000000000000 (0)
    + 0x37c Padding6 : [4] ""
    + 0x380 CsrServerReadOnlySharedMemoryBase: 0x00007df4`66cb0000
    + 0x388 TppWorkerpListLock : 0
    + 0x390 TppWorkerpList : _LIST_ENTRY [ 0x000000a3`b5f0f860 - 0x000000a3`b63ffb70 ]
    + 0x3a0 WaitOnAddressHashTable : [128] (null)
    + 0x7a0 TelemetryCoverageHeader: (null)
    + 0x7a8 CloudFileFlags : 0xe0
    +0x7acCloudFileDiagFlags: 0
    + 0x7b0 PlaceholderCompatibilityMode : 2 ''
    + 0x7b1 PlaceholderCompatibilityModeReserved : [7] ""
    + 0x7b8 LeapSecondData : 0x00007df5`3fe20000 _LEAP_SECOND_DATA
    + 0x7c0 LeapSecondFlags : 0
    + 0x7c0 SixtySecondEnabled : 0y0
    + 0x7c0 Reserved : 0y0000000000000000000000000000000 (0)
    + 0x7c4 NtGlobalFlag2: 0

View ProcessParameters

In order to further understand and view, here again look at the variables of ProcessParameters.

Looking at the output of PEB, you can see that the ProcessParameters structure is named _RTL_USER_PROCESS_PARAMETERS. This structure saves a lot of basic information about the process, such as environment variables, command lines, etc. View the current ProcessParameters

dx -r1 ((ntdll!_RTL_USER_PROCESS_PARAMETERS *)0x1a650d52540)

# or
dt _RTL_USER_PROCESS_PARAMETERS 0x1a650d52540

The output looks like this:

0:007> dt _RTL_USER_PROCESS_PARAMETERS 0x1a650d52540
ntdll!_RTL_USER_PROCESS_PARAMETERS
    + 0x000 MaximumLength : 0x78a
    + 0x004 Length : 0x78a
    + 0x008 Flags : 0x6001
    + 0x00c DebugFlags: 0
    + 0x010 ConsoleHandle: (null)
    + 0x018 ConsoleFlags : 0
    + 0x020 StandardInput: (null)
    + 0x028 StandardOutput: (null)
    + 0x030 StandardError: (null)
    + 0x038 CurrentDirectory: _CURDIR
    + 0x050 DllPath : _UNICODE_STRING ""
    + 0x060 ImagePathName : _UNICODE_STRING "C:\WINDOWS\system32\
otepad.exe"
    + 0x070 CommandLine : _UNICODE_STRING ""C:\WINDOWS\system32\
otepad.exe" "
    + 0x080 Environment : 0x000001a6`50d50fe0 Void
    + 0x088 StartingX: 0
    + 0x08c StartingY : 0
    + 0x090 CountX : 0
    + 0x094 CountY : 0
    + 0x098 CountCharsX : 0
    + 0x09c CountCharsY : 0
    + 0x0a0 FillAttribute: 0
    + 0x0a4 WindowFlags : 0x801
    + 0x0a8 ShowWindowFlags : 1
    + 0x0b0 WindowTitle: _UNICODE_STRING "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Accessories\
otepad.lnk"
    + 0x0c0 DesktopInfo : _UNICODE_STRING "Winsta0\Default"
    + 0x0d0 ShellInfo : _UNICODE_STRING ""
    + 0x0e0 RuntimeData : _UNICODE_STRING ""
    + 0x0f0 CurrentDirectores: [32] _RTL_DRIVE_LETTER_CURDIR
    + 0x3f0 EnvironmentSize : 0x154e
    + 0x3f8 EnvironmentVersion: 3
    + 0x400 PackageDependencyData : (null)
    + 0x408 ProcessGroupId : 0x3ec
    + 0x40c LoaderThreads: 0
    + 0x410 RedirectionDllName : _UNICODE_STRING ""
    + 0x420 HeapPartitionName : _UNICODE_STRING ""
    + 0x430 DefaultThreadpoolCpuSetMasks: (null)
    + 0x438 DefaultThreadpoolCpuSetMaskCount : 0
    + 0x43c DefaultThreadpoolThreadMaximum: 0

At this point, you can basically see the detailed information of the process. If it is the windbg preview version, you can see some information with a few clicks, but the Environment environment variable is a pointer. If you need to view it, you still need to enter a command.

View Environment

There are three members in the _RTL_USER_PROCESS_PARAMETERS structure related to Environment

# Pointer to environment variable
 + 0x080 Environment : 0x000001a6`50d50fe0 Void

# Size of environment variables
 + 0x3f0 EnvironmentSize : 0x154e

# Version of environment variable
 + 0x3f8 EnvironmentVersion: 3

We can see the contents of environment variables through the environment variable pointer and size.

db 0x000001a6`50d50fe0 l 0x154e