pe文件结构(TLS)

news2025/7/25 22:24:15

TLS


什么是TLS?

TLS是 Thread Local Storage 的缩写,线程局部存储。主要是为了解决多线程中变量同步的问题

如果需要要一个线程内部的各个函数调用都能访问,但其它线程不能访问的变量(被称为static memory local to a thread 线程局部静态变量),就需要新的机制来实现,这就是TLS

用途1:

TLS变量

线程A去修改TLS变量时,线程B不会受影响,因为每个线程都拥有一个TLS变量的副本

创建TLS变量

__declspe(thread) int g_tls = 1000;

用途2:

在安全领域中,TLS常被用于处理如反调试,抢占执行等操作

TLS回调函数

#include<iostream>
#include<Windows.h>
// 首先加上编译选项 
_declspec(thread) int g_tlsNum = 100;
#ifdef _WIN64
#pragma comment(linker, "/INCLUDE:_tls_used")
#else
#pragma comment(linker, "/INCLUDE:__tls_used")
#endif


DWORD WINAPI threadProc(LPVOID lparam) {
	g_tlsNum = 300;
	printf("g_tlsNum=%d\n",g_tlsNum);
	return 0;
}

void NTAPI t_TlsCallBack_A(PVOID DllHandle, DWORD Reason, PVOID Reserved);

/*
	注册TLS函数,.CRT$XLX的作用
	CRT表示使用C Runtime库
	X表示标识名随机
	L表示 TLS Callback section
	X也可以换成B~Y任意一个字符

*/
// 注册 TLS 回调
#ifdef _WIN64
#pragma const_seg(".CRT$XLX") // x64 下用 const_seg(只读段)
EXTERN_C const // 禁用 C++ 的名称修饰 
#else
#pragma data_seg(".CRT$XLX") // x86 下用 data_seg(可读写段)
#endif

//存储回调函数地址 PIMAGE_TLS_CALLBACK pTLS_CALLBACKs,写了几个回调函就要往里面添加几个,最后必须要有一个0
PIMAGE_TLS_CALLBACK pTLS_CALLBACKs[] = { t_TlsCallBack_A,0 };

#ifdef _WIN64
#pragma const_seg()
#else
#pragma data_seg()
#endif


// 编写Tls回调函数 参数1:模块加载基址 参数2:调用的原因 参数3:保留
void NTAPI t_TlsCallBack_A(PVOID DllHandle, DWORD Reason, PVOID Reserved) {
	switch (Reason) {
	case DLL_PROCESS_ATTACH:
		printf("Hello Tls\n");
		break;
	case DLL_THREAD_ATTACH:
		break;
	case DLL_THREAD_DETACH:
		break;
	case DLL_PROCESS_DETACH:
		break;
	}
}

int main() {

	// 创建线程
	CreateThread(NULL, NULL, threadProc,NULL,NULL,NULL);
	return 0;
}

何时被调用

  • #define DLL_PROCESS_ATTACH 1 // 进程创建时
  • #define DLL_THREAD_ATTACH 2 // 线程创建时
  • #define DLL_THREAD_DETACH 3 // 线程销毁时
  • #define DLL_PROCESS_DETACH 0 // 进程销毁时

在这里插入图片描述

查看执行结果,我们会发现TLS是最先执行的,这样我们就可以用这个回调函数来反调试一些调试器的加载,一般来说调试器在加载一个程序的时候,程序最先执行的代码是OEP(Original Entry Point),但TLS在OPE之前执行

我们来修改一下代码来写一个简单的反调试程序

void NTAPI t_TlsCallBack_A(PVOID DllHandle, DWORD Reason, PVOID Reserved) {
	switch (Reason) {
	case DLL_PROCESS_ATTACH:
	{
		BOOL result = FALSE;
		HANDLE hRealProcess = NULL;
		DuplicateHandle(
			GetCurrentProcess(),         // 当前进程
			GetCurrentProcess(),         // 伪句柄 (HANDLE)-1
			GetCurrentProcess(),         // 目标进程(仍为当前进程)
			&hRealProcess,               // 存储真实句柄
			NULL, FALSE, DUPLICATE_SAME_ACCESS
		);
		CheckRemoteDebuggerPresent(hRealProcess, &result); // 这种只是最简单的,现代调试器都会有反反调试的手段
		if (result) {
			MessageBox(NULL, L"检测到有调试器加载", L"Warning", MB_OK | MB_ICONWARNING);
			ExitProcess(0);
		}
		break;
	}
		
	case DLL_THREAD_ATTACH:
		break;
	case DLL_THREAD_DETACH:
		break;
	case DLL_PROCESS_DETACH:
		break;
	}
}

直接双击运行程序发现是没有问题的

在这里插入图片描述

我们来测试下有调试器加载的情况(由于目前市面上常用的调试器都有反反调试的功能,我们这个简单的反调试肯定是不会被检测出来的,所以我们用Visual Studio自带的调试器来看一下)

在这里插入图片描述
可以看到我们main函数还没执行之前就已经触发了检测


TLS表

在我们的pe文件当中,有这么一张表,就是用来告诉Tls函数和变量在哪里存放着

