{{위키데이터 속성 추적}}
'''TIB ({{lang|en|Win32 Thread Information Block}})''' (TIB)은 Win32의 [[자료 구조]]로서 현재 실행 중인 [[스레드]]에 대한 정보를 저장하고 있다. 이 구조체는 또한 스레드 환경 블록 (TEB: Thread Environment Block)으로도 알려져 있다.<ref name="Pietrek-May96" />

이 TIB는 공식적으로 윈도 9x에서는 문서화되어 있지 않다. 윈도 NT 시리즈 DDK는 하위 시스템 독립적인 부분을 문서화한 winnt.h에 NT_TIB 구조체를 포함한다. [[와인 (소프트웨어)|와인]]은 확장된 (구체적인 하위 시스템 부분의) TIB를 위한 선언을 포함한다. 수 많은 Win32 프로그램들은 실질적으로 API의 한 부분이라고 할 수 있는 이 문서화되지 않은 필드들을 사용한다. 특히 첫 번째 필드는 마이크로소프트의 자체 컴파일러에서 직접적으로 코드에 의한 참조가 일어난다.<ref name="Pietrek-May96" />

TIB는 Win32 API를 호출하지 않고도 프로세스에 대한 많은 정보를 얻기 위해 사용될 수 있다. [[PEB]]를 가리키는 포인터를 통해서 IAT에 대한 접근, 프로세스 시작 인수, 이미지 이름 등을 얻을 수 있다.

