TLS回调函数实现反调试
创始人
2024-05-08 15:35:37
0次

title: TLS回调函数实现反调试.md
date: 2022-06-16 23:40:49.231
updated: 2022-06-16 23:41:11.924
url: /archives/tls回调函数实现反调试
categories:
tags:

  • 逆向

TLS回调函数实现反调试

TLS-线程局部存储

先于我们OEP执行

#include
#include
#include
#include
#include   
#include   
#include 
#include 
#pragma comment(linker,"/INCLUDE:__tls_used")  
// 告诉链接器我要用到TLSDWORD isDebug = 0;void NTAPI TLS_CALLBACK1(PVOID DllHandle, DWORD Reason, PVOID Reserved) {if (Reason == DLL_PROCESS_ATTACH){::MessageBoxA(0,"TLS函数执行1",0,0);//不接受内核调试信息/*NtSetInformationThread(GetCurrentThread(),ThreadHideFromDebugger,0,0);NtSetInformationProcess(GetCurrentProcess(),ProcessDebugPort,(PVOID)&isDebug,sizeof(DWORD),NULL);*/}}void NTAPI TLS_CALLBACK2(PVOID DllHandle, DWORD Reason, PVOID Reserved) {if (Reason == DLL_PROCESS_ATTACH){::MessageBoxA(0, "TLS函数执行2", 0, 0);}}int main()
{::MessageBoxA(0,"Main函数启动了",0,0);
}
//新建一段数据放入TLS这个目录里面
#pragma data_seg(".CRT$XLX")			
PIMAGE_TLS_CALLBACK pTLS_CALLBACKs[] = { TLS_CALLBACK1,  TLS_CALLBACK2, NULL };
#pragma data_seg()

image-20220616180649848

描述了TLS的结构体

image-20220616180820595

对应

在这里插入图片描述

可以理解为函数指针的数组

实例

#include   
#include   
#include 
#include 
#pragma comment(linker,"/INCLUDE:__tls_used")  
// 告诉链接器我要用到TLSDWORD dwDebugPort;
typedef NTSTATUS(__stdcall* pNtQueryInformationProcess)(IN HANDLE           ProcessHandle,IN PROCESSINFOCLASS ProcessInformationClass,OUT PVOID           ProcessInformation,IN ULONG            ProcessInformationLength,OUT PULONG          ReturnLength);void NTAPI TLS_CALLBACK1(PVOID DllHandle, DWORD Reason, PVOID Reserved) {if (Reason == DLL_PROCESS_ATTACH){::MessageBoxA(0,"TLS函数执行1",0,0);//不接受内核调试信息HMODULE hModule = LoadLibrary(TEXT("Ntdll.dll"));pNtQueryInformationProcess ntQueryInformationProcess = (pNtQueryInformationProcess)GetProcAddress(hModule, "NtQueryInformationProcess");ntQueryInformationProcess(GetCurrentProcess(), ProcessDebugPort, &dwDebugPort, sizeof(dwDebugPort), NULL);//dwDebugPort 为0表示没用被调试,反之则是}}//void NTAPI TLS_CALLBACK2(PVOID DllHandle, DWORD Reason, PVOID Reserved) {
//
//	if (Reason == DLL_PROCESS_ATTACH)
//	{
//		::MessageBoxA(0, "TLS函数执行2", 0, 0);
//
//	}
//
//}int main()
{     char str[] = "wust_is_good!";for (int i = 0; i < 14; ++i) {str[i] ^= dwDebugPort;}::MessageBoxA(NULL,str,"提示", MB_OK);
}
//新建一段数据放入TLS这个目录里面
#pragma data_seg(".CRT$XLX")			
PIMAGE_TLS_CALLBACK pTLS_CALLBACKs[] = { TLS_CALLBACK1,  /*TLS_CALLBACK2,*/ NULL };
#pragma data_seg()

如果直接运行

在这里插入图片描述

本地调试运行

在这里插入图片描述

一堆乱码

由于dwDebugPort是全局变量, 发现不是调试,置为0,0异或任何数都是该数本身

题目 Dest0g3 520迎新赛 tttea

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

注意到是xxtea的特征值

在这里插入图片描述

加密方式也是xxtea,实现部分把输入的44位flag ,组成11位int 类型的数据进行xxtea加密,最后与密文对比

原本是直接写的东西,直接魔改xxtea直接弄,发现跑出来是乱码,直接动态调试

构造flag

flag{12345678912345678912345678912345678911}

注意到字符串,image-20220616193828367

image-20220616193859423

发现TLS和反调试函数

image-20220616193937181

该字符串地址后24正好是key的位置

由于TLS一般在程序难以发现

最好使用查看PE文件的软件看各个段

PE结构里->数据目录表(常见的导出表、导入表等)->TLS表

所以,加入TLS_CALLBACK,在TLS表里会找到TLS回调函数,这是找到TLS回调的一个方法

image-20220616194825241

image-20220616194121230

image-20220616194354897

2个反调试

image-20220616194413039

这个是异或

所以真正的delta为0x66403319 ^ 0x12345678,即0x74746561

EXP

#include   
#include   
#include #define MX (((z>>6^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (key[(p&3)^e] ^ z))) void xxtea_decode(uint32_t* v, int n, DWORD delta)
{char* key = (char*)δuint32_t y, z, sum;unsigned p, rounds, e;rounds = 6 + 52 / n;sum = rounds * delta;y = v[0];do{e = (sum >> 2) & 3;for (p = n - 1; p > 0; p--){z = v[p - 1];y = v[p] -= MX;}z = v[n - 1];y = v[0] -= MX;sum -= delta;} while (--rounds);
}int main()
{DWORD delta = 0x74746561;char enc[] = { 3, 35, 34, 47, 54, 136, 253, 67, 33, 232, 91, 101, 49, 30, 59, 166, 75, 184, 220, 136, 128, 25, 132, 111, 151, 114, 33, 38, 173, 100, 238, 187, 136, 4, 77, 6, 47, 38, 229, 107, 129, 75, 245, 115 };xxtea_decode((uint32_t*)enc, 11, delta);printf("%s", enc);return 0;
}
//Dest0g3{73dd38c2-9d45-4f7a-9bd0-90a1e9907c1}

相关内容

热门资讯

前端-session、jwt 目录:   (1)session (2&#x...
linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
关于测试,我发现了哪些新大陆 关于测试 平常也只是听说过一些关于测试的术语,但并没有使用过测试工具。偶然看到编程老师...
前缀和与对数器与二分法 1. 前缀和 假设有一个数组,我们想大量频繁的去访问L到R这个区间的和,...
nodejs:本地安装nvm实... 一、背景-使用不同版本node的原因 vue3+ts、nuxt3版本,node...
JAVA集合知识整理 Java集合知识整理 HashMap相关 HashMap的底层数据结构:jdk1.8之...
无刷直流电机介绍及单片机控制实... 无刷直流电机介绍及单片机控制实例前言基本概念优势与劣势使用寿命基本结构使用单片机控制实例电子调速器&...
fwdiary(2) dp2 1.传纸条  AcWing 275. 传纸条 - AcWing 走两条路,走一条最大的...
常用的DOS命令 常用的DOS命令 DOS(Disk Operating System,磁...
<C++> 类和对象(下) 1.const成员函数将const修饰的“成员函数”称之为const成员函数,cons...