在我们16张表中第10张表就是我们的Tls表对应存放的虚拟地址

// IMAGE_TLS_DIRECTORY64结构体 
typedef struct _IMAGE_TLS_DIRECTORY64 {
    ULONGLONG StartAddressOfRawData;	// Tls初始化数据的起始地址
    ULONGLONG EndAddressOfRawData;		// Tls初始化数据的结束地址 (这个范围存放初始化的值)
    ULONGLONG AddressOfIndex;         	// Tls索引的位置
    ULONGLONG AddressOfCallBacks;     	// PIMAGE_TLS_CALLBACK * (Tls回调函数的数组指针)
    DWORD SizeOfZeroFill;				// 填充0的个数
    union {
        DWORD Characteristics;
        struct {
            DWORD Reserved0 : 20;
            DWORD Alignment : 4;
            DWORD Reserved1 : 8;
        } DUMMYSTRUCTNAME;
    } DUMMYUNIONNAME;

} IMAGE_TLS_DIRECTORY64;
// 获取Tls表信息
void getTlsInfo(const char* peFileBuffer) {
	// 获取Tls表地址
	TableAddress repositionAddress = g_tableAddress[IMAGE_DIRECTORY_ENTRY_TLS];
	// 通过Rva得到文件地址
	DWORD fileAddress = rvaToFoa(repositionAddress.myVirtualAddress);

	// 解析结构体
	PIMAGE_TLS_DIRECTORY64 tlsDirectory = (PIMAGE_TLS_DIRECTORY64)(peFileBuffer + fileAddress);

	printf("Tls初始化数据的起始地址:0x%llX\n", tlsDirectory->StartAddressOfRawData);
	printf("Tls初始化数据的结束地址:0x%llX\n", tlsDirectory->EndAddressOfRawData);
	printf("Tls索引的位置:0x%llX\n", tlsDirectory->AddressOfIndex);
	printf("Tls回调函数的数组指针:0x%llX\n", tlsDirectory->AddressOfCallBacks);
	printf("填充0的个数:%d\n", tlsDirectory->SizeOfZeroFill);

}

在这里插入图片描述

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2403788.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

中型零售业数据库抉择:MySQL省成本,SQL SERVER?

针对中型零售企业&#xff08;20台固定POS数十台移动POS&#xff0c;含库存管理与结算业务&#xff09;的操作系统与数据库选型&#xff0c;需平衡性能、成本、扩展性及运维效率。结合行业实践与系统需求&#xff0c;建议如下&#xff1a; &#x1f5a5;️ ​​一、操作系统选型…

IDEA中的debug使用技巧

详细教学视频见b站链接&#xff1a;IDEA的debug调试 CSDN详细博客文章链接&#xff1a;debug文章学习 以下为个人学习记录总结&#xff1a; idea中的debug模式界面如下&#xff1a; 现在详细介绍图标作用&#xff1a; 图标一&#xff08;Show Execution Point&#xff09;&…

RockyLinux9.6搭建k8s集群

博主介绍&#xff1a;✌全网粉丝5W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…

AI IDE 正式上线!通义灵码开箱即用

近期&#xff0c;通义灵码AI IDE正式上线&#xff0c;即日起用户可在通义灵码官网免费下载开箱即用。 作为AI原生的开发环境工具&#xff0c;通义灵码AI IDE深度适配了最新的千问3大模型&#xff0c;并全面集成通义灵码插件能力&#xff0c;具备编程智能体、行间建议预测、行间…

Ubuntu20.04基础配置安装——系统安装(一)

引言&#xff1a; 工作需要&#xff0c;Ubuntu的各类环境配置&#xff0c;从23年开始使用Ubuntu20.04之后&#xff0c;尽管能力在不断提升&#xff0c;但是依旧会遇到Ubuntu系统崩掉的情况&#xff0c;为了方便后续系统出现问题及时替换&#xff0c;减少从网上搜索资源进行基础…

Kafka入门-消费者

消费者 Kafka消费方式&#xff1a;采用pull&#xff08;拉&#xff09;的方式&#xff0c;消费者从broker中主动拉去数据。使用pull的好处就是消费者可以根据自身需求&#xff0c;进行拉取数据&#xff0c;但是坏处就是如果Kafka没有数据&#xff0c;那么消费者可能会陷入循环…

中电金信:从智能应用到全栈AI,大模型如何重构金融业务价值链?

导语 当前&#xff0c;AI大模型技术正加速重构金融行业的智能化图景。为助力金融机构精准把握这一变革机遇&#xff0c;中电金信与IDC联合发布《中国金融大模型发展白皮书》。《白皮书》在梳理了AI大模型整体发展现状的基础上&#xff0c;结合金融行业用户的需求调研深入分析了…

巴西医疗巨头尤迈Kafka数据泄露事件的全过程分析与AI安防策略分析

一、事件背景与主体信息 涉事主体:Unimed,全球最大医疗合作社,巴西医疗行业龙头企业,拥有约1500万客户。技术背景:泄露源于其未保护的Kafka实例(开源实时数据传输平台),用于客户与聊天机器人“Sara”及医生的实时通信。二、时间线梳理 时间节点关键事件描述2025年3月24…

