TLS(Thread Local Storage)用来在进程内部每个线程中存储私有的数据。每个线程都会拥有独立的TLS存储空间,可以在TLS存储空间中保存线程的上下文信息、变量、函数指针等。TLS其目的是为了解决多线程变量同步问题,声明为TLS变量后,当线程去访问全局变量时,会将这个变量拷贝到自己线程中的TLS空间中,以防止同一时刻内多次修改全局变量导致变量不稳定的情况,先来看一段简单的案例:

#include <Windows.h>
#include <stdio.h> #pragma comment(linker, "/INCLUDE:__tls_used") // TLS变量
__declspec (thread) int g_nNum = 0x11111111;
__declspec (thread) char g_szStr[] = "TLS g_nNum = 0x%p ...\r\n"; // 当有线程访问tls变量时,该线程会复制一份tls变量到自己tls空间
// 线程只能修改自己的空间tls变量,不会修改到全局变量 // TLS回调函数A
void NTAPI t_TlsCallBack_A(PVOID DllHandle, DWORD Reason, PVOID Red)
{
if (DLL_THREAD_DETACH == Reason) // 如果线程退出则打印信息
printf("t_TlsCallBack_A -> ThreadDetach!\r\n");
return;
} // TLS回调函数B
void NTAPI t_TlsCallBack_B(PVOID DllHandle, DWORD Reason, PVOID Red)
{
if (DLL_THREAD_DETACH == Reason) // 如果线程退出则打印信息
printf("t_TlsCallBack_B -> ThreadDetach!\r\n"); /* Reason 什么事件触发的
DLL_PROCESS_ATTACH 1
DLL_THREAD_ATTACH 2
DLL_THREAD_DETACH 3
DLL_PROCESS_DETACH 0 */
return;
} // 注册TLS回调函数,".CRT$XLB"
#pragma data_seg(".CRT$XLB")
PIMAGE_TLS_CALLBACK p_thread_callback[] = { t_TlsCallBack_A, t_TlsCallBack_B, };
#pragma data_seg() DWORD WINAPI t_ThreadFun(PVOID pParam)
{
printf(g_szStr, g_nNum);
g_nNum = 0x22222222;
printf(g_szStr, g_nNum);
return 0;
} int main(int argc, char * argv[])
{
CreateThread(NULL, 0, t_ThreadFun, NULL, 0, 0);
Sleep(100);
CreateThread(NULL, 0, t_ThreadFun, NULL, 0, 0); system("pause");
return 0;
}

TLS(Thread Local Storage)中断是另一种反调试技术,它利用进程中的线程来执行自定义的中断处理函数,TLS中断处理函数会被在程序加载之前就运行,并能够抢在调试器对程序进行跟踪之前终止执行,这使得它成为一种相对安全的反调试技术。当程序被加载时,TLS中断会自动执行,而对于调试器来说,默认情况下是不会运行TLS中断处理函数的,因此可以利用这一点来判断程序是否正在运行在调试器下。

#include <Windows.h>
#include <stdio.h> // linker spec 通知链接器PE文件要创建TLS目录
#ifdef _M_IX86
#pragma comment (linker, "/INCLUDE:__tls_used")
#pragma comment (linker, "/INCLUDE:__tls_callback")
#else
#pragma comment (linker, "/INCLUDE:_tls_used")
#pragma comment (linker, "/INCLUDE:_tls_callback")
#endif void NTAPI __stdcall TLS_CALLBACK(PVOID DllHandle, DWORD dwReason, PVOID Reserved)
{
if (IsDebuggerPresent())
{
MessageBox(NULL, " TLS_CALLBACK: 请勿调试本程序 !", "TLS Callback", MB_ICONSTOP);
ExitProcess(0);
}
} // 创建TLS段
EXTERN_C
#ifdef _M_X64
#pragma const_seg (".CRT$XLB")
PIMAGE_TLS_CALLBACK _tls_callback = TLS_CALLBACK;
#else
#pragma data_seg (".CRT$XLB")
PIMAGE_TLS_CALLBACK _tls_callback = TLS_CALLBACK;
#endif int main(int argc, char * argv[])
{
system("pause");
return 0;
}

