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. Nmap & ncat

    Nmap & ncat https://github.com/udacity/course-ud303 https://nmap.org/dist/nmap-7.30-setup.exe Yo ...

  2. 海 鱼立 鲷 & 海䲞鲷

    海 鱼立 鲷 & 海䲞鲷 䲞 lì 鲷 diāo 二长棘鲷 二长棘鲷(学名:Parargyrops edita)为辐鳍鱼纲鲈形目鲷科二长棘鲷属的鱼类,俗名板鱼.䲞鱼.盘仔鱼.立花.赤鬃.长鳍. ...

  3. leetcode solution cracked tutorial

    leetcode solution cracked tutorial problemset https://leetcode.com/problemset/all/ Top Interview Que ...

  4. free Google translator for the personal website

    free Google translator for the personal website https://html5.xgqfrms.xyz/

  5. fetch & form-data & upload & image file

    fetch & form-data & upload & image file no need multipart/form-data https://blog.xinshan ...

  6. 解析js字符串

    myEval export const evalExp = /[!\&\|\+\-\*\%=\/<\>\^\(\)\~\:\?\;]/g; export function myEv ...

  7. GoEasy使用阿里云OSS出现的问题

    前言:本人使用goeasy来实现微信小程序里面和其他人的im临时对话窗口,想要实现可以同时发送语音和视频.图片.表情包的话,就要通过goeasy关联到阿里云的存储对象. 报错:The OSS Acce ...

  8. Datahero inc:区块链方案如何在现有食品溯源系统里实现落地?

    在食品行业,区块链溯源平台的应用,主要是指围绕"从农田到餐桌"的安全管理理念,综合运用区块链技术.大数据技术和二维码技术等前沿技术,具有产品生产企业管理. 产品生产档案 (农药/防 ...

  9. 别找了,这可能是全网最全的鸿蒙(OpenHarmony)刷机指南

    目录: 1. 配置编译环境 2. 编译HarmonyOS源代码 3. 烧录HarmonyOS 4.下载文中资源 5.作者文章合集 摘要:相信很多同学都玩过鸿蒙(HarmonyOS)了,不过估计大多数同 ...

  10. Mac上的Redis安装和使用

    redis简介 REmote DIctionary Server(Redis) 是一个由 Salvatore Sanfilippo 写的 key-value 存储系统,是跨平台的非关系型数据库. Re ...