pe中TLS(thread local storage)中函数的执行时机早于入口函数(entry point),

相关结构:

//
// Thread Local Storage
// typedef VOID
(NTAPI *PIMAGE_TLS_CALLBACK) (
PVOID DllHandle,
DWORD Reason,
PVOID Reserved
); typedef struct _IMAGE_TLS_DIRECTORY64 {
ULONGLONG StartAddressOfRawData;
ULONGLONG EndAddressOfRawData;
ULONGLONG AddressOfIndex; // PDWORD
ULONGLONG AddressOfCallBacks; // PIMAGE_TLS_CALLBACK *;
DWORD SizeOfZeroFill;
union {
DWORD Characteristics;
struct {
DWORD Reserved0 : 20;
DWORD Alignment : 4;
DWORD Reserved1 : 8;
} DUMMYSTRUCTNAME;
} DUMMYUNIONNAME; } IMAGE_TLS_DIRECTORY64; typedef IMAGE_TLS_DIRECTORY64 * PIMAGE_TLS_DIRECTORY64; typedef struct _IMAGE_TLS_DIRECTORY32 {
DWORD StartAddressOfRawData;
DWORD EndAddressOfRawData;
DWORD AddressOfIndex; // PDWORD
DWORD AddressOfCallBacks; // PIMAGE_TLS_CALLBACK *
DWORD SizeOfZeroFill;
union {
DWORD Characteristics;
struct {
DWORD Reserved0 : 20;
DWORD Alignment : 4;
DWORD Reserved1 : 8;
} DUMMYSTRUCTNAME;
} DUMMYUNIONNAME; } IMAGE_TLS_DIRECTORY32;
typedef IMAGE_TLS_DIRECTORY32 * PIMAGE_TLS_DIRECTORY32;

例子:

#include <iostream>
#include <Windows.h> //TLS回调函数测试
void NTAPI MY_TLS_CALLBACK(PVOID DllHandle, DWORD Reason, PVOID Reserved)
{
printf("CALL TLS 1\n");
switch (Reason)
{
case DLL_PROCESS_ATTACH:
printf("DLL_PROCESS_ATTACH\ttls 1\n");
break;
case DLL_THREAD_ATTACH:
printf("DLL_THREAD_ATTACH\ttls 1\n");
break;
case DLL_THREAD_DETACH:
printf("DLL_THREAD_DETACH\ttls 1\n");
break;
case DLL_PROCESS_DETACH:
//printf("DLL_PROCESS_DETACH\ttls 1\n");//进程结束时并没有输出,可能关闭了通道??
break;
}
}
void NTAPI MY_TLS_CALLBACK2(PVOID DllHandle, DWORD Reason, PVOID Reserved)
{
printf("CALL TLS 2\n");
switch (Reason)
{
case DLL_PROCESS_ATTACH:
printf("DLL_PROCESS_ATTACH\ttls 2\n");
break;
case DLL_THREAD_ATTACH:
printf("DLL_THREAD_ATTACH\ttls 2\n");
break;
case DLL_THREAD_DETACH:
printf("DLL_THREAD_DETACH\ttls 2\n");
break;
case DLL_PROCESS_DETACH:
//printf("DLL_PROCESS_DETACH\ttls 2\n");
break;
}
}
/*
#ifdef _M_AMD64
#pragma comment (linker, "/INCLUDE:_tls_used")
#pragma comment (linker, "/INCLUDE:p_tls_callback1")
#pragma const_seg(push)
#pragma const_seg(".CRT$XLX")
EXTERN_C const PIMAGE_TLS_CALLBACK p_tls_callback1[] = { MY_TLS_CALLBACK,MY_TLS_CALLBACK2,0 };
#pragma const_seg(pop)
#endif
#ifdef _M_IX86
#pragma comment (linker, "/INCLUDE:__tls_used")
#pragma comment (linker, "/INCLUDE:_p_tls_callback1")
#pragma const_seg(push)
#pragma const_seg(".CRT$XLX")
EXTERN_C const PIMAGE_TLS_CALLBACK p_tls_callback1[] = { MY_TLS_CALLBACK,MY_TLS_CALLBACK2,0 };
#pragma const_seg(pop)
#endif
*/ #ifdef _M_AMD64
#pragma comment(linker,"/INCLUDE:_tls_used")
#pragma const_seg(".CRT$XLX")
EXTERN_C const PIMAGE_TLS_CALLBACK p_tls_callback1[] = { MY_TLS_CALLBACK,MY_TLS_CALLBACK2,0 };
#pragma const_seg()
#endif #ifdef _M_IX86
#pragma comment (linker, "/INCLUDE:__tls_used")
#pragma const_seg(".CRT$XLX")
EXTERN_C const PIMAGE_TLS_CALLBACK p_tls_callback1[] = { MY_TLS_CALLBACK,MY_TLS_CALLBACK2,0 };
#pragma const_seg()
#endif DWORD WINAPI MyThreadFunction(LPVOID lpParam) {
int nb = *(int*)lpParam;
for (int i = 0; i < nb; ++i) {
printf("number: %d\n", i);
Sleep(1000);
}
return 1;
}
int main()
{
std::cout << "Hello World!\n";
DWORD dwThreadId=0;
int number = 3; HANDLE hThread= CreateThread(
NULL, // default security attributes
0, // use default stack size
MyThreadFunction, // thread function name
&number, // argument to thread function
0, // use default creation flags
&dwThreadId); // returns the thread identifier
getchar();
}

