当前位置: 首页 > article >正文

PE文件之TLS

PE文件之TLS是什么线程局部存储线程局部存储Thread Local StorageTLS是各线程独立的数据存储空间使用TLS可以像修改自身局部变量一样修改进程的全局变量而不影响其它线程。这很好地解决了多线程程序设计中变量的同步问题。TLS机制最重要的地方在于用来向目标文件写入内容的代码在所有线程中都是一样的而从TLS中取出的文件偏移和字节数却各不相同。实现TLS比较常见的办法是在进程中建立一个全局表通过线程的ID去查询相应的数据结构因为每个线程的ID是不一样的所以查到的数据也自然就不一样了。程序员最受益的地方是不需要加入任何同步代码即可满足程序功能设计的要求所有同步操作由操作系统在内部自行完成这就是TLS技术。TLS技术分为两种动态线程局部存储技术静态线程局部存储技术TLS技术的分类主要依据是线程局部存储的数据所用空间在程序运行期操作系统完成的是动态申请还是静态分配。动态线程局部存储Windows为每个进程维护了一个全局的TLS索引池TlsAlloc分配并为每个线程维护了一个私有的TLS槽位数组TLS Slots。这个数组在PE文件中没有固定的存储结构而是在内存中动态生成。动态TLS主要使用如下四个函数TlsAlloc系统返回一个全局索引如 0x2C。这个索引在所有线程中代表同一个“槽位编号”这是进程级别的TlsSetValue(Index, pData)系统找到当前线程的TEBThread Environment Block定位到其中的TLS数组将 pData存入数组的第 Index个位置这是线程级别的TlsGetValue(Index)从当前线程的TLS数组中取出第 Index个值这是线程级别的TlsFree每个线程的TEB中有一个 ThreadLocalStoragePointer字段指向一个 LPVOID数组。TlsGetValue本质上就是一次数组寻址*(TEB-ThreadLocalStoragePointer Index)。静态线程局部存储在PE文件结构中静态线程局部存储特指通过编译器关键字如__declspec(thread)或__thread声明的、在编译链接时即确定存储布局并由PE文件自身的数据结构和系统加载器直接支持的线程局部变量机制。1. 实现核心PE文件中的静态TLS段当编译器发现__declspec(thread) int tls_var;这样的变量时它会进行特殊处理编译阶段将该变量放入一个特殊的节区通常命名为.tls或类似名称。链接阶段链接器会汇总所有此类变量在PE文件中创建或合并一个.tls 节区并生成一个IMAGE_TLS_DIRECTORY结构体。这个结构体的指针被放入PE头数据目录表的第9项IMAGE_DIRECTORY_ENTRY_TLS。2. 关键数据结构IMAGE_TLS_DIRECTORY这个结构体定义了静态TLS的“蓝图”包含以下关键字段StartAddressOfRawData / EndAddressOfRawData指向.tls 节区在文件中的起始和结束RVA。这块数据是TLS变量的初始化模板。AddressOfIndex指向存储TLS索引的位置通常是一个全局变量。AddressOfCallbacks指向TLS回调函数数组上一轮已详述。SizeOfZeroFill指定需要额外清零的TLS数据大小。3. 加载器的工作流程加载器在加载PE文件时处理静态TLS的步骤如下定位TLS目录通过数据目录表第9项找到IMAGE_TLS_DIRECTORY。为每个线程创建TLS存储块系统为进程的主线程创建一个私有的TLS内存块。当新线程被创建时系统会a. 分配一块新的内存。b. 将StartAddressOfRawData指向的模板数据完整拷贝到这块内存中初始化。c. 将SizeOfZeroFill指定大小的区域清零。初始化访问线程通过一个非常高效的机制访问其TLS变量。在x86/x64架构上通常通过FS/GS段寄存器中的一个固定偏移由加载器设置直接寻址到该线程的TLS存储块然后加上变量的编译时偏移量来访问。这比动态TLS的API调用快得多。动态TLS和静态TLS比较机制动态TLS (API)静态TLS (PE结构)全局索引DWORD g_tlsIndex TlsAlloc();DWORD tlsIndex;由AddressOfIndex指向索引获取程序员调用TlsAlloc()得到由系统加载器自动分配并写入AddressOfIndex指向的地址索引用途作为TlsGetValue(g_tlsIndex)的参数由编译器生成代码通过 FS/GS:[tlsIndex] 的方式直接寻址存储位置索引是进程全局变量索引变量位于进程的数据段如 .dataAddressOfIndex存储的是它的地址TLS回调函数程序可以通过PE文件的方式提供一个或多个TLS回调函数用以支持对TLS数据进行附加的初始化和终止操作这种操作类似于面向对象程序设计中的构造函数和析构函数。尽管回调函数通常不超过一个但还是将其作为一个数组来实现以便在需要时可以另外添加更多回调函数。如果回调函数超过一个它们将会按照其地址在数组中出现的顺序被依次调用一个双字的空指针表示这个数组的结尾。如果程序没有提供回调函数则该列表可以为空这时这个数组就只有一个元素即双字的0。下面是TLS回调函数的定义可以看到这和DllMain函数的定义是很像的。

