1.静态tls将变量定义在PE文件内部. 使用.tls节存储
.tls节中包含:
初始化数据
用于每个线程初始化和终止的回调函数
TLS索引
2.代码访问tls数据时经过的步骤:
(1) 链接时, 链接器设置tls目录中的AddressOfIndex字段. 该字段指向一个位置,该位置保存了程序用到的tls索引
(2) 创建线程时, 将TEB的地址放入fs寄存器来传递tls数组地址. teb+0x2c处字段指向tls数组
(3) 将tls索引值保存到AddressOfIndex字段指向的位置
(4)获取tls索引和tls数组位置
(5)访问
3.PE中tls节及其数据结构
typedef struct _IMAGE_TLS_DIRECTORY32 { DWORD StartAddressOfRawData; //tls模板起始地址 DWORD EndAddressOfRawData; //tls模板结束地址 DWORD AddressOfIndex; // PDWORD 索引位置 DWORD AddressOfCallBacks; // PIMAGE_TLS_CALLBACK * 回调函数数组指针 DWORD SizeOfZeroFill; // union { //保留 DWORD Characteristics; struct { DWORD Reserved0 : 20; DWORD Alignment : 4; DWORD Reserved1 : 8; } DUMMYSTRUCTNAME; } DUMMYUNIONNAME; } IMAGE_TLS_DIRECTORY32;
tls回调函数:
typedef VOID (NTAPI *PIMAGE_TLS_CALLBACK) ( PVOID DllHandle, DWORD Reason, PVOID Reserved );
4. 所以通过数据目录项中定位到tls表基址后, 就可以获取tls回调函数地址,然后查看是否通过tls实现了反调试