== TIB의 내용 (32비트 윈도우) ==
{| class="wikitable" style="margin-bottom: 10px;"
! width="5%" |위치
! width="5%" |길이
! width="5%" |윈도우 버전
! width="40%" |설명
|-
| align="right" |FS:[0x00]
| align="right" |4
| align="right" |Win9x and NT
|현재 Structured Exception Handling (SEH) 프레임
|-
| align="right" |FS:[0x04]
| align="right" |4
| align="right" |Win9x and NT
|스택 베이스 / 스택의 바닥 (높은 주소)
|-
| align="right" |FS:[0x08]
| align="right" |4
| align="right" |Win9x and NT
|스택 한계 / 스택의 천장 (낮은 주소)
|-
| align="right" |FS:[0x0C]
| align="right" |4
| align="right" |NT
|SubSystemTib
|-
| align="right" |FS:[0x10]
| align="right" |4
| align="right" |NT
|[[스레드|Fiber data]]
|-
| align="right" |FS:[0x14]
| align="right" |4
| align="right" |Win9x and NT
|임의 데이터 슬롯
|-
| align="right" |FS:[0x18]
| align="right" |4
| align="right" |Win9x and NT
|Thread Environment Block
|-
| align="center" colspan="4" | ---- [[윈도우 NT 아키텍처|NT subsystem]] 독립적인 부분 끝 ----
|-
| align="right" |FS:[0x1C]
| align="right" |4
| align="right" |NT
|Environment Pointer
|-
| align="right" |FS:[0x20]
| align="right" |4
| align="right" |NT
|프로세스 ID (몇몇 윈도우 버전에서 이 필드는 'DebugContext'로 쓰인다.)
|-
| align="right" |FS:[0x24]
| align="right" |4
| align="right" |NT
|현재 스레드 ID
|-
| align="right" |FS:[0x28]
| align="right" |4
| align="right" |NT
|활동중인 RPC 핸들
|-
| align="right" |FS:[0x2C]
| align="right" |4
| align="right" |Win9x and NT
|thread-local storage 배열의 선형 주소
|-
| align="right" |FS:[0x30]
| align="right" |4
| align="right" |NT
|Process Environment Block (PEB)의 선형 주소
|-
| align="right" |FS:[0x34]
| align="right" |4
| align="right" |NT
|마지막 오류 번호
|-
| align="right" |FS:[0x38]
| align="right" |4
| align="right" |NT
|Count of owned critical sections
|-
| align="right" |FS:[0x3C]
| align="right" |4
| align="right" |NT
|CSR 클라이언트 스레드의 주소
|-
| align="right" |FS:[0x40]
| align="right" |4
| align="right" |NT
|Win32 스레드 정보
|-
| align="right" |FS:[0x44]
| align="right" |124
| align="right" |NT, Wine
|Win32 클라이언트 정보 (NT), user32 private data (Wine), 0x60 = LastError (Win95), 0x74 = LastError (WinME)
|-
| align="right" |FS:[0xC0]
| align="right" |4
| align="right" |NT
|Reserved for Wow64. Wow64에서 FastSysCall에 대한 포인터를 포함한다.
|-
| align="right" |FS:[0xC4]
| align="right" |4
| align="right" |NT
|Current Locale
|-
| align="right" |FS:[0xC8]
| align="right" |4
| align="right" |NT
|FP Software Status Register
|-
| align="right" |FS:[0xCC]
| align="right" |216
| align="right" |NT, Wine
|Reserved for OS (NT), kernel32 private data (Wine)
herein: FS:[0x124] 4 NT Pointer to KTHREAD (ETHREAD) structure
|-
| align="right" |FS:[0x1A4]
| align="right" |4
| align="right" |NT
|예외 코드
|-
| align="right" |FS:[0x1A8]
| align="right" |18
| align="right" |NT
|Activation context stack
|-
| align="right" |FS:[0x1BC]
| align="right" |24
| align="right" |NT, Wine
|Spare bytes (NT), ntdll private data (Wine)
|-
| align="right" |FS:[0x1D4]
| align="right" |40
| align="right" |NT, Wine
|Reserved for OS (NT), ntdll private data (Wine)
|-
| align="right" |FS:[0x1FC]
| align="right" |1248
| align="right" |NT, Wine
|GDI TEB Batch (OS), vm86 private data (Wine)
|-
| align="right" |FS:[0x6DC]
| align="right" |4
| align="right" |NT
|GDI Region
|-
| align="right" |FS:[0x6E0]
| align="right" |4
| align="right" |NT
|GDI 펜
|-
| align="right" |FS:[0x6E4]
| align="right" |4
| align="right" |NT
|GDI 브러시
|-
| align="right" |FS:[0x6E8]
| align="right" |4
| align="right" |NT
|Real Process ID
|-
| align="right" |FS:[0x6EC]
| align="right" |4
| align="right" |NT
|Real Thread ID
|-
| align="right" |FS:[0x6F0]
| align="right" |4
| align="right" |NT
|GDI cached process handle
|-
| align="right" |FS:[0x6F4]
| align="right" |4
| align="right" |NT
|GDI 클라이언트 프로세스 ID (PID)
|-
| align="right" |FS:[0x6F8]
| align="right" |4
| align="right" |NT
|GDI 클라이언트 스레드 ID (TID)
|-
| align="right" |FS:[0x6FC]
| align="right" |4
| align="right" |NT
|GDI thread locale information
|-
| align="right" |FS:[0x700]
| align="right" |20
| align="right" |NT
|Reserved for user application
|-
| align="right" |FS:[0x714]
| align="right" |1248
| align="right" |NT
|Reserved for GL
|-
| align="right" |FS:[0xBF4]
| align="right" |4
| align="right" |NT
|마지막 상태 값
|-
| align="right" |FS:[0xBF8]
| align="right" |532
| align="right" |NT
|Static UNICODE_STRING buffer
|-
| align="right" |FS:[0xE0C]
| align="right" |4
| align="right" |NT
|deallocation stack에 대한 포인터
|-
| align="right" |FS:[0xE10]
| align="right" |256
| align="right" |NT
|TLS 슬롯, 슬롯 당 4 byte
|-
| align="right" |FS:[0xF10]
| align="right" |8
| align="right" |NT
|TLS 링크 (LIST_ENTRY structure)
|-
| align="right" |FS:[0xF18]
| align="right" |4
| align="right" |NT
|VDM
|-
| align="right" |FS:[0xF1C]
| align="right" |4
| align="right" |NT
|Reserved for RPC
|-
| align="right" |FS:[0xF28]
| align="right" |4
| align="right" |NT
|스레드 에러 모드(RtlSetThreadErrorMode)
|}
FS는 TIB를 저장하는데, TDB(스레드 데이터 베이스)라고 알려진 데이터 블록에 내장되어 있다. TIB는 스레드에 관련된 예외 핸들링 체인과 TLS(thread local storage)에 대한 포인터를 포함한다.