快速上手 Metabase:从安装到高级功能实战

文章目录 1. 引言&#xff1a;Metabase——轻量级的数据分析工具&#x1f3af; 学完本教程你能掌握&#xff1a; 2. 安装 Metabase&#xff1a;本地部署实操2.1 环境准备2.2 使用 Docker 安装 Metabase2.3 初始化设置2.4 连接外部数据库 3. 第一个数据探索&#xff1a;5分钟创建…

Linux基础命令which 和 find 简明指南

&#x1f3af; Linux which 和 find 命令简明指南&#xff1a;从入门到实用 &#x1f4c5; 更新时间&#xff1a;2025年6月7日 &#x1f3f7;️ 标签&#xff1a;Linux | which | find | 命令行 | 文件查找 文章目录 前言&#x1f31f; 一、Linux 命令的本质与 which、find 的作…

思尔芯携手Andes晶心科技,加速先进RISC-V 芯片开发

在RISC-V生态快速发展和应用场景不断拓展的背景下&#xff0c;芯片设计正面临前所未有的复杂度挑战。近日&#xff0c;RISC-V处理器核领先厂商Andes晶心科技与思尔芯&#xff08;S2C&#xff09;达成重要合作&#xff0c;其双核单集群AX45MPV处理器已在思尔芯最新一代原型验证系…

kafka消息积压排查

kafka监控搭建&#xff1a;https://insights.blog.csdn.net/article/details/139129552?spm1001.2101.3001.6650.1&utm_mediumdistribute.pc_relevant.none-task-blog-2%7Edefault%7Ebaidujs_baidulandingword%7EPaidSort-1-139129552-blog-132216491.235%5Ev43%5Econtrol…

drawio 开源免费的流程图绘制

开源地址 docker-compose 一键启动 #This compose file adds draw.io to your stack version: 3.5 services:drawio:image: jgraph/drawiocontainer_name: drawiorestart: unless-stoppedports:- 8081:8080- 8443:8443environment:PUBLIC_DNS: domainORGANISATION_UNIT: unitOR…

YOLOv8 升级之路:主干网络嵌入 SCINet,优化黑暗环境目标检测

文章目录 引言1. 低照度图像检测的挑战1.1 低照度环境对目标检测的影响1.2 传统解决方案的局限性 2. SCINet网络原理2.1 SCINet核心思想2.2 网络架构 3. YOLOv8与SCINet的集成方案3.1 总体架构设计3.2 关键集成代码3.3 训练策略 4. 实验结果与分析4.1 实验设置4.2 性能对比4.3 …

传输层:udp与tcp协议

目录 再谈端口号 端口号范围划分 认识知名端口号(Well-Know Port Number) 两个问题 netstat pidof 如何学习下三层协议 UDP协议 UDP协议端格式 UDP的特点 面向数据报 UDP的缓冲区 UDP使用注意事项 基于UDP的应用层协议 TCP协议 TCP协议段格式 1.源端口号…

centos7.9源码安装zabbix7.12,求赞

centos7.9源码安装zabbix7.12-全网独有 3.CentOS7_Zabbix7.0LTS3.1.安装环境3.2.换成阿里源3.3.安装相关依赖包3.3.1.直接安装依赖3.3.2.编译安装-遇到问题01-net-snmp3.3.3.编译安装-遇到问题02-libevent3.3.4.编译安装-遇到问题03-安装openssl 3.4.创建用户和组3.5.下载上传源…

亚远景科技助力东风日产通过ASPICE CL2评估

热烈祝贺东风日产通过ASPICE CL2评估 近日&#xff0c;东风日产PK1B VCM热管理项目成功通过ASPICE CL2级能力评估&#xff0c;标志着东风日产在汽车电子软件研发管理体系及技术创新能力上已达到国际领先水平&#xff0c;为其全球化布局注入强劲动能。 ASPICE&#xff1a;国际竞…

基于JWT+SpringSecurity整合一个单点认证授权机制

基于 JWT Spring Security 的授权认证机制&#xff0c;在整体架构设计上体现了高度的安全性与灵活性。其在整合框架中的应用&#xff0c;充分展示了模块化、可扩展性和高效鉴权的设计理念&#xff0c;为开发者提供了一种值得借鉴的安全架构模式。 1.SpringSecurity概念理解 …

IDEA 打开文件乱码

问题&#xff1a;文件乱码 底部编码无法切换 解决方案&#xff1a; 第一步 使用Nodepad 查询文件编码 本项目设置为 转为 UTF-8 无 BOM 第二步&#xff1a;在 IntelliJ IDEA 中&#xff1a;右键点击文件 → File Encoding → 选择目标编码&#xff08;如 UTF-8&#xff09; 最…

第2章:Neo4j安装与配置

在了解了Neo4j的基本概念和优势之后&#xff0c;下一步就是将其安装并配置好&#xff0c;以便开始实际操作。本章将详细介绍Neo4j的各种部署方式&#xff0c;涵盖不同操作系统的安装步骤&#xff0c;深入探讨关键配置项&#xff0c;并介绍常用的管理工具&#xff0c;为读者顺利…