![]() |
#2
asmdaydream2011-11-06 19:55
|


#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。
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 的
$是给链接器的。LINK 做的一个重要的任务,就是把所有具有相同名字的段合并成为
一个单独的段(这也就是连接程序名字的由来之一),合并的做法就是简单地把每个
段中的数据按顺序前后放到一个连续的空间就可以了。这样在最终运行的时候,程序
看到的CRT$XL?段也就是一个连续的数组,而不是多个数组。
*/
#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 应该是你定义好的其他
Team509
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;
}
[ 本帖最后由 asmdaydream 于 2011-11-6 19:57 编辑 ]