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实现了反调试