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. ^ 1.0 1.1 Pietrek, Matt. Under The Hood. Microsoft Systems Journal. May 1996 [2010-07-07]. (原始内容存档于2016-03-03). 

进一步阅读

编辑

外部链接

编辑