노트: 위의 설명은 오직 x86 32비트 윈도우에서 설명하는 것이다. x86-64 (64-bit) 윈도우에서, GS (FS가 아니라)는 TIB를 가리키는 세그먼트 레지스터로 사용된다. 게다가 위 구조체의 몇몇 변수 슬롯들은 다른 크기를 가진다.

== TIB에 접근하기 ==
현재 스레드의 TIB는 세그먼트 [[프로세서 레지스터|레지스터]] FS (x86) 또는 GS (x64)의 오프셋으로 접근할 수 있다.

FS:[0]부터 오프셋으로 TIB 필드에 접근하는 것 대신 FS:[0x18]에 저장된 먼저 선형 자기 참조 포인터를 가지는 것이 TIB 필드에 접근하는 보편적인 방식이다. 이 포인터는 포인터 연산 등에 사용될 수 있다.

32-bit x86에서의 C inlined-assembly 예시:<syntaxhighlight lang="c">
// gcc (AT&T-style inline assembly).
void *getTIB() {
    void *pTIB;
    __asm__("movl %%fs:0x18, %0" : "=r" (pTIB) : : );
    return pTIB;
}
</syntaxhighlight><syntaxhighlight lang="c">
// Microsoft C
void *getTIB() {
    void *pTIB;
    __asm {
        mov EAX, FS:[0x18]
        mov pTIB, EAX
    }
    return pTIB;
}
</syntaxhighlight><syntaxhighlight lang="c">
// Using Microsoft's intrinsics instead of inline assembly
void *getTIB() {
    return = (void *)__readfsdword(0x18);
}
</syntaxhighlight>

== 같이 보기 ==
* [[마이크로소프트의 예외 처리 메커니즘]](SEH)

== 각주 ==
{{각주|refs=
<ref name="Pietrek-May96">{{저널 인용
 |제목       = Under The Hood
 |저널       = Microsoft Systems Journal
 |날짜       = 1996-05
 |이름       = Matt
 |성          = Pietrek
 |url          = http://www.microsoft.com/msj/archive/s2ce.aspx
 |확인날짜 = 2016-02-11
 |보존url    = https://web.archive.org/web/20160303235154/http://www.microsoft.com/msj/archive/s2ce.aspx
 |보존날짜 = 2016-03-03
 |url-status = dead
}}</ref>
}}

== 관련 문헌 ==
* {{서적 인용 | url=http://cs.mipt.ru/docs/comp/eng/os/win32/win95_sys_progr_secr/main.pdf | 제목=Windows 95 Programming Secrets | 저자=Pietrek, Matt | 날짜=1996-03 | 출판사=IDG | ISBN=1-56884-318-6 | 쪽=136–138 | 형식=PDF | 확인날짜=2010-07-17 | 보존url=https://web.archive.org/web/20110514140137/http://cs.mipt.ru/docs/comp/eng/os/win32/win95_sys_progr_secr/main.pdf | 보존날짜=2011-05-14 | url-status=dead }}

== 외부 링크 ==
* [http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/Thread/TEB.html TEB layout on NTinternals.net] {{웨이백|url=http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/Thread/TEB.html |date=20201102051026 }}
* [https://web.archive.org/web/20150929000043/http://www.microsoft.com/msj/0197/exception/exception.aspx Structured Exception Handling and the TIB]

[[분류:마이크로소프트 API]]
[[분류:스레드]]