線程信息塊
外觀
此條目需要補充更多來源。 (2019年1月12日) |
Win32線程信息塊(TIB)是32位Windows作業系統的線程使用的數據結構,存儲了每個線程的運行時信息。 也稱作「線程環境塊」(Thread Environment Block,TEB)。[1]
Windows NT系列的DDK在winnt.h中包括了一個struct NT_TIB,為獨立於subsystem的部分。Wine包含了TIB與subsystem相關的擴展部分。由於非常多程序使用了TIB,事實上TIB成為Windows API的一部分。[1]
TIB可用於獲取很多進程相關信息,而不必調用Win32 API。例如,模擬GetLastError()或GetVersion()。通過PEB可以獲取訪問導入表(import table, IAT)、進程啟動參數、程序名字等。
32位程序通過FS段寄存器,64位程序通過GS段寄存器可以獲得TIB
TIB的內容
[編輯]字節/
類型 |
偏移
(32 比特, FS) |
偏移
(64 比特, GS) |
Windows 版本 | 描述 |
---|---|---|---|---|
pointer | FS:[0x00] | GS:[0x00] | Win9x and NT | 當前結構化異常 (SEH) 幀 |
pointer | FS:[0x04] | GS:[0x08] | Win9x and NT | 棧基 / 棧底部 (高地址) |
pointer | FS:[0x08] | GS:[0x10] | Win9x and NT | 棧上限 / 棧的天頂 (低地址) |
pointer | FS:[0x0C] | GS:[0x18] | NT | SubSystemTib |
pointer | FS:[0x10] | GS:[0x20] | NT | 纖程數據 |
pointer | FS:[0x14] | GS:[0x28] | Win9x and NT | 任意數據slot |
pointer | FS:[0x18] | GS:[0x30] | Win9x and NT | TEB的線性地址 |
---- 以上為獨立於NT subsystem的部分 ---- | ||||
pointer | FS:[0x1C] | GS:[0x38] | NT | 環境指針 |
pointer | FS:[0x20] | GS:[0x40] | NT | 進程ID (某些Windows版本這裏也用作 'DebugContext') |
4 | FS:[0x24] | GS:[0x48] | NT | 當前線程ID |
4 | FS:[0x28] | GS:[0x54] | NT | 活動的RPC句柄 |
4 | FS:[0x2C] | GS:[0x58] | Win9x and NT | 線程局部存儲數組的線性地址 |
4 | FS:[0x30] | GS:[0x60] | NT | PEB的線性地址 |
4 | FS:[0x34] | GS:[0x68] | NT | 最後一個錯誤號 |
4 | FS:[0x38] | NT | 擁有的臨界區數量 | |
4 | FS:[0x3C] | NT | CSR客戶線程地址 | |
4 | FS:[0x40] | NT | Win32線程信息 | |
124 | FS:[0x44] | NT, Wine | Win32客戶信息(NT), user32私有數據(Wine), 0x60 = LastError (Win95), 0x74 = LastError (WinME) | |
4 | FS:[0xC0] | NT | 保留給Wow64.到FastSysCall的指針 | |
4 | FS:[0xC4] | NT | 當前Locale | |
4 | FS:[0xC8] | NT | FP軟件狀態寄存器 | |
216 | FS:[0xCC] | NT, Wine | 保留給OS (NT), kernel32私有數據(Wine) 因此: FS:[0x124] 4 NT 到 KTHREAD (ETHREAD)結構的指針 | |
4 | FS:[0x1A4] | NT | 異常碼 | |
18 | FS:[0x1A8] | NT | 活動上下文棧 | |
24 | FS:[0x1BC] | NT, Wine | 空閒字節(NT), ntdll私有數據(Wine) | |
40 | FS:[0x1D4] | NT, Wine | 保留給OS (NT), ntdll私有數據(Wine) | |
1248 | FS:[0x1FC] | NT, Wine | GDI TEB Batch (OS), vm86私有數據(Wine) | |
4 | FS:[0x6DC] | NT | GDI Region | |
4 | FS:[0x6E0] | NT | GDI Pen | |
4 | FS:[0x6E4] | NT | GDI Brush | |
4 | FS:[0x6E8] | NT | 真實進程ID | |
4 | FS:[0x6EC] | NT | 真實線程ID | |
4 | FS:[0x6F0] | NT | GDI緩存的進程句柄 | |
4 | FS:[0x6F4] | NT | GDI客戶進程ID (PID) | |
4 | FS:[0x6F8] | NT | GDI客戶線程ID (TID) | |
4 | FS:[0x6FC] | NT | GDI線程locale信息 | |
20 | FS:[0x700] | NT | 保留給用戶應用程式 | |
1248 | FS:[0x714] | NT | 保留給GL | |
4 | FS:[0xBF4] | GS:[0x1250] | NT | 最後狀態值 |
532 | FS:[0xBF8] | GS:[0x1258] | NT | 靜態UNICODE_STRING緩衝區 |
pointer | FS:[0xE0C] | GS:[0x1478] | NT | 分配格棧的內存地址 |
pointer[] | FS:[0xE10] | GS:[0x1480] | NT | TLS槽, 4/8位元組每槽,64個槽 |
8 | FS:[0xF10] | GS:[0x1680] | NT | TLS連結(LIST_ENTRY結構) |
4 | FS:[0xF18] | NT | VDM | |
4 | FS:[0xF1C] | NT | 保留給RPC | |
4 | FS:[0xF28] | NT | 線程錯誤模式(RtlSetThreadErrorMode) |
訪問TIB
[編輯]// gcc (AT&T-style inline assembly).
void *getTIB() {
void *pTIB;
__asm__("movl %%fs:0x18, %0" : "=r" (pTIB) : : );
return pTIB;
}
// Microsoft C
__declspec(naked)
void *getTIB() {
__asm mov EAX, FS:[18h]
}
// Using Microsoft's intrinsics instead of inline assembly (works for both X86 and X64 architectures)
void *getTIB() {
#ifdef _M_IX86
return (void *)__readfsdword(0x18);
#elif _M_AMD64
return (void *)__readgsqword(0x30);
#endif
}
參見
[編輯]參考文獻
[編輯]- ^ 1.0 1.1 Pietrek, Matt. Under The Hood. Microsoft Systems Journal. May 1996 [2010-07-07]. (原始內容存檔於2016-03-03).
進一步閱讀
[編輯]- Pietrek, Matt. Windows 95 Programming Secrets (PDF). IDG. March 1996: 136–138 [2010-07-17]. ISBN 978-1-56884-318-6. (原始內容 (pdf)存檔於2011-05-14).