TLS (Thread Local Storage 线程局部存储 )回调函数常用于反调试。
程序运行时,TLS数据初始化和TLS回调函数都在入口处(OEP)之前执行,也就是说,TLS是程序开始执行的地方。(许多病毒或外壳程序会利用这一点执行一些特殊的操作)
TLS 定义:
typedef VOID
(NTAPI *PIMAGE_TLS_CALLBACK) (
PVOID DllHandle,
DWORD Reason,
PVOID Reserved
);
其中Reason 有以下几种参数:
#define DLL_PROCESS_DETACH 0 进程退出
#define DLL_PROCESS_ATTACH 1 进程启动
#define DLL_THREAD_ATTACH 2 线程启动
#define DLL_THREAD_DETACH 3 线程退出
实例:(小白写的简单,多多包涵)
TLS.cpp
#include <Windows.h>
#include <stdio.h>
void NTAPI __stdcall TLS_CALLBACK(PVOID DllHandle, DWORD dwReason, PVOID Reserved) //DllHandle模块句柄、Reason调用原因、 Reserved加载方式(显式/隐式)
{
switch (dwReason)
{
case DLL_THREAD_ATTACH: //Reason会有4种参数
MessageBox(0, "TLS函数DLL_THREAD_ATTACH", "TLS", 0); break;
case DLL_PROCESS_ATTACH: //debug
MessageBox(0, "TLS函数DLL_PROCESS_ATTACH", "TLS", 0); break;
case DLL_THREAD_DETACH:
MessageBox(0, "TLS函数DLL_THREAD_DETACH", "TLS", 0); break;
case DLL_PROCESS_DETACH:
MessageBox(0, "TLS函数DLL_PROCESS_DETACH", "TLS", 0); break;
}
}
//使用TLS需要在程序中新建一个data段专门存放TLS数据,
//并且需要通知链接器在PE头中添加相关数据,所以有了这一段代码
#pragma comment (linker, "/INCLUDE:__tls_used")
#pragma comment (linker, "/INCLUDE:__tls_callback")
EXTERN_C
#pragma data_seg (".CRT$XLB")//.CRT表明是使用C RunTime机制,$后面的XLB中:X表示随机的标识,L表示是TLS callback section,B可以被换成B到Y之间的任意一个字母,
//但是不能使用“.CRT$XLA”和“.CRT$XLZ”,因为“.CRT$XLA”和“.CRT$XLZ”是用于tlssup.obj的。
PIMAGE_TLS_CALLBACK _tls_callback = TLS_CALLBACK; //共享数据段
#pragma data_seg ()
int main()
{
::MessageBox(0, "主窗口", "main'函数", 0);
return 0;
}
运行:
第一个窗口:(TLS)
第二个窗口:(main函数)