首页 > 其他分享 >8.10 TLS线程局部存储反调试

8.10 TLS线程局部存储反调试

时间:2023-09-27 09:34:29浏览次数:30  
标签:TLS tls CALLBACK 线程 pragma PVOID 8.10

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;
}

标签:TLS,tls,CALLBACK,线程,pragma,PVOID,8.10
From: https://www.cnblogs.com/LyShark/p/17731910.html

相关文章

  • 多线程Review-926-01
    一、进程与线程1、进程:①电脑管家等软件我们运行的应用程序②在内存中正在运行的程序2、线程:①进程中的一个最小执行单元。一个进程最少得有一个线程②软件中的每一个功能,如电脑管家中的清理垃圾、杀毒、软件搜索二、线程的创建方式1、继承Thread类  :优点——代码......
  • Spring中构造器、init-method、@PostConstruct、afterPropertiesSet孰先孰后,自动注入
     引用:https://www.cnblogs.com/qlqwjy/p/9417034.html首先明白,spring的IOC功能需要是利用反射原理,反射获取类的无参构造方法创建对象,如果一个类没有无参的构造方法spring是不会创建对象的。在这里需要提醒一下,如果我们在class中没有显示的声明构造方法,默认会生成一个无参......
  • Java 21 正式 GA,虚拟线程真的来了
    UTC时间2023年9月19日,期盼已久的Java21终于发布正式版!本文一起来看看其中最受Java开发者关注的一项新特性:Loom项目的两个新特性之一的”虚拟线程(VirtualThread)“(另外一个新特性是”结构化并发(StructuredConcurrency)“,当前是预览状态),它被称之为Java版的”协......
  • 在Java中线程有几种状态?
    一、Java中线程六种状态线程在自身的生命周期中,并不是固定地处于某个状态,而是随着代码的执行在不同的状态之间进行切换......
  • 线程
    开线程的第一种方式:frommultiprocessingimportProcess #导入进程fromthreadingimportRhread #导入线程importtime  deftask(name):print('%sisruning'%name)time.sleep(1)print('%siisover')#开启线程不需要再main下面执行代码直接书写......
  • 修复 K8s SSL/TLS 漏洞(CVE-2016-2183)
    转载于:https://www.cnblogs.com/kubesphere/p/17141586.html前言简介生产环境KubeSphere3.3.0部署的Kubernetes集群在安全评估的时候发现安全漏洞,其中一项漏洞提示 SSL/TLS协议信息泄露漏洞(CVE-2016-2183)。本文详细描述了漏洞产生原因、漏洞修复方案、漏洞修复的......
  • Linux-----进程、线程、协程的生命周期、调度器slab
    Linux进程、线程、协程的区别进程进程是操作系统中的一个独立执行单元。每个进程都有自己的独立内存空间,包括代码段、数据段、堆栈等。进程之间通常需要通过进程间通信(IPC)来交换数据和信息。进程启动和销毁开销较大,因为需要分配和释放独立的内存空间。进程之间隔离度高,一个......
  • 细说多线程,如何解决线程安全问题
    关于多线程,首先熟练分清楚线程和进程的关系:进程:内存中正在运行的一个程序线程:进程中的一个最小执行单元。一个进程最少得有一个线程(Java程序中一个请求就是一个线程)。一、创建多线程的方式有四种:1.继承Thread类1.定义一个子类继承Thread类,并重写run方法2.创建Thread的子类对......
  • 多线程
    首先先说一下什么是进程什么事线程,进程就是在内存中正在运行的程序,线程是进程的最小执行单位,一个进程最少得有一个线程,线程是指软件中的每一个功能。    线程的创建方式有三种,继承Thread类,实现Runable接口,实现Callable接口,继承Thread类和实现Runable接口的区别在于,java是单......
  • 多线程
    学习多线程我们要先明白进程与线程进程就是在内存中正在运行的程序,就跟我们手机上一个个正在运行的软件一样.线程:线程是进程的最小执行单元,一个进程中最少拥有一个线程,线程就相当于手机软件中的一个个软件线程创建的方式(共四种)第一种是继承Thread类,重写run......