相关文章:

PE文件之TLS

PE文件之TLS 是什么线程局部存储 线程局部存储(Thread Local Storage,TLS)是各线程独立的数据存储空间,使用TLS可以像修改自身局部变量一样修改进程的全局变量而不影响其它线程。这很好地解决了多线程程序设计中变量的同步问题。 …...

LPS25H气压传感器I²C驱动开发与气压测高实战

1. LPS25H气压传感器驱动库技术解析LPS25H是意法半导体(STMicroelectronics)推出的一款高精度、低功耗数字气压传感器,采用MEMS技术制造,可测量绝对压力范围为260 hPa至1260 hPa(对应海拔约9000 m至−500 m&#xff09…...

Si5351A Arduino时钟库:面向RF应用的轻量级全功能驱动

1. 项目概述PU2REO_Si5351Lite 是一款专为 Skyworks(前 Silicon Labs)Si5351A 10 引脚 MSOP 封装时钟发生器芯片设计的轻量级、全功能 Arduino 库。该库的核心目标是提供一种完全脱离 Silicon Labs 官方 ClockBuilder 闭源软件的、基于纯固件控制的解决方…...

Qwen3-0.6B-FP8应用场景:学生辅助学习、程序员代码解释、运营文案生成

Qwen3-0.6B-FP8:小模型大智慧,三大场景实战指南 你是不是也遇到过这些头疼事? 学生时代,面对复杂的数学题和物理概念,怎么都绕不过弯,想找个随时能问的“学霸”朋友?刚入行的程序员,…...

从ifconfig到iproute2:现代Linux网络管理工具链迁移全攻略

从ifconfig到iproute2:现代Linux网络管理工具链迁移全攻略 在Linux系统管理领域,网络配置一直是最基础也最关键的技能之一。过去二十年间,ifconfig、route等传统工具曾是每个运维人员的标配,但随着Linux内核网络栈的演进&#xff…...

Turbo Intruder:3大核心优势实现百万级请求的Web安全测试实战指南

Turbo Intruder:3大核心优势实现百万级请求的Web安全测试实战指南 【免费下载链接】turbo-intruder Turbo Intruder is a Burp Suite extension for sending large numbers of HTTP requests and analyzing the results. 项目地址: https://gitcode.com/gh_mirror…...

LoRA无感切换是啥?yz-bijini-cosplay新手必看的功能详解与实操

LoRA无感切换是啥?yz-bijini-cosplay新手必看的功能详解与实操 1. 引言:为什么LoRA无感切换如此重要? 想象一下这样的场景:你正在使用AI生成Cosplay图片,已经加载好模型,生成了几张不错的作品。突然&…...

Qwen2.5-VL-7B-Instruct部署教程:多卡GPU负载均衡与并发请求优化配置

Qwen2.5-VL-7B-Instruct部署教程:多卡GPU负载均衡与并发请求优化配置 想试试让AI看懂图片还能跟你聊天吗?今天要聊的Qwen2.5-VL-7B-Instruct,就是一个能“看图说话”的智能模型。它不仅能理解图片里的内容,还能根据你的问题给出详…...

嵌入式实时控制中的连续域动态环节C库设计

1. 项目概述AutomationElements 是一个面向工业自动化与嵌入式控制系统的轻量级 C 语言函数库,专为资源受限的微控制器(如 Cortex-M0/M3/M4)设计。其核心定位并非通用数学计算库,而是提供一组可直接嵌入实时控制环路的基础连续域动…...

Snap7实战:如何绕过西门子PLC的优化块访问限制实现高效数据读写

Snap7实战:突破西门子PLC优化块访问限制的数据读写方案 在工业自动化领域,西门子PLC与上位机的高效数据交互一直是开发者关注的焦点。许多工程师在使用Snap7库进行数据通信时,常常会遇到优化块访问限制带来的困扰。本文将深入解析如何通过合理…...

终极指南:如何巧妙隐身玩转Riot游戏而不被打扰

终极指南:如何巧妙隐身玩转Riot游戏而不被打扰 【免费下载链接】Deceive 🎩 Appear offline for the League of Legends client. 项目地址: https://gitcode.com/gh_mirrors/de/Deceive 在当今快节奏的游戏世界中,你是否经常面临这样的…...

工业机械臂轨迹跟踪实战:从动力学模型到精准焊接(附MATLAB仿真代码)

工业机械臂轨迹跟踪实战:从动力学模型到精准焊接(附MATLAB仿真代码) 在汽车制造和精密设备生产线上,机械臂焊接轨迹的精度直接决定产品质量。传统示教编程已无法满足复杂三维焊缝的微米级要求,而基于动力学模型的控制算…...

Arduino Stepper库原理与工业级电机控制实践

1. Arduino Stepper 库深度解析:从电机控制原理到工业级应用实践1.1 库定位与工程价值Arduino Stepper 库是嵌入式系统中电机控制领域最基础、最广泛使用的开源驱动组件之一。其核心价值不在于技术复杂度,而在于将步进电机底层时序控制抽象为可复用、可移…...

MoE模型训练总是不稳定?可能是你的“路由器”在捣鬼——深入解读R3对齐策略

MoE模型训练总是不稳定?可能是你的“路由器”在捣鬼——深入解读R3对齐策略 想象一下,你正在指挥一支由数百名专业顾问组成的超级团队处理复杂任务。每位顾问都是某个细分领域的顶尖专家,而你的工作是根据问题类型实时决定咨询哪几位专家。这…...

MAX7219四合一点阵驱动原理与同步显示设计

1. 项目概述MAX7219四合一点阵显示模块是一种面向嵌入式系统设计的高集成度LED驱动解决方案,其核心目标是通过极简的硬件接口和确定性的时序控制,实现多片88点阵的稳定、无闪烁显示。该模块并非通用显示终端,而是专为需要紧凑空间部署、低资源…...

电梯安全新视角:基于YOLO的电动车检测数据集解析与优化技巧

电梯安全新视角:基于YOLO的电动车检测数据集解析与优化技巧 电梯作为现代建筑中不可或缺的垂直交通工具,其安全问题日益受到关注。近年来,电动车违规进入电梯引发的安全事故频发,如何利用计算机视觉技术实现智能检测成为研究热点。…...

《ShardingSphere解读》18 执行引擎:如何把握 ShardingSphere 中的 Executor 执行模型?(上)

在上一篇中,我们对 ShardingGroupExecuteCallback 和 SQLExecuteTemplate 做了介绍。从设计上讲,前者充当 ShardingExecuteEngine 的回调入口;而后者则是一个模板类,完成对 ShardingExecuteEngine 的封装并提供了对外的统一入口&a…...

VR-Reversal:无需VR设备,轻松将3D视频转换为2D的终极指南

VR-Reversal:无需VR设备,轻松将3D视频转换为2D的终极指南 【免费下载链接】VR-reversal VR-Reversal - Player for conversion of 3D video to 2D with optional saving of head tracking data and rendering out of 2D copies. 项目地址: https://git…...

【CP AUTOSAR】Pwm(PWMDriver)配置实践与电源管理详解

1. PWM驱动基础与AUTOSAR架构解析 第一次接触AUTOSAR的PWM驱动时,我被各种专业术语搞得晕头转向。后来在实际项目中摸爬滚打才发现,理解PWM在AUTOSAR架构中的定位非常重要。PWM驱动属于MCAL(微控制器抽象层)的组成部分&#xff0c…...

Kappa系数详解:比准确率更靠谱的分类器评估方法(Python代码示例)

Kappa系数详解:比准确率更靠谱的分类器评估方法(Python代码示例) 在机器学习模型的评估中,准确率(Accuracy)常常被作为最直观的指标使用。但当我们面对类别分布极度不均衡的数据时,这个看似可靠…...

DDNS-GO 动态域名解析:从零搭建到高效运维

1. 为什么你需要DDNS-GO动态域名解析 家里有NAS的朋友一定遇到过这样的烦恼:明明设置了远程访问,过几天突然连不上了。检查路由器发现,运营商的公网IP又偷偷换了!这就是动态IP带来的困扰。我去年帮朋友调试家庭监控系统时&#xf…...

Nacos配置中@Value注解如何正确解析properties数组类型

1. 为什么Value注解解析properties数组会出问题? 在实际开发中,我们经常遇到这样的场景:需要在Nacos配置中心定义一组URL白名单,或者配置多个排除路径。按照常规思路,很多人会直接在properties文件中写成数组格式&…...

RT-Thread内核移植详解:libcpu与BSP双层实现

1. RT-Thread内核移植技术解析:从CPU架构适配到BSP工程实现嵌入式实时操作系统(RTOS)的移植是连接底层硬件与上层应用的关键桥梁。RT-Thread作为一款开源、中立、可裁剪的实时操作系统,其设计哲学强调“一次编写,多平台…...

告别编译踩坑:用Buildroot一键集成tcpdump到你的嵌入式Linux系统

告别编译踩坑:用Buildroot一键集成tcpdump到你的嵌入式Linux系统 在嵌入式Linux开发中,网络调试工具tcpdump的重要性不言而喻。它能帮助我们捕获和分析网络数据包,是排查网络问题的利器。然而,传统的交叉编译方式往往让开发者陷入…...

Spring_couplet_generation 模型背后的神经网络:从LSTM到现代架构

Spring_couplet_generation 模型背后的神经网络:从LSTM到现代架构 你有没有想过,当你输入一句“春风送暖”,AI就能对出“福气临门”这样工整的下联,它到底是怎么做到的?这背后,是一系列神经网络在默默工作…...

避坑指南:Unity调用Win32 API设置无边框窗口时容易忽略的3个细节

Unity无边框窗口实战:避开Win32 API调用的3个典型陷阱 当Unity开发者需要实现PC端无边框窗口效果时,Win32 API调用往往是绕不开的技术路径。但在这个过程中,从窗口初始化异常到多显示器适配问题,再到任务栏高度计算的坑&#xff0…...

MacBook远程办公神器:Microsoft Remote Desktop + cpolar内网穿透保姆级教程

MacBook远程办公终极方案:Microsoft Remote Desktop与内网穿透实战指南 远程办公已成为现代职场不可或缺的工作方式。想象一下这样的场景:你正在咖啡馆享受下午茶,突然接到紧急任务需要处理公司电脑上的文件;或是出差在外&#xf…...

保姆级避坑指南:在Ubuntu 22.04上为Unitree Go2配置ROS2 Humble开发环境(含网络、防火墙、DDS配置)

Unitree Go2机器人ROS2开发环境配置全攻略:从零避坑到实战部署 引言 当你第一次拿到Unitree Go2四足机器人时,那种兴奋感可能很快会被复杂的开发环境配置过程冲淡。作为一款前沿的机器人平台,Go2与ROS2 Humble的集成并非一帆风顺——网络配置…...

当前知识库暂无关于如何取消 sas_cspm_dp_cn-0s64mgf8q000v 的具体信息。根据该标识符的命名格式(包含 cspm 和地域标识 cn),它很可能与 云安全态势管理(CSPM)

收到阿里云的短信:您购买的云安全态势管理资源包用量已耗尽(如您账户内已无其它可用资源包,将产生账号扣费) 工作台产品消息:[余量预警] 尊敬的hi30489928aliyun.com 您购买的云安全态势管理资源包 (资源包实例: sas_…...

从零手写 miniGPT 02 | 数据工程与训练循环:GPT 是如何“学习“的?

上一节我们从 Block 层面解析了 GPT 的核心结构,包括多头注意力、前馈网络以及残差与归一化机制,这些模块共同构成了 Transformer 的基本计算单元,也是当前主流大模型共享的底层框架。 然而,模型能力的差异并不完全来源于结构本身…...