使用TLS进行反调试是使用在TLS回调函数中加入反调试代码的方法来进行的反调试手段
TLS回调函数是指,每当创建/终止进程的线程时会自动调用执行的函数。创建的主线程也会自动调用回调函数,且其调用执行先于EP代码。
那么很显然TLS反调试可以达到一些比常规反调试更好的效果
诶这个题目怎么OD加载不进去QAQΣ( ° △ °|||)︴
关于TLS本身的其他属性这里也不赘述 这里主要研究TLS的写法
一个VS2015下的简单demo(x86 release版本)
#include <Windows.h>
#include <stdio.h>
void NTAPI __stdcall TLS_CALLBACK(PVOID DllHandle, DWORD dwReason, PVOID Reserved)
{
if (IsDebuggerPresent())
{
printf("Debugger detected\n");
}
else
{
printf("No debugger\n");
}
}
#pragma comment (linker, "/INCLUDE:__tls_used")
#pragma comment (linker, "/INCLUDE:__tls_callback")
EXTERN_C
#pragma data_seg (".CRT$XLB")
PIMAGE_TLS_CALLBACK _tls_callback = TLS_CALLBACK;
#pragma data_seg ()
int main()
{
printf("This is main()\n");
return 0;
}
首先是TLS回调函数的函数原型
void NTAPI __stdcall TLS_CALLBACK(PVOID DllHandle, DWORD dwReason, PVOID Reserved);
需要知道的是TLS回调函数设计的本意是为了完成相应的初始化以及其他的一些初始化工作,比如加载一个dll的时候blablabla...
所以常规的用法可能更类似下面这种:
void NTAPI tls_callback(PVOID DllHandle, DWORD dwReason, PVOID Reserved)
{
if (dwReason == DLL_THREAD_ATTACH)
{
MessageBox(0, L"DLL_THREAD_ATTACH", L"DLL_THREAD_ATTACH", 0);
}
if (dwReason == DLL_PROCESS_ATTACH)
{
MessageBox(0, L"DLL_PROCESS_ATTACH", L"DLL_PROCESS_ATTACH", 0);
}
}
接下来需要解释的是这一段:
#pragma comment (linker, "/INCLUDE:__tls_used")
#pragma comment (linker, "/INCLUDE:__tls_callback")
EXTERN_C
#pragma data_seg (".CRT$XLB")
PIMAGE_TLS_CALLBACK _tls_callback = TLS_CALLBACK;
#pragma data_seg ()
使用TLS需要在程序中新建一个data段专门存放TLS数据,并且需要通知链接器在PE头中添加相关数据,所以有了上面这一段代码
demo的效果:
在加载完之前TLS回调函数便已经执行,如果稍加修改demo的代码为直接退出那么将会直接退出