8.10 TLS线程局部存储反调试的更多相关文章

  1. TLS线程局部存储

    0x01 TLS (Thread Local Storage) 为线程单独提供的私有空间 0x02 gcc中的隐式TLS使用方法 隐式TLS __thread int number; 显式TLS pt ...

  2. C/C++ 程序反调试的方法

    C/C++ 要实现程序反调试有多种方法,BeingDebugged,NtGlobalFlag,ProcessHeap,CheckRemoteDebuggerPresent,STARTUPINFO,Is ...

  3. 基于TLS的反调试技术

    TLS(Thread Local Storage 线程局部存储) 一个进程中的每个线程在访问同一个线程局部存储时,访问到的都是独立的绑定于该线程的数据块.在PEB(进程环境块)中TLS存储槽共64个( ...

  4. WIN10 X64下通过TLS实现反调试

    目录(?)[-] TLS技术简介 1 TLS回调函数 2 TLS的数据结构 具体实现及原理 1 VS2015 X64 release下的demo 2 回调函数的具体实现 21 使用IsDebugger ...

  5. 线程局部存储TLS

    1 .使用线程局部存储的理由 当我们希望这个进程的全局变量变为线程私有时,而不是所有线程共享的,也就是每个线程拥有一份副本时,这时候就可以用到线程局部存储(TLS,Thread Local Stora ...

  6. TLS反调试

    0x01 TLS反调试简介 TLS(Thread Local Storage)原本的目的是解决多线程程序中变量同步的问题.线程本身有独立于其他线程的栈空间,因此线程中的局部变量不用考虑同步问题.多线程 ...

  7. 线程局部存储(TLS)

    线程局部存储(TLS) 2011-10-11 09:59:28|  分类: Win32---API |  标签:tls   |举报 |字号 订阅   什么是线程局部存储 众所周知,线程是执行的单元,同 ...

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

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

  9. 线程局部存储 TLS

    C/C++运行库提供了TLS(线程局部存储),在多线程还未产生时,可以将数据与正在执行的线程关联.strtok()函数就是一个很好的例子.与它一起的还有strtok_s(),_tcstok_s()等等 ...

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

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

随机推荐

  1. CNCF大使预测:2024年云原生面临倦怠、离职及云成本精简

    本文由 CNCF 大使 Eric D. Schabell 撰写,预测2024年云原生领域最可能发生的3大变化,并与其对云原生可观测性领域的见解结合. 关注云原生倦怠 毫无疑问,在 2023 年中云原生 ...

  2. BZOJ 3450 - Tyvj1952 Easy (期望DP)

    描述 某一天 WJMZBMR 在打 osu~~~ 但是他太弱逼了,有些地方完全靠运气:( 我们来简化一下这个游戏的规则: 有 \(n(n\le 300000)\) 次点击要做,成功了就是 o,失败了就 ...

  3. Springcloud和Dubbo的区别。Eureka和Ribbon和Hystrix和zuul

    netty 是什么? "netty 是一个基于nio的客户.服务器端编程框架,netty提供异步的,事件驱动的网络应用程序框架和工具,可以快速开发高可用的客户端和服务器.netty是基于ni ...

  4. 《3D编程模式》写书-第6次记录

    大家好,这段时间我完成了对初稿的第二轮修改,已经把稿子提交给编辑了 这里是所有的的写书记录: <3D编程模式>写书记录 本轮修改主要进行了下面的修改: 修改UML描述 增加依赖关系 角色之 ...

  5. docker容器常用操作

    1.查看运行容器 docker ps:  2.查看所有容器 docker ps -a:  3.查看容器的日志 docker logs 容器名称/容器ID: 4.运行镜像 docker run --na ...

  6. wireshark 显示过滤表达式

    转载请注明出处: 1.根据协议过滤: 在显示过滤表达式的输入框中直接输入对应的协议类型即可:http   tcp  udp 2.根据 IP 过滤: 根据源IP地址过滤:如源地址IP为:127.0.0. ...

  7. Pycharm配置git

    原文链接:https://www.jianshu.com/p/ae92970d2062 1.下载Gitee插件 同样在设置页面,选中 Plugins,并搜索 Gitee安装. 安装后,重启一下Pych ...

  8. NewStarCTF 2023 公开赛道 WEEK2|CRYPTO全解

    一.滴啤 题目信息 from Crypto.Util.number import * import gmpy2 from flag import flag def gen_prime(number): ...

  9. Linux复习笔记

    Linux复习笔记 常识说明 目录结构 Linux以树型结构管理文件,其最上层文件夹为 / ,也就是根目录. 如图所示,图中展示了一部分文件夹的结构: 所有的文件夹都属于根目录的子文件夹. 安装好系统 ...

  10. [转帖]InfluxDB 修改数据存储路径

    1.创建数据存储目录 mkdir -p /home/data/influxdb 说明:目录可以根据实际情况进行修改. 2.设置目录访问权限 sudo chown influxdb.influxdb / ...