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函數)