TLS反调试
TLS
TLS是Thread Local Storage的缩写,线程局部存储,主要是为了解决多线程中的变量同步的问题
TLS的意义
进程中的全局变量与函数内定义的静态(static)变量,是各个线程都可以访问的共享变量。在一个线程修改的内存内容,对所有的线程都生效。这是一个优点也是一个缺点,优点是交换数据快,缺点是多个数据访问共享数据,需要昂贵的同步开销,也容易造成同步相关的BUG
如果需要在一个线程内部的各个函数调用都能访问、但其它线程不能访问的变量(被称为static memory local to a thread 线程局部静态变量),就需要新的机制TLS来处理。
TLS变量
当线程A去修改TLS变量的时候,TLS变量不会有影响,每个人都有一个TLS变量的副本,互不影响。
创建TLS变量
_declspec(thread) int g_number = 100;
TLS代码实践
https://www.cnblogs.com/Sna1lGo/p/14466889.html
TLS用途2
TLS在安全领域中,常被用来处理如反调试、抢占执行等操作
TLS回调函数
1 首先加上编译选项
#pragma comment(linker,"/INCLUDE:__tls used")
2
/*
注册TLS函数 .CRT$XLX的作用
CRT表示使用C Runtime机制
X表示表示名随机
L表示TLS Callback section
X也可以换成B~Y任意一个字符
*/
#pragma data_seg(".CRT$XLX")
//存储回调函数地址
PIMAGE_TLS_CALLBACK pTLS_CALLBACKs[]= {TLS_CALLBACK1,0};
//这个数组才是TLS的关键
#pragma data_seg()
TLS回调函数格式
void NTAPI t_TlsCallBack_A(PVOID DllHandle, DWORD Reason, PVOID Reserved)
{
}
TLS函数何时被调用
当一个程序被调用的时候,先执行TLS函数后,再跳转到程序的IMAGEBASE执行PE文件结构。
可以在TLS函数中添加代码来防止程序被调试
PE文件中的TLS表
也是可选pe头的数据目录表下面的一个内容,但是索引是9
//TLS结构体
typedef struct _IMAGE_TLS_DIRECTORY32 {
DWORD StartAddressOfRawData;
DWORD EndAddressOfRawData;
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;
typedef IMAGE_TLS_DIRECTORY32 * PIMAGE_TLS_DIRECTORY32;