Win32 스레드 정보 블록
Win32 Thread Information Block![]() | 이 기사는 업데이트가 필요합니다.(2013년 12월) |
컴퓨팅에서 Win32 TIB(Thread Information Block)는 현재 실행 중인 스레드에 대한 정보를 저장하는 x86의 Win32의 데이터 구조입니다.Win32의 스레드 환경 블록(TEB)이라고도 합니다.OS/[1]2와 유사한 구조를 가진 32비트 시스템에서 파생되었으며 이전 버전과 호환됩니다.
TIB는 Windows 9x용으로 공식 문서화되어 있지 않습니다.Windows NT 시리즈 DDK(및 MinGW/React)OS 구현)에는 하위 시스템 독립 부분을 문서화하는 winnt.h의 NT_TIB 구조가 포함되어 있습니다.TIB가 효과적으로 문서화되기 전에도 많은 응용프로그램이 이미 해당 필드를 사용하기 시작하여 API의 일부가 되었습니다.특히 SEH 프레임을 포함하는 첫 번째 필드는 Microsoft의 자체 [1]컴파일러에서 생성된 코드에 의해 직접 참조됩니다.TEB의 Win32 하위 시스템 관련 부분은 문서화되어 있지 않지만, Wine에는 Winterl.[2]h에 TEB 정의가 포함되어 있습니다.
TIB를 사용하면 Win32 API를 호출하지 않고도 프로세스에 대한 많은 정보를 얻을 수 있습니다.예를 들어 GetLastError(), GetVersion()의 에뮬레이션이 있습니다.PEB에 대한 포인터를 통해 가져오기 테이블(IAT), 프로세스 시작 인수, 이미지 이름 등에 액세스할 수 있습니다.32비트 윈도우즈의 FS 세그먼트 레지스터와 64비트 윈도우즈의 GS에서 액세스할 수 있습니다.
Windows의 TIB 내용
이 표는 Microsoft Windows [2]내부에 대한 Wine의 작업을 기반으로 합니다.
바이트/ 유형 | 오프셋(32비트, FS) | 오프셋(64비트, GS) | Windows 버전 | 묘사 |
---|---|---|---|---|
포인터 | FS:[0x00] | GS:[0x00] | Win9x 및 NT | 현재 구조화된 예외 처리(SEH) 프레임 |
포인터 | FS:[0x04] | GS:[0x08] | Win9x 및 NT | 스택 베이스 / 스택 맨 아래(높은 주소) |
포인터 | FS:[0x08] | GS:[0x10] | Win9x 및 NT | 스택 한계 / 스택의 상한(낮은 주소) |
포인터 | FS:[0x0C] | GS:[0x18] | NT | 하위 시스템 팁 |
포인터 | FS:[0x10] | GS:[0x20] | NT | 섬유 데이터 |
포인터 | FS:[0x14] | GS:[0x28] | Win9x 및 NT | 임의 데이터 슬롯 |
포인터 | FS:[0x18] | GS:[0x30] | Win9x 및 NT | TEB의 선형 주소 |
NT 하위 시스템 독립 부분의 끝. 아래는 Win32 의존적입니다. | ||||
포인터 | FS:[0x1C] | GS:[0x38] | NT | 환경 포인터 |
포인터 | FS:[0x20] | GS:[0x40] | NT | 프로세스 ID(일부 Windows 배포에서 이 필드는 'DebugContext'로 사용됨) |
포인터 | FS:[0x24] | GS:[0x48] | NT | 현재 스레드 ID |
포인터 | FS:[0x28] | GS:[0x50] | NT | 활성 RPC 핸들 |
포인터 | FS:[0x2C] | GS:[0x58] | Win9x 및 NT | 스레드 로컬 스토리지 어레이의 선형 주소 |
포인터 | FS:[0x30] | GS:[0x60] | NT | 프로세스 환경 블록(PEB)의 선형 주소 |
4 | FS:[0x34] | GS:[0x68] | NT | 마지막 오류 번호 |
4 | FS:[0x38] | GS:[0x6C] | NT | 소유한 중요 섹션 수 |
포인터 | FS:[0x3C] | GS:[0x70] | NT | CSR 클라이언트 스레드의 주소 |
포인터 | FS:[0x40] | GS:[0x78] | NT | Win32 스레드 정보 |
124 | FS:[0x44] | GS:[0x80] | NT, 와인 | Win32 클라이언트 정보(NT), user32 개인 데이터(Wine), 0x60 = 마지막 오류(Win95&98), 0x74 = 마지막 오류(WinME) |
포인터 | FS:[0xC0] | GS:[0x100] | NT | Wow64로 예약되어 있습니다.Wow64의 FastSysCall 포인터를 포함합니다. |
4 | FS:[0xC4] | GS:[0x108] | NT | 현재 로케일 |
4 | FS:[0xC8] | GS:[0x10C] | NT | FP 소프트웨어 상태 레지스터 |
216 | FS:[0xCC] | GS:[0x110] | NT, 와인 | OS(NT), 커널32 개인 데이터(Wine)용으로 예약됨 여기: FS:[0x124] 4 NT 포인터 - KTHREAD(ETHREAD) 구조 |
4 | FS:[0x1A4] | GS:[0x2C0] | NT | 예외코드 |
18 | FS:[0x1A8] | GS:[0x2C8] | NT | 활성화 컨텍스트 스택 |
24 | FS:[0x1BC] | GS:[0x2E8] | NT, 와인 | 예비 바이트(NT), ntdll 개인 데이터(와인) |
40 | FS:[0x1D4] | GS:[0x300] | NT, 와인 | OS(NT), ntdll 개인 데이터(Wine)용으로 예약됨 |
1248 | FS:[0x1FC] | GS:[0x350] | NT, 와인 | GDI TEB 배치(OS), vm86 개인 데이터(Wine) |
4 | FS:[0x6DC] | GS:[0x838] | NT | GDI 영역 |
4 | FS:[0x6E0] | GS:[0x840] | NT | GDI 펜 |
4 | FS:[0x6E4] | GS:[0x848] | NT | GDI 브러시 |
4 | FS:[0x6E8] | GS:[0x850] | NT | 실제 프로세스 ID |
4 | FS:[0x6EC] | GS:[0x858] | NT | 실제 스레드 ID |
4 | FS:[0x6F0] | GS:[0x860] | NT | GDI 캐시된 프로세스 핸들 |
4 | FS:[0x6F4] | GS:[0x868] | NT | GDI 클라이언트 프로세스 ID(PID) |
4 | FS:[0x6F8] | GS:[0x86C] | NT | GDI 클라이언트 스레드 ID(TID) |
4 | FS:[0x6FC] | GS:[0x870] | NT | GDI 스레드 로케일 정보 |
20 | FS:[0x700] | GS:[0x878] | NT | 사용자 응용 프로그램용으로 예약됨 |
1248 | FS:[0x714] | GS:[0x890] | NT | GL용으로 예약됨(내부 [2]정보는 와인 참조 참조) |
4 | FS:[0xBF4] | GS:[0x1250] | NT | 마지막 상태 값 |
532 | FS:[0xBF8] | GS:[0x1258] | NT | 정적 UNICODE_STRING 버퍼 |
포인터 | FS:[0xE0C] | GS:[0x1478] | NT | DeallocationStack이라고도 하며, 스택 버퍼의 실제 시작 주소를 설정하므로 실제 스택 제한: 스택 제한 필드(스택 오버플로를 탐지하는 데 사용되는 가드 페이지를 숨김)보다 몇 페이지 적습니다. |
포인터[] | FS:[0xE10] | GS:[0x1480] | NT | TLS 슬롯, 슬롯당 4/8바이트, 64개 슬롯 |
8 | FS:[0xF10] | GS:[0x1680] | NT | TLS 링크(LIST_ENTRY 구조) |
4 | FS:[0xF18] | GS:[0x1690] | NT | VDM |
4 | FS:[0xF1C] | GS:[0x1698] | NT | RPC용으로 예약됨 |
4 | FS:[0xF28] | GS:[0x16B0] | NT | 스레드 오류 모드(RtlSetThreadErrorMode) |
4 | FS:[0xF78] | GS:[0x1748] | NT | 보장된 스택 바이트 |
이 표는 전체 표가 아닙니다. FS:[0xfb4] / GS:[17c8][2]까지 모든 필드에 대한 와인 참조를 참조하십시오.최신 Windows 버전은 TIB 크기를 Windows 10에서 최대 0x1000/0x1838까지 확장합니다.추가된 필드 중 일부가 제거되어 [3]정의가 충돌합니다. |
FS(32비트용) 또는 GS(64비트용)는 TDB(스레드 데이터베이스)라고 하는 데이터 블록에 내장된 TIB에 매핑됩니다.TIB에는 스레드별 예외 처리 체인과 TLS(스레드 로컬 스토리지)에 대한 포인터가 포함되어 있습니다.스레드 로컬 스토리지가 C 로컬 스토리지와 동일하지 않습니다.
TIB에 저장된 스택 정보
프로세스는 TIB에 저장된 정보를 적절히 업데이트하는 한 스레드 스택을 자유롭게 이동할 수 있어야 합니다.스택 기본, 스택 제한, 할당 해제 스택 및 보장된 스택 바이트 등 몇 가지 필드가 이 문제의 핵심이며, 각각 오프셋 0x8, 0x10, 0x1478 및 0x1748에 64비트로 저장됩니다.서로 다른 Windows 커널 기능은 특히 스택 오버플로를 다른 읽기/쓰기 페이지 장애와 구별하기 위해 이러한 값을 읽고 씁니다(보증된 스택 바이트의 스택 제한 사이에서 보호되는 페이지에 대한 읽기 또는 쓰기는 액세스 위반 대신 스택 오버플로 예외를 생성합니다).할당 취소 스택은 Windows API를 사용하여 보호된 페이지의 양을 변경할 수 있기 때문에 중요합니다. SetThreadStackGuarantee 함수를 사용하면 현재 공간을 읽고 확장할 수 있습니다.읽기 위해 GuaranteeStackBytes 필드를 읽고, 이 필드를 확장하려면 스택 페이지를 커밋 해제해야 합니다.DeallocationStack을 설정하지 않고 스택 제한을 설정하면 SetThreadStackGuarantee에서 이상한 동작이 발생할 수 있습니다.예를 들어 스택 한계를 잘못된 값으로 덮어씁니다.다른 라이브러리에서는 SetThreadStackGuarantee를 호출합니다(예: ).NET CLR은 스레드 스택을 설정하는 데 사용합니다.
TIB 액세스
현재 스레드의 TIB는 세그먼트 레지스터 FS(x86) 또는 GS(x64)의 오프셋으로 액세스할 수 있습니다.
에서 오프셋을 사용하여 TIB 필드에 액세스하는 것은 일반적이지 않습니다.FS:[0]
하지만 오히려 먼저 저장된 선형 자체 참조 포인터를 얻습니다.FS:[18h]
이 포인터는 포인터 산술과 함께 사용되거나 구조 포인터에 캐스팅될 수 있습니다.
Microsoft Windows SDK 또는 유사한 기능을 사용하면 프로그래머는 다음에 정의된 인라인 함수를 사용할 수 있습니다.winnt.h
이름 지어진NtCurrentTeb
현재 스레드 정보 블록의 주소를 다음과 같이 반환합니다.NT_TIB *
.[4]
IA-32 아키텍처에 대한 대체 액세스 방법은 다음과 같습니다.
gcc(AT&T 스타일 인라인 어셈블리). 무효의 *TIB를 획득합니다.(무효의) { 등록하세요 무효의 *pTIB; #정의된 경우(_x86_64__) 정의된 경우(_amd64__) __asm__("movq %%gs:0x30, %0" : "=r" (pTIB)); #ellif 정의(_i386__) __asm__("movl %%fs:0x18, %0" : "=r" (pTIB)); #오페라의 #오류 지원되지 않는 아키텍처 #엔디프 돌아가다 pTIB; }
gcc(이름이 지정된 주소 공간, -O1 또는 -ftree-ter의 인라인 어셈블리 버전과 동일). 무효의 *TIB를 획득합니다.(무효의) { #정의된 경우(_x86_64__) 정의된 경우(_amd64__) #ifndef __SEG_GS #error 지원되지 않는 GCC 버전 #엔디프 돌아가다 *(무효의 *__sk_gs *) 0x30; #ellif 정의(_i386__) #ifndef __SEG_FS #error 지원되지 않는 GCC 버전 #엔디프 돌아가다 *(무효의 *__fs *) 0x18; #오페라의 #오류 지원되지 않는 아키텍처 #엔디프 }
마이크로소프트 C __declspec(벌거벗은) 무효의 *TIB를 획득합니다.() { __asm 이사를 EAX, FS:[18h] __asm 리트 }
인라인 어셈블리 대신 Microsoft의 내장 기능 사용(X86 및 X64 아키텍처 모두에서 작동) 무효의 *TIB를 획득합니다.() { #ifdef_M_IX86 돌아가다 (무효의 *)__readfsdword(0x18); #elif _M_AMD64 돌아가다 (무효의 *)__readgsqword(0x30); #오페라의 #오류 지원되지 않는 아키텍처 #엔디프 }
참고 항목
레퍼런스
- ^ a b Pietrek, Matt (May 1996). "Under The Hood". Microsoft Systems Journal. Archived from the original on 2009-06-14. Retrieved 2010-07-07.
- ^ a b c d "wine winternl.h: typedef struct _TEB". GitHub. wine-mirror. 29 October 2019.
- ^ Chapell, Geoff. "TEB".
- ^ "NtCurrentTeb function". Microsoft Docs. Retrieved 20 November 2019.
진일보한 내용
- Pietrek, Matt (March 1996). Windows 95 Programming Secrets (pdf). IDG. pp. 136–138. ISBN 978-1-56884-318-6. Retrieved 2010-07-17.
{{cite book}}
CS1 유지보수: url-status(링크)