什么是TLS
TLS(Thread Local Storage)是给定多线程进程中的每个线程可以分配存储线程特定数据的位置的方法。使用TLS技术可以在线程内部独立使用或修改进程的全局数据或静态数据, 就像对待自身的局部变量一样。
TLS通常被用于反调试,因为TLS可以在程序的入口点(EP,Entry Point)前执行函数。
TLS回调函数的定义
typedef VOID (NTAPI *PIMAGE_TLS_CALLBACK) (PVOID DllHandle, DWORD Reason, PVOID Reserved);
其中,Reson
的取值为
#define DLL_PROCESS_ATTACH 1 //进程/主线程启动
#define DLL_THREAD_ATTACH 2 //子线程启动
#define DLL_THREAD_DETACH 3 //子线程关闭
#define DLL_PROCESS_ATTACH 0 //主线程关闭
各回调函数的执行时机
我们用下面的这样一段代码来进行测试:
#include
#include
//告诉链接器使用tls
#ifdef _M_X64
#pragma comment (linker, "/INCLUDE:_tls_used")
#pragma comment (linker, "/INCLUDE:_tls_callback")
#else
#pragma comment (linker, "/INCLUDE:__tls_used")
#pragma comment (linker, "/INCLUDE:__tls_callback")
#endif
static int exec_order = 0;
void print(const char* szMsg)
{
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
WriteConsoleA(hStdout, szMsg, strlen(szMsg), NULL, NULL);
}
void NTAPI TLS_CALLBACK(PVOID DllHandle, DWORD Reason, PVOID Reserved)
{
switch (Reason)
{
case DLL_PROCESS_ATTACH:
exec_order++;
printf("order: %d, reason == 1: process attach\n", exec_order);
break;
case DLL_THREAD_ATTACH:
exec_order++;
printf("order: %d, reason == 2: thread attach\n", exec_order);
break;
case DLL_THREAD_DETACH:
exec_order++;
printf("order: %d, reason == 3: thread detach\n", exec_order);
break;
case DLL_PROCESS_DETACH:
exec_order++;
printf("order: %d, reason == 0: process detach\n", exec_order);
break;
default:
break;
}
}
//创建tls段
EXTERN_C
#ifdef _M_X64
#pragma const_seg (".CRT$XLB")
const
#else
#pragma data_seg (".CRT$XLB")
#endif
PIMAGE_TLS_CALLBACK _tls_callback[] = { TLS_CALLBACK, 0 };
#pragma data_seg ()
#pragma const_seg ()
DWORD WINAPI SubThread(LPVOID lParam)
{
exec_order++;
printf("order: %d, subthread start!\n", exec_order);
exec_order++;
printf("order: %d, subthread end!\n", exec_order);
return 0;
}
int main()
{
exec_order++;
printf("order: %d, main start!\n", exec_order);
HANDLE hThread = NULL;
hThread = CreateThread(NULL, 0, SubThread, NULL, 0, NULL);
if (hThread)
{
WaitForSingleObject(hThread, 5000);
CloseHandle(hThread);
}
exec_order++;
printf("order: %d, main end!\n", exec_order);
}
执行结果: