【逆向工程核心原理:TLS回调函数】
TLS
代码逆向分析领域中,TLS(Thread Local Storage,线程局部存储)回调函数(Callback Function)常用反调试。TLS回调函数的调用运行要先于EP代码的执行,该特征使它可以作为一种反调试技术的使用。
TLS是各线程的独立的数据存储空间,使用TLS技术可在线程内部独立使用或修改进程的全局数据或静态数据,就像对待自身的局部变量一样。
- PE中的TLS
若在编程中启用了TLS功能,PE头文件中就会设置TLS表(TLS Table)项目
IMAGE_NT_HEADERS
IMAGE_OPTIONAL_HEADER
IMAGE_DATA_DIRECTORY[9]
上图多了TLS结构的索引,通过这个地址可以找到TLS结构。
看一下TLS结构体定义。
TLS结构有32位和64位两个版本,其属性个数相同,只是属性的长度发生了变化
typedef struct _IMAGE_TLS_DIRECTORY64 {ULONGLONG StartAddressOfRawData;ULONGLONG EndAddressOfRawData;ULONGLONG AddressOfIndex; // PDWORDULONGLONG 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 struct _IMAGE_TLS_DIRECTORY32 {DWORD StartAddressOfRawData;DWORD EndAddressOfRawData;DWORD AddressOfIndex; // PDWORDDWORD 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;
通过这个目录表,可以找到TLS结构体,关注这个变量,就可以找到一个数组,数组里是回调函数地址的数组,以全零结尾
这就是找到了回调函数的地址数组,这里只有一个地址
TLS回调函数运行时机
所谓TLS回调函数是指,每当创建/终止进程的线程时会自动调用执行的函数。有意思的是,创建进程的主线程时,也会自动调用回调函数,且其调用执行先于EP代码。反调试技术利用的就是TLS回调函数的这一特征。
注:
请注意,创建或终止某线程时,TLS回调函数都会自动调用执行,前后共2次。
执行进程的主线程(运行线程的EP代码)前,TLS回调函数会被先调用执行,许多逆向分析人员将该特征应用于程序的反调试技术。
// IMAGE_TLS_CALLBACK结构
typedef VOID
(NTAPI *PIMAGE_TLS_CALLBACK) (PVOID DllHandle,DWORD Reason,PVOID Reserved);
DllHandle为模块句柄,Reason是调用的原因:
// 进程主线程main执行前调用
#define DLL_PROCESS_ATTACH 1
// main开始执行,main开始创建线程前调用
#define DLL_THREAD_ATTACH 2
// 子线程结束后调用
#define DLL_THREAD_DETACH 3
// 子线程执行完毕,main也结束后调用
#define DLL_PROCESS_ATTACH 0
example:
#include<Windows.h>// 通知链接器使用TLS
#pragma comment(linker,"/INCLUDE:__tls_used")void print_console(const char* szMsg)
{HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);WriteConsole(hStdout, szMsg, strlen(szMsg), NULL, NULL);}void NTAPI TLS_CALLBACK1(PVOID DllHandle, DWORD Reason, PVOID Reserved)
{char szMsg[80] = { 0, };wsprintfA(szMsg, "TLS_CALLBACK1():DllHandle=%X,Reason=%d\n", DllHandle, Reason);print_console(szMsg);
}void NTAPI TLS_CALLBACK2(PVOID DllHandle, DWORD Reason, PVOID Reserved)
{char szMsg[80] = { 0, };wsprintfA(szMsg, "TLS_CALLBACK2():DllHandle=%X,Reason=%d\n", DllHandle, Reason);print_console(szMsg);
}// 注册TLS函数,.CRT$XLX的作用:CRT表示使用C Runtime 机制,X表示表示名随机,L表示TLS Callback section,X也可以换成B~Y任意一个字符
// 在这里用数组存放TLS回调函数地址
#pragma data_seg(".CRT$XLX")
PIMAGE_TLS_CALLBACK pTLS_CALLBACKs[] = { TLS_CALLBACK1,TLS_CALLBACK2,0 };#pragma data_seg()DWORD WINAPI ThreadProc(LPVOID lPram) {print_console("ThreadProc() start\n");print_console("ThreadProc() end\n");return 0;
}int main(void)
{HANDLE hThread = NULL;print_console("main()start\n");hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);WaitForSingleObject(hThread, 60 * 1000);CloseHandle(hThread);print_console("main() end\n");system("pause");return 0;
}
调试TLS
开始调试前,要设置System breakpoint
2.x也可以直接设置TLS ballback
断下后,去AddressofCallback
去找存放回调函数地址的数组,这里写了一个数据0x401000
在这里就是TLS回调函数内容
手工添加TLS
调试可以,也可以通过修改PE文件,给没有TLS
的程序添加TLS回调函数
- 扩大最后一个节
- 修改PE头,保证扩展正确
- 增加TLS的目录表
- 增加TLS的结构体(放在扩大的节里)
- 根据结构体所指的数组中的地址,添加TLS回调函数代码
1、2:扩大节、修改PE节表
3、添加TLS目录表
4、去RVA=C200处,添加TLS结构体内容
5、添加TLS函数代码
- 结果
载入od调试,就是触发这个弹窗
相关文章:

【逆向工程核心原理:TLS回调函数】
TLS 代码逆向分析领域中,TLS(Thread Local Storage,线程局部存储)回调函数(Callback Function)常用反调试。TLS回调函数的调用运行要先于EP代码的执行,该特征使它可以作为一种反调试技术的使用…...

“Shell“Awk命令
文章目录 一.Awk二.Awk按行输出文本三.Awk按字段输出文本四.通过管道,双引号调用shell命令五.总结: 一.Awk Awk的工作原理: 逐行读取文本,默认以空格或tab键为分隔符进行分隔,将分隔所得的各个字段保存到内建变量中&a…...

射频放大器的原理和作用(射频放大器和功率放大器的区别)
射频放大器是一种电子电路,用于将输入信号增强到足够高的电平以驱动射频输出负载。其原理和作用如下: 射频放大器的工作原理是利用晶体管的三极管效应,将输入信号放大到足够的电平以驱动输出负载。在射频放大器中,输入信号经过输入…...
揭秘KubeEdge边缘网络项目EdgeMesh:如何打造高速、安全、低延迟的互联网连接
KubeEdge是由百度主导的边缘计算项目,旨在为物联网设备提供一种高效、安全的互联网连接方式。EdgeMesh是KubeEdge的核心组件之一,它是一种基于OpenDaylight的边缘网络协议,能够在物联网设备之间提供高速、可靠的互联网连接。 EdgeMesh的设计目…...

Java设计模式 14-访问者模式
访问者模式 这个模式用的很少,《设计模式》的作者评价为: 大多情况下,你不需要使用访问者模式,但是一旦需要使用它时,那就真的需要使用了 一、测评系统的需求 1)将观众分为男人和女人,对歌手进行测评&…...

【数据结构】线性表之链表
目录 前言一、链表的定义二、链表的分类1. 单向和双向2. 带头和不带头3. 循环和不循环4. 常用(无头单向非循环链表和带头双向循环链表) 三、无头单向非循环链表的接口及实现1. 单链表的接口2. 接口的实现 四、带头双向循环链表接口的及实现1. 双向链表的…...

微服架构基础设施环境平台搭建 -(四)在Kubernetes集群基础上搭建Kubesphere平台
微服架构基础设施环境平台搭建 -(四)在Kubernetes集群基础上搭建Kubesphere平台 通过采用微服相关架构构建一套以KubernetesDocker为自动化运维基础平台,以微服务为服务中心,在此基础之上构建业务中台,并通过Jekins自动…...

Linux开发板安装Python环境
1. 环境介绍 硬件:STM32MP157,使用的是野火出的开发板。 软件:Debian ARM 架构制作的 Linux 发行版,版本信息如下: Linux发行版本:Debian GNU/Linux 10 内核版本:4.19.94 2. Python 简介…...

ChatGPT 聊天接口API 使用
一、准备工作 1.准备 OPENAI_ACCESS_TOKEN 2.准备好PostMan 软件 二、测试交流Demo 本次使用POSTMAN工具进行快速测试,旨在通过ChatGPT API实现有效的上下文流。在测试过程中,我们发现了三个问题: 1.如果您想要进行具有上下文的交流&…...

软件测试月薪2万,需要技术达到什么水平?
最近跟朋友在一起聚会的时候,提了一个问题,说一个软件测试工程师如何能月薪达到二万,技术水平需要达到什么程度?人回答说这只能是大企业或者互联网企业工程师才能拿到。也许是的,小公司或者非互联网企业拿二万的不太可…...
从入门到进阶,Vue框架让Web开发更简单高效
Vue是现代前端开发中最为流行的JavaScript框架之一,它具有轻量、易学、易用的特点,能够帮助开发者构建出高效、交互丰富的Web应用。在本文中,我们将会深入探索Vue框架的各个方面,包括Vue组件、Vue路由、Vue状态管理等,…...

怎么缩小照片的kb,压缩照片kb的几种方法
缩小照片的KB大小是我们日常工作生活中遇到的常见问题。虽然听起来十分专业,但其实很简单。照片的KB是指照片文件的大小,通常以“KB”为单位表示。缩小照片的KB就是减小照片文件的大小,以便占用更少的磁盘空间或更快地上传和下载照片。在实际…...
2. 注解Annotation
Java注解(Annotation)又称为Java标注,是JDK5.0引入的一种注释机制.注解是原数据的一种形式,提供有关于程序但不属于程序本身的数据.注解对他们注解的代码的操作没有直接的影响. 声明方式 注解的声明方式使用interface关键字,举例说明: public interface MyInject{ }元注解 Ta…...
【Leetcode -495.提莫攻击 -496.下一个更大的元素Ⅰ】
Leetcode Leetcode -495.提莫攻击Leetcode - 496.下一个更大的元素Ⅰ Leetcode -495.提莫攻击 题目:在《英雄联盟》的世界中,有一个叫 “提莫” 的英雄。他的攻击可以让敌方英雄艾希(编者注:寒冰射手)进入中毒状态。 …...

肝一肝设计模式【八】-- 外观模式
系列文章目录 肝一肝设计模式【一】-- 单例模式 传送门 肝一肝设计模式【二】-- 工厂模式 传送门 肝一肝设计模式【三】-- 原型模式 传送门 肝一肝设计模式【四】-- 建造者模式 传送门 肝一肝设计模式【五】-- 适配器模式 传送门 肝一肝设计模式【六】-- 装饰器模式 传送门 肝…...

Maven uber-jar(带依赖的打包插件)maven-shade-plugin
文章目录 最基础的 maven-shade-plugin 使用生成可执行的 Jar 包 和 常用的资源转换类包名重命名打包时排除依赖与其他常用打包插件比较 本文是对 maven-shade-plugin 常用配置的介绍,更详细的学习请参照 Apache Maven Shade Plugin 官方文档 通过使用 maven-shade…...

MySQL基础(二十八)索引优化与查询优化
都有哪些维度可以进行数据库调优?简言之: 索引失效、没有充分利用到索引——索引建立关联查询太多JOIN (设计缺陷或不得已的需求)——SQL优化服务器调优及各个参数设置(缓冲、线程数等)———调整my.cnf。数据过多――分库分表 关于数据库调优的知识点非常分散。不同的DBMS&…...

初步认识性能测试和完成一次完整的性能测试
上一篇博文主要通过两个例子让测试新手了解一下测试思想,和在做测试之前应该了解人几点,那么我们在如何完成一次完整的性能测试呢? 测试报告是一次完整性能测试的体现,所以,这里我给出一个完整的性能测试报告ÿ…...

使用插件快速生成代码
使用插件快速生成代码 咋们常说,授人以鱼不如授人以渔,在这里给大家提供一些技巧性的东西,方便一些新手同学可以快速上手,同时,也提高我们的开发兴趣与开发热情! 主要讲什么呢,我们来学一学如何…...

FE_Vue学习笔记 插槽 slot
插槽分为匿名插槽、具名插槽、作用域插槽。子组件中: 匿名插槽只能有一个;可以有多个具名插槽;作用域插槽中可以有匿名插槽和具名插槽。 当项目中一个组件可以多次复用时,我们可以把这个组件封装成单独的.vue文件,从…...
后进先出(LIFO)详解
LIFO 是 Last In, First Out 的缩写,中文译为后进先出。这是一种数据结构的工作原则,类似于一摞盘子或一叠书本: 最后放进去的元素最先出来 -想象往筒状容器里放盘子: (1)你放进的最后一个盘子(…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...

ElasticSearch搜索引擎之倒排索引及其底层算法
文章目录 一、搜索引擎1、什么是搜索引擎?2、搜索引擎的分类3、常用的搜索引擎4、搜索引擎的特点二、倒排索引1、简介2、为什么倒排索引不用B+树1.创建时间长,文件大。2.其次,树深,IO次数可怕。3.索引可能会失效。4.精准度差。三. 倒排索引四、算法1、Term Index的算法2、 …...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...
MinIO Docker 部署:仅开放一个端口
MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...