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. 【GitChat首秀:限时免费】互联网测试岗校招的那些事儿

    2020 校园秋招即将结束,2021 校招春招即将开始. 作为一名扎根互联网近十年的资深测试开发,我刚经历过数十个测试岗位的校招笔试和面试选拔.在 2020 年秋招面试过程中,我深深地感受到" ...

  2. 如何使用 js 实现相似图片搜索

    如何使用 js 实现相似图片搜索 以图搜图 https://www.google.com/imghp?hl=en https://www.google.com/imghp?hl=zh https:// ...

  3. js data type checker

    js data type checker js 数据类型检测 "use strict"; /** * * @author xgqfrms * @license MIT * @cop ...

  4. useful podcast

    useful podcast front end podcast https://shoptalkshow.com https://stackoverflow.blog/podcast/ SoundC ...

  5. React & Didact

    React & Didact A DIY guide to build your own React https://github.com/pomber/didact https://gith ...

  6. JS Calendar API

    JS Calendar API js 如何获取当天是周几(一周的第几天) const date = new Date(); // Mon Mar 23 2020 15:15:36 GMT+0800 ( ...

  7. BGV暴涨千倍,未来或将超越YFI领跑DeFi全场!

    毫无疑问,YFI在2020年上半年以一己之力掀翻了DeFi市场的热潮.迄今为止,YFI的新鲜资讯从不缺席,最近也是频频登上各大知名媒体热搜.其币价远远超过比特币价格,也让资本市场注意到DeFi市场原来 ...

  8. epoll原理详解及epoll反应堆模型

    本文转载自epoll原理详解及epoll反应堆模型 导语 设想一个场景:有100万用户同时与一个进程保持着TCP连接,而每一时刻只有几十个或几百个TCP连接是活跃的(接收TCP包),也就是说在每一时刻 ...

  9. 配置安装oh-my-bash

    背景 最近项目上有用到petalinux,所以只能在bash环境下使用命令行,所以不能使用oh-my-zsh 之前看一个dalao用oh-my-bash来规避这个问题.所以这里试一下安装oh-my-b ...

  10. Vue学习笔记-jsonl转换显示工具JsonView安装及使用

    一  使用环境: windows 7 64位操作系统 二  jsonl转换显示工具JsonView安装及使用 1.下载: https://github.com/gildas-lormeau/JSONV ...