输出:

《逆向工程核心原理》——TLS回调函数的更多相关文章

  1. 通过TLS回调函数的反调试

    下面是TLS数据结构的定义 typedef struct _IMAGE_TLS_DIRECTORY { DWORD StartAddressOfRawData; DWORD EndAddressOfR ...

  2. TLS回调函数

    @author: dlive TLS (Thread Local Storage 线程局部存储 )回调函数常用于反调试. TLS回调函数的调用运行要先于EP代码执行,该特性使它可以作为一种反调试技术使 ...

  3. TLS回调函数以及反调试简单使用

    TLS回调函数以及反调试简单使用 0x00  TLS介绍 TLS(Thread Local Storage,线程局部储存),主要用于给线程独立的传值,由于线程不拥有进程的资源,所以几个同一进程的几个线 ...

  4. Mina、Netty、Twisted一起学(九):异步IO和回调函数

    用过JavaScript或者jQuery的同学都知道,JavaScript特别是jQuery中存在大量的回调函数,例如Ajax.jQuery的动画等. $.get(url, function() { ...

  5. 小兔JS教程(三)-- 彻底攻略JS回调函数

    这一讲来谈谈回调函数. 其实一句话就能概括这个东西: 回调函数就是把一个函数当做参数,传入另一个函数中.传进去的目的仅仅是为了在某个时刻去执行它. 如果不执行,那么你传一个函数进去干嘛呢? 就比如说对 ...

  6. 嵌入式&iOS:回调函数(C)与block(OC)传 参/函数 对比

    C的回调函数: callBack.h 1).声明一个doSomeThingCount函数,参数为一个(无返回值,1个int参数的)函数. void DSTCount(void(*CallBack)(i ...

  7. 嵌入式&iOS:回调函数(C)与block(OC)回调对比

    学了OC的block,再写C的回调函数有点别扭,对比下区别,回忆记录下. C的回调函数: callBack.h 1).定义一个回调函数的参数数量.类型. typedef void (*CallBack ...

  8. 理解 JavaScript 回调函数并使用

    JavaScript中,函数是一等(first-class)对象:也就是说,函数是 Object 类型并且可以像其他一等对象(String,Array,Number等)一样使用.它们可以"保 ...

  9. 关于js的回调函数的一点看法

    算了一下又有好几个月没写博客了,最近在忙公司android的项目,所以也就很少抽时间来写些东西了.刚闲下来,我就翻了翻之前看的东西.做了android之后更加感觉到手机端开发的重要性,现在做nativ ...

随机推荐

  1. C++中函数的形式参数引用

    形式参数的传递方式 值传递 值传递是将数值传递到程序中,这种方式传递是单向传递 但是如果想要双向传递,这种视频无法满足: 引用传递 引用传递可以实现双向的传递 为了对比处两个之间的差异,这里举出两个例 ...

  2. Google Chrome All In One

    Google Chrome All In One Chrome Experiments Chrome 测试版 Chrome 开发者版 Chrome Canary 版 chrome://welcome/ ...

  3. Python & file operation mode

    Python & file operation mode create/read/write/append mode https://docs.python.org/3/library/fun ...

  4. NGK官方又出助力市场计划方案 1万枚VAST任性送

    近期NGK官方的一系列动作,可以说是在向外界宣告:NGK2.0即将来袭,席卷加密数字货币市场.前一段时间,NGK官方宣布,NGK公链布局算力领域,打造NGK算力生态星空计划,并推出了SPC星空币.目前 ...

  5. ROS等下载时无法连接问题的解决方法

    资料参考: https://blog.csdn.net/weixin_44692299/article/details/105869229

  6. Scrapy项目_苏宁图书信息

     苏宁图书(https://book.suning.com/) 目标: 1.图书一级分类 2.图书二级分类 3.图书三级分类 4.图书名字 5.图书作者 6.图书价格 7.通过Scrapy获取以上数据 ...

  7. Spring 注解(二)注解工具类

    本文转载自Spring 注解(二)注解工具类 导语 首先回顾一下 AnnotationUtils 和 AnnotatedElementUtils 这两个注解工具类的用法: @Test @GetMapp ...

  8. C# NOPI 项目实战(经典)(可下载项目源码)

    1 -.首先说明下项目目的: 之前我有写过一篇  "NPOI操作EXCEL" 这篇文章主要介绍了如何安装NPOI,以及NPOI具体如何使用,并且用具体实例介绍了excel导入到da ...

  9. 【springboot读取配置文件】@ConfigurationProperties、@PropertySource和@Value

    概念: @ConfigurationProperties : 是springboot的注解,用于把主配置文件中配置属性设置到对于的Bean属性上 @PropertySource :是spring的注解 ...

  10. Vue(1)

    一:概述 Vue是一套用于构建用户界面的渐进式JavaScript框架,与其它大型框架不同的是,Vue被设计为可以自底向上逐层应用.Vue的核心库只关心视图层,不仅易于上手,还便于与第三方库或既有项目 ...