본문 바로가기

High Level Technique/Reversing

Thread Environment Block (TEB)

Thread Environment Block (TEB)


Thread Environment Block (이하 TEB) 는 프로세스에서 실행되는 thread에 대한 정보를 담고 있는 구조체 입니다.

thread 별로 TEB 구조체가 하나씩 할당되고, OS 종류별로 조금씩 다릅니다.





VS2013에서 찾은 TEB 구조체 입니다. 핵심원리에 나와있는 구조체와는 조금 다르네요.


WinDBG를 이용해서 확인해 보도록 하겠습니다.


아무 파일이나 넣어서 dt_TEB를 하면 TEB에 대한 정보가 나타납니다.


Windows 10 x64환경에서 진행되었습니다.


0:000> dt_TEB

ntdll!_TEB

   +0x000 NtTib            : _NT_TIB

   +0x038 EnvironmentPointer : Ptr64 Void

   +0x040 ClientId         : _CLIENT_ID

   +0x050 ActiveRpcHandle  : Ptr64 Void

   +0x058 ThreadLocalStoragePointer : Ptr64 Void

   +0x060 ProcessEnvironmentBlock : Ptr64 _PEB

   +0x068 LastErrorValue   : Uint4B

   +0x06c CountOfOwnedCriticalSections : Uint4B

   +0x070 CsrClientThread  : Ptr64 Void

   +0x078 Win32ThreadInfo  : Ptr64 Void

   +0x080 User32Reserved   : [26] Uint4B

   +0x0e8 UserReserved     : [5] Uint4B

   +0x100 WOW32Reserved    : Ptr64 Void

   +0x108 CurrentLocale    : Uint4B

   +0x10c FpSoftwareStatusRegister : Uint4B

   +0x110 ReservedForDebuggerInstrumentation : [16] Ptr64 Void

   +0x190 SystemReserved1  : [38] Ptr64 Void

   +0x2c0 ExceptionCode    : Int4B

   +0x2c4 Padding0         : [4] UChar

   +0x2c8 ActivationContextStackPointer : Ptr64 _ACTIVATION_CONTEXT_STACK

   +0x2d0 InstrumentationCallbackSp : Uint8B

   +0x2d8 InstrumentationCallbackPreviousPc : Uint8B

   +0x2e0 InstrumentationCallbackPreviousSp : Uint8B

   +0x2e8 TxFsContext      : Uint4B

   +0x2ec InstrumentationCallbackDisabled : UChar

   +0x2ed Padding1         : [3] UChar

   +0x2f0 GdiTebBatch      : _GDI_TEB_BATCH

   +0x7d8 RealClientId     : _CLIENT_ID

   +0x7e8 GdiCachedProcessHandle : Ptr64 Void

   +0x7f0 GdiClientPID     : Uint4B

   +0x7f4 GdiClientTID     : Uint4B

   +0x7f8 GdiThreadLocalInfo : Ptr64 Void

   +0x800 Win32ClientInfo  : [62] Uint8B

   +0x9f0 glDispatchTable  : [233] Ptr64 Void

   +0x1138 glReserved1      : [29] Uint8B

   +0x1220 glReserved2      : Ptr64 Void

   +0x1228 glSectionInfo    : Ptr64 Void

   +0x1230 glSection        : Ptr64 Void

   +0x1238 glTable          : Ptr64 Void

   +0x1240 glCurrentRC      : Ptr64 Void

   +0x1248 glContext        : Ptr64 Void

   +0x1250 LastStatusValue  : Uint4B

   +0x1254 Padding2         : [4] UChar

   +0x1258 StaticUnicodeString : _UNICODE_STRING

   +0x1268 StaticUnicodeBuffer : [261] Wchar

   +0x1472 Padding3         : [6] UChar

   +0x1478 DeallocationStack : Ptr64 Void

   +0x1480 TlsSlots         : [64] Ptr64 Void

   +0x1680 TlsLinks         : _LIST_ENTRY

   +0x1690 Vdm              : Ptr64 Void

   +0x1698 ReservedForNtRpc : Ptr64 Void

   +0x16a0 DbgSsReserved    : [2] Ptr64 Void

   +0x16b0 HardErrorMode    : Uint4B

   +0x16b4 Padding4         : [4] UChar

   +0x16b8 Instrumentation  : [11] Ptr64 Void

   +0x1710 ActivityId       : _GUID

   +0x1720 SubProcessTag    : Ptr64 Void

   +0x1728 PerflibData      : Ptr64 Void

   +0x1730 EtwTraceData     : Ptr64 Void

   +0x1738 WinSockData      : Ptr64 Void

   +0x1740 GdiBatchCount    : Uint4B

   +0x1744 CurrentIdealProcessor : _PROCESSOR_NUMBER

   +0x1744 IdealProcessorValue : Uint4B

   +0x1744 ReservedPad0     : UChar

   +0x1745 ReservedPad1     : UChar

   +0x1746 ReservedPad2     : UChar

   +0x1747 IdealProcessor   : UChar

   +0x1748 GuaranteedStackBytes : Uint4B

   +0x174c Padding5         : [4] UChar

   +0x1750 ReservedForPerf  : Ptr64 Void

   +0x1758 ReservedForOle   : Ptr64 Void

   +0x1760 WaitingOnLoaderLock : Uint4B

   +0x1764 Padding6         : [4] UChar

   +0x1768 SavedPriorityState : Ptr64 Void

   +0x1770 ReservedForCodeCoverage : Uint8B

   +0x1778 ThreadPoolData   : Ptr64 Void

   +0x1780 TlsExpansionSlots : Ptr64 Ptr64 Void

   +0x1788 DeallocationBStore : Ptr64 Void

   +0x1790 BStoreLimit      : Ptr64 Void

   +0x1798 MuiGeneration    : Uint4B

   +0x179c IsImpersonating  : Uint4B

   +0x17a0 NlsCache         : Ptr64 Void

   +0x17a8 pShimData        : Ptr64 Void

   +0x17b0 HeapVirtualAffinity : Uint2B

   +0x17b2 LowFragHeapDataSlot : Uint2B

   +0x17b4 Padding7         : [4] UChar

   +0x17b8 CurrentTransactionHandle : Ptr64 Void

   +0x17c0 ActiveFrame      : Ptr64 _TEB_ACTIVE_FRAME

   +0x17c8 FlsData          : Ptr64 Void

   +0x17d0 PreferredLanguages : Ptr64 Void

   +0x17d8 UserPrefLanguages : Ptr64 Void

   +0x17e0 MergedPrefLanguages : Ptr64 Void

   +0x17e8 MuiImpersonation : Uint4B

   +0x17ec CrossTebFlags    : Uint2B

   +0x17ec SpareCrossTebBits : Pos 0, 16 Bits

   +0x17ee SameTebFlags     : Uint2B

   +0x17ee SafeThunkCall    : Pos 0, 1 Bit

   +0x17ee InDebugPrint     : Pos 1, 1 Bit

   +0x17ee HasFiberData     : Pos 2, 1 Bit

   +0x17ee SkipThreadAttach : Pos 3, 1 Bit

   +0x17ee WerInShipAssertCode : Pos 4, 1 Bit

   +0x17ee RanProcessInit   : Pos 5, 1 Bit

   +0x17ee ClonedThread     : Pos 6, 1 Bit

   +0x17ee SuppressDebugMsg : Pos 7, 1 Bit

   +0x17ee DisableUserStackWalk : Pos 8, 1 Bit

   +0x17ee RtlExceptionAttached : Pos 9, 1 Bit

   +0x17ee InitialThread    : Pos 10, 1 Bit

   +0x17ee SessionAware     : Pos 11, 1 Bit

   +0x17ee LoadOwner        : Pos 12, 1 Bit

   +0x17ee LoaderWorker     : Pos 13, 1 Bit

   +0x17ee SpareSameTebBits : Pos 14, 2 Bits

   +0x17f0 TxnScopeEnterCallback : Ptr64 Void

   +0x17f8 TxnScopeExitCallback : Ptr64 Void

   +0x1800 TxnScopeContext  : Ptr64 Void

   +0x1808 LockCount        : Uint4B

   +0x180c WowTebOffset     : Int4B

   +0x1810 ResourceRetValue : Ptr64 Void

   +0x1818 ReservedForWdf   : Ptr64 Void

   +0x1820 ReservedForCrt   : Uint8B

   +0x1828 EffectiveContainerId : _GUID



