虽然说是牛人们N年前手中的玩物,我却是最近才知道有这回事 
  资料也不多,昨天BAIDU+论坛搜索弄了很久,有点搜获,不敢独享,发出来和大家共享。
---------------------------------------------------------------------
  话说很久很久以前我们就知道,main,WinMain,DllMain等在一般情况下并不是应用程序或动态链接库执行的起点,所以我们经常在crt0上进行一些OOXX的事情。
 结果现在发现,在crt0之前,我们还能做一些事情,这个OOXX的事情就是所谓的Thread Local Storage技术带来的tls回调函数??!!
 一个让我觉得很牛逼的东西。当然鸡肋还是有一点的,那就是非常明显地暴露了我们要执行特定意图代码的位置。
 不管怎么说,我们小菜还是来学习下吧!
PS.
如果用VC写代码,在TLS回调函数中不要使用C库的函数,因为此时MSVCRTXXX.DLL还没加载,至少我的VS2K3是这样的。另外如果要执行可能出现异常的代码,一定要try/catch。不然操作系统不会报错,而是直接跑到OEP去了。
再PS.
牛人们请自觉,这个是菜鸟交流的帖子。。。。你们就不要来OOXX了。。。。
---------------------------------------------------------------------
资料链接:
http://www.pediy.com/bbshtml/bbs7/pediy7-667.htm
http://bbs.pediy.com/showthread.php?p=80239
http://bbs.pediy.com/showthread.php?threadid=31875
http://www.codeproject.com/KB/threads/tls.aspx
http://bbs.pediy.com/showthread.php?t=63237&highlight=tls
http://bbs.pediy.com/showthread.php?threadid=17828 
http://bbs.pediy.com/showthread.php?threadid=17839 
http://bbs.pediy.com/showthread.php?threadid=12532 
http://bbs.pediy.com/showthread.php?threadid=18144
---------------------------------------------------------------------
TLS表结构
typedef struct _IMAGE_TLS_DIRECTORY32 {
    DWORD   StartAddressOfRawData;
    DWORD   EndAddressOfRawData;
    DWORD   AddressOfIndex;             // PDWORD
    DWORD   AddressOfCallBacks;         // PIMAGE_TLS_CALLBACK *
    DWORD   SizeOfZeroFill;
    DWORD   Characteristics;
} IMAGE_TLS_DIRECTORY32;
---------------------------------------------------------------------
表里面的其他项都可以填0,但是要求AddressOfIndex指向一个数组,数组存放所有TLS的回调函数的地址,以NULL结束数组
---------------------------------------------------------------------
TLS回调函数的函数原型
extern "C" void NTAPI TLS_callback ( PVOID DllHandle, DWORD Reason, PVOID Reserved );
其中Readson的意义和DllMain()的差不多
---------------------------------------------------------------------
一个简单的使用TLS的实例
来源http://hi.baidu.com/zhanglinguo11/blog/item/5d7c9623c2b2be549922ed41.html

代码:
// TLS_CallBack_test.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <windows.h>
#include <winnt.h>
//下面这行告诉链接器在PE文件中要创建TLS目录
#pragma comment(linker, "/INCLUDE:__tls_used")
/*这是PIMAGE_TLS_CALLBACK()函数的原型,其中第一个和第三个参数保留,第二个参数决定函数在那种情况下*/
void NTAPI my_tls_callback(PVOID h, DWORD reason, PVOID pv)
{
/*一共有四个选项DLL_PROCESS_ATTACH、DLL_THREAD_ATTACH、DLL_THREAD_DETACH和DLL_PROCESS_DETACH。详见微软发布的《Microsoft Portable Executable and Common Object File Format Specification v8》*/
//仅在进程初始化创建主线程时执行的代码
if( reason == DLL_PROCESS_ATTACH ){
   MessageBox(NULL,L"hi,this is tls callback",L"title",MB_OK);
}
return;
}
/*下面这段是创建一个tls段
".CRT$XLB"的含义是:
.CRT表明是使用C RunTime机制
$后面的XLB中
X表示随机的标识
L表示是TLS callback section
B可以被换成B到Y的任意一个字母,但是不能使用".CRT$XLA"和".CRT$XLZ"
因为".CRT$XLA"和".CRT$XLZ"是用于tlssup.obj的
*/
#pragma data_seg(".CRT$XLB")
/*如果要定义多个TLS_CallBack函数,可以把下面这句写成:
PIMAGE_TLS_CALLBACK p_thread_callback [] = {tls_callback_A, tls_callback_B, tls_callback_C,0};
其中tls_callback_B和tls_callback_C应该是你定义好的其他TLS_callBack函数
*/
PIMAGE_TLS_CALLBACK p_thread_callback = my_tls_callback;
#pragma data_seg()

int main(void)
{
MessageBox(NULL,L"hi,this is main()",L"title",MB_OK);
return 0;
}
---------------------------------------------------------------------
祝我们大家一起进步!