TLS回调函数

代码逆向分析领域中,TLS(Thread Local Storage,线程局部存储)回调函数(Callback Function)常用于反调试。TLS回调函数的调用运行要先于EP代码的执行,该特征使它可以作为一种反调试技术使用。

1、程序:HelloTls.exe

运行练习程序文件(HelloTls.exe),弹出1一个消息框,单机“确定”按钮后,程序终止运行。
G6SLWV.png
下面使用OllyDbg调试练习示例程序。在OllyDbg调试器中打开并运行HelloTls。
.exe文件,弹出如下对话框。
G6Znvn.png
点击确定,按钮,进程终止。

2、TLS

1、IMAFGE_DATA_DIRECTORY[9]
若在编程中启用了TLS功能,PE头文件中就会设置TLS表(TLS Table)项目。
2、IMAGE_TLS_DIRECTORY

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
typedef struct _IMAGE_TLS_DIRECTORY64 
{
ULONGLONG StartAddressOfRawData;
ULONGLONG EndAddressOfRawData;
ULONGLONG AddressOfIndex;
ULONGLONG AddressOfCallBacks;
DWORD SizeOfZeroFill;
DWORD Characteristics;
} IMAGE_TLS_DIRECTORY64;
typedef IMAGE_TLS_DIRECTORY64 * PIMAGE_TLS_DIRECTORY64;

typedef struct _IMAGE_TLS_DIRECTORY32
{
DWORD StartAddressOfRawData;
DWORD EndAddressOfRawData;
DWORD AddressOfIndex;
DWORD AddressOfCallBacks;
DWORD SizeOfZeroFill;
DWORD Characteristics;
} IMAGE_TLS_DIRECTORY32;
typedef IMAGE_TLS_DIRECTORY32 * PIMAGE_TLS_DIRECTORY32;

#ifdef _WIN64
typedef IMAGE_TLS_DIRECTORY64 IMAGE_TLS_DIRECTORY64;
typedef PIMAGE_TLS_DIRECTORY64 PIMAGE_TLS_DIRECTORY64;
#else
typedef IMAGE_TLS_DIRECTORY32 IMAGE_TLS_DIRECTORY32;
typedef PIMAGE_TLS_DIRECTORY32 PIMAGE_TLS_DIRECTORY32;

IMAGE_TLS_DIRECTORY结构体有两种版本,分别为32位与64位。使用工具查看IMAGE_TLS_DIRECTORY结构体,如图所示。
G6nE4O.png
3、回调函数地址数组
G6Ksc4.png
该数组中实际存储的就是TLS回调函数的地址。进程启动时,系统会逐一调用存储在该数组中的函数。

3、TLS回调函数

创建或终止某线程时,TLS回调函数都会自动调用执行,前后共两次。
TLS回调函数的定义代码如下。

1
2
3
4
5
6
typedef VOID
(NTAPI *PIMAGE_TLS_CALLBACK) (
PVOID DllHandle,
DWORD Reason,
PVOID Reserved
);