JIURL play Win2k process threads chapter of TEB: JIURL Home: http://jiurl.yeah.net Date: 2003-7-30
TECK, thread Environment Block, thread environment block. Located in the user address space. In a lower address than the PEB, such as 0x7ffdf000, 0x7ffde000. Each thread has a TEB. Due to the TEB in the user address space, you can access the TEB structure in the code in user mode in this process. The Ethread structure of a thread in Win2K Build 2195 offset 020 * TEB points to the Teb structure of this thread. In undocumented.ntinternals.net (need to be aware of this is an unofficial site) we can find the definition of TEB and its related structures. Some relevant structures are also defined from KD. We first list the definition of the structure and will be described.
// from undocumented.ntinternals.nettypedef struct _TEB {NT_TIB Tib; PVOID EnvironmentPointer; CLIENT_ID Cid; PVOID ActiveRpcInfo; PVOID ThreadLocalStoragePointer; PPEB Peb; ULONG LastErrorValue; ULONG CountOfOwnedCriticalSections; PVOID CsrClientThread; PVOID Win32ThreadInfo; ULONG Win32ClientInfo [0x1F]; PVOID WOW32Reserved; ULONG currentLocale; ULONG FpSoftwareStatusRegister; PVOID SystemReserved1 [0x36]; PVOID Spare1; ULONG ExceptionCode; ULONG SpareBytes1 [0x28]; PVOID SystemReserved2 [0xA]; ULONG GdiRgn; ULONG GdiPen; ULONG GdiBrush; CLIENT_ID RealClientId; PVOID GdiCachedProcessHandle; ULONG GdiClientPID; ULONG GdiClientTID ; PVOID GdiThreadLocaleInfo; PVOID UserReserved [5]; PVOID GlDispatchTable [0x118]; ULONG GlReserved1 [0x1A]; PVOID GlReserved2; PVOID GlSectionInfo; PVOID GlSection; PVOID GlTable; PVOID GlCurrentRC; PVOID GlContext; NTSTATUS LastStatusValue; UNICODE_STRING StaticUnicodeString; WCHAR StaticUnicodeBuffer [0x105 ]; Pvoid deallocationStack; pvoid tlsslots [0x40]; list_entry tlslinks; pvoid vdm; pvoid reservedfornTRP c; PVOID DbgSsReserved [0x2]; ULONG HardErrorDisabled; PVOID Instrumentation [0x10]; PVOID WinSockData; ULONG GdiBatchCount; ULONG Spare2; ULONG Spare3; ULONG Spare4; PVOID ReservedForOle; ULONG WaitingOnLoaderLock; PVOID StackCommit; PVOID StackCommitMax; PVOID StackReserved;} TEB, * PTEB; // from kdstruct _NT_TIB (sizeof = 28) 00 struct _EXCEPTION_REGISTRATION_RECORD * ExceptionList 04 void * StackBase 08 void * StackLimit 0c void * SubSystemTib 10 void * FiberData 10 uint32 Version 14 void * ArbitraryUserPointer 18 struct _NT_TIB * Selfstruct _CLIENT_ID (sizeof = 8) 0 void * UniqueProcess 4 void * UniqueThreadstruct _EXCEPTION_REGISTRATION_RECORD (sizeof = 8) 0 struct _EXCEPTION_REGISTRATION_RECORD * Next
4 function * Handlerstruct _UNICODE_STRING (sizeof = 8) 0 uint16 Length 2 uint16 MaximumLength 4 uint16 * Buffer exception processing chain struct _TEBstruct _NT_TIB (sizeof = 28) 00 struct _EXCEPTION_REGISTRATION_RECORD * ExceptionList directed structured exception handling (seh) chain pointer. Stack struct _tebstruct _nt_tib (sizeof = 28) 04 void * stackbase 08 void * stacklimit, a thread, there are two own stacks. One is the stack in kernel mode, one is the stack in user mode. When the thread is in kernel mode, it is RING0, when executing code, is used, using the kernel mode stack. When the thread is in user mode, it is when the code is executed, and the user mode stack is used. Some threads running only in the kernel mode do not have a user mode stack, such as some threads of the System process (PID 8 process). A thread's user mode stack is located in the user address space. Thread TEB Offset 04 STACKBASE is the highest address of the thread user mode stack, that is, the start address, the stack is downward. StackLimit at the thread TEB offset 08 is the minimum address (effective part) of the thread user mode stack. The information of the thread's kernel mode stack is in the thread Ethread structure. In the assembly code of the FS segment, we can see the use of the FS in the assembly code of many functions of the system. For x86, the segmentation mechanism is default and must be used. Win2K uses a flat (FLAT) model, set the segment to the entire 4G address space, hidden the segmentation mechanism. However, the FS section is an exception. For runs running in user mode, it is running under RING3, and the FS segment is the address space where the current thread is located. For runs running in kernel mode, it is running under RING0, and the FS segment starts from the address FFDFF000, the part of the address space of 0x2000. Below we use SOFTICE to observe the FS segment of Ring3 execution code and an FS segment executing code in RING0. RING3 executing a segment register and global descriptor table at RING3: r -dcs: EIP = 001b: 00401919 SS: ESP = 0023: 0012FE20EAX = 00000001 EBX = 7FFDF000 ECX = 0012FFB0 EDX = 00040000Esi = 0012FE20 EDI = 0012FF80 EBP = 0012FF80 EFL = 00000246DS = 0023 ES = 0023 FS = 0038 GS = 0000 Note CS is 1B, indicating that the CPL is RING3. Note the FS segment selector.
:. GdtSel Type Base Limit DPL AttributesGDTbase = 80036000 Limit = 03FF0008 Code32 00000000 FFFFFFFF 0 P RE0010 Data32 00000000 FFFFFFFF 0 P RW001B Code32 00000000 FFFFFFFF 3 P RE0023 Data32 00000000 FFFFFFFF 3 P RW0028 TSS32 801F4000 000020AB 0 P B0030 Data32 FFDFF000 00001FFF 0 P RW003B Data32 7FFDE000 00000FFF 3 P rw // fs corresponds to the segment descriptor, base = 7ffde000 DPL = 3 // The TEB of the current thread is in the 4kb address space at the beginning of the 7FFDE000. 0043 DATA16 00000400 0000FFF 3 P rw0048 reserved 000000000000000000 0 NP0050 TSS32 80470040 00000068 0 p ... ring0 Just the RING3 program for system call, generated INT 2E interrupt. When it is turned to the interrupt 2e interrupt handler, the CPU and the conversion of the stack segment and the code segment are converted. Interrupt 2E's interrupt handler will select the original FS segment to assign the FS segment selector to 30. Segment registers and global descriptors // attention CS and SS are already RING0. Note that the FS value is 30. : R -dCS: EIP = 0008: 804615DD SS: ESP = 0010: EF0B5DB4EAX = 00000038 EBX = 00000030 ECX = 80002000 EDX = 0012FD9CESI = 00000000 EDI = 0012FF80 EBP = 0012FDF8 EFL = 00000002DS = 0023 ES = 0023 FS = 0030 GS = 0000 :. gdtSel Type Base Limit DPL AttributesGDTbase = 80036000 Limit = 03FF0008 Code32 00000000 FFFFFFFF 0 P RE0010 Data32 00000000 FFFFFFFF 0 P RW001B Code32 00000000 FFFFFFFF 3 P RE0023 Data32 00000000 FFFFFFFF 3 P RW0028 TSS32 801F4000 000020AB 0 P B0030 Data32 FFDFF000 00001FFF 0 P RW / / Fs corresponds to the paragraph descriptor, base = ffdff000 dPL = 0003B DATA32 7FFDE000 00000FFF 3 P RW ... The FS segment in user mode is the Teb of the current thread. The FS segment in the kernel mode is 8KB started by FFDFF000 (usually only 4KB mapped by physical memory) address space. Its content is some information related to the current thread. Where the offset 00 at 00 is an exception_registration_record * ExceptionList in kernel mode. Offset 04 4 bytes of offset 08 is the information related to the thread kernel stack. The 4 bytes of offset 124 are pointers that point to the Ethread structure of the current thread. Note that this address space starting from FFDFF000 is the current thread, for different threads, the content in this address space is different.