중요한 것은 _NT_TIB와 Ptr64_PEB 입니다.


핵심원리에서는 30 offset만큼 떨어져있는데 windows 10 x64에서는 60 offset만큼 떨어져 있습니다.


먼저 _NT_TIB에 대해서 알아보도록 하겠습니다.



ExceptionList는 _EXECPETION_REGISTRATION_RECODE 구조체 링크드 리스트를 가리키고 있습니다. Structured Exception Handler (SEH)라고 하는 Windows 예외 처리 메커니즘에 사용됩니다.


Self는 _NT_TIB 구조체 자기 자신 포인터입니다. 





User Mode TEB 접근


User Mode에서 TEB에 접근을 하려면 NtCurrentTeb()를 이용하면 됩니다.


이 API는 현재 thread의 TEB 구조체 주소를 리턴하는 함수입니다. 





abexcm1.exe를 가지고 열어봤더니 값이 들어있지 않았습니다.



그래서 64bit notepad.exe를 가지고 확인해 봤습니다.



ntdll에서 ntcurrentteb 함수가 존재하지 않는것을 알 수있었습니다.


구글 검색을 통해서 좀 더 알아봤는데, x64에서는 TEB가 FS 레지스터가 아닌 GS 레지스터로 바뀌었다고 합니다.


출처: http://www.nynaeve.net/?p=180



출처: http://blog.rewolf.pl/blog/?p=102#.UMg6zi2wc5c


FS:[18]의 값이 GS:[30]으로 되어있습니다.




일단 32bit 기준으로 정리해야겠다.



Segment Descriptor Table


FS 세그먼트 레지스터는 현재 thread의 TEB를 가리키는데 사용된다. 32비트 운영체제에서는 메모리가 4G인데 FS 레지스터는 16bit 입니다.

16bit를 이용해서 메모리 전체를 어떻게 가리킬 수 있을까요?


실제로 FS 레지스터가 직접 TEB 주소를 가리키는게 아니라 TEB 주소를 가지고 있는 segment Descriptor Table의 Index 값을 가지고 있습니다.


Segment Descriptor Table은 커널 메모리 영역에 존재하고, Global Descriptor Table Register (GDTR)에 그 주소가 저장되어 있습니다.


FS:[0x18] = TEB 시작주소

FS:[0x18] = TEB.NtTib.Self = address of TIB = address of TEB = FS:0 = 7ffdf000


FS:[0x30] = PEB 시작주소

FS:[0x30] = TEB.ProcessEnvironmentBloc = address of PEB


FS:[0x0] = SEH 시작주소

FS:[0x0] = TEB.NtTib.ExceptionList = addresss of SEH


'High Level Technique > Reversing' 카테고리의 다른 글

Structured Exception Handler (SEH)  (0) 2016.08.04
Process Environment Block (PEB)  (0) 2016.08.02
Thread Local Storage CallBack (TLS)  (0) 2016.08.01
DLL Injection in kernel 6  (0) 2016.07.27
Session in Kernel 6  (0) 2016.07.26