wzb 发表于 2011-7-11 09:48

用C++写的TLS Callback(vc6.0编译通过

TLS是线程局部存储的意思。用TLS可以干很多你想干的,像PE感染、PE文件自校验、调试器检测(附件里就是一个用TLS做调试器检测的小例子)
但是TLS Callback用C++不是很好写,编译设置有些麻烦,在这我介绍一下TLS如何用C++写

TLS Callback的原理是:
1、在链接时,链接器要在PE文件中创建TLS目录。
2、在创建线程时,加载器会从TEB(线程环境块,通过FS寄存器可以获取TEB的位置)中获取一个指向TLS回调函数数组的指针。
3、如果在TLS回调函数数组不是一个空的数组,加载器就会顺序执行这个数组中的各个回调函数(在入口函数之前加载)。

所以我们第一步就要分配一个TLS段
#pragma data_seg(".tls")         //分配一个TLS段

然后告诉编译器,生成TLS目录
#pragma comment(linker, "/INCLUDE:__tls_used")      //下面这行告诉链接器在PE文件中要创建TLS目录

接下来初始化TLS目录:
nt _tls_index=0;
int _tls_start=0;
int _tls_end=0;
int __xl_a=0;
int __xl_z=0;
extern PIMAGE_TLS_CALLBACK tls_callbacktbl[];   //TLS回调函数数组
IMAGE_TLS_DIRECTORY32 _tls_used=
{
   (DWORD)&_tls_start,
   (DWORD)&_tls_end,
   (DWORD)&_tls_index,
   (DWORD)tls_callbacktbl,
   0,
   0
};

下面是一些编译设置:
#pragma data_seg(".tls$ZZZ")
#pragma data_seg(".CRT$XLA")                  //.CRT表明是使用C RunTime机制,$后面的XLA中X表示随机的标识,L表示是TLS callback section,A是任意的
#pragma data_seg(".CRT$XLZ")
#pragma data_seg(".rdata$T")

上面这些代码,放到一个.c文件中,在工程属性中选去掉预编译头

然后就可以开始我们的正题TLS函数的编写了:
函数声明是:
void NTAPI my_tls_callback(PVOID h, DWORD reason, PVOID pv);
其中第一和第三个参数不用管它,是保留的
第二个参数有下面几个可能的值:

DLL_PROCESS_ATTACH,是指新进程创建时,在初始化主线程时执行
DLL_THREAD_ATTACH,是指在新进程初始化时执行,但是不包括主线程
DLL_THREAD_DETACH,是指在所有的线程终止时执行,但是同样不包括主线程
DLL_PROCESS_DETACH,是指在进程终止时执行

TLS函数一般是这样的格式:
Void NTAPI tls_callback(PVOID h, DWORD reason, PVOID pv)
{
if(reason==DLL_PROCESS_ATTACH)
{
......................
}
if(reason==DLL_THREAD_ATTACH)
{
......................
}
...................
return;
};
填上自己的代码就可以了。

最后要写TLS回调函数数组:
extern "C" PIMAGE_TLS_CALLBACK tls_callbacktbl[] = {tls_callback,0};

有几个TLS回调函数就写几个,以0结尾。

附件是一个例子,用TLS做调试器检测。
测试的时候要把反调试的插件都去掉啊!

锋爷 发表于 2011-7-11 10:11

太深奥了··看不懂··

atkdef 发表于 2011-7-11 10:26

看得出楼主很有心。。。
我也不懂这个,
只是觉得- -
怎么这么象DLLMAIN啊,
那个reason。。。

亚辛 发表于 2011-11-17 23:04

参数和DLLMain一样的

无敌英雄 发表于 2011-11-18 05:38

xiaoai2449 发表于 2012-4-5 00:36

很不错,学习一下   呵呵

晓儿 发表于 2012-4-5 00:45

每天多抽出一点时间来这里学习一下。

renminbi 发表于 2012-4-13 14:13

学习一下TLS回调

liangliang0558 发表于 2012-4-13 19:40

很好学习啦 谢谢分享

guiguixiaotong 发表于 2012-8-31 19:01

看得有点感觉,看来基础自己基础还是还差
页: [1] 2
查看完整版本: 用C++写的TLS Callback(vc6.0编译通过