TLS回调函数实现反调试


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<stdlib.h>
#include<time.h>
#include<string.h>
#include<tchar.h>
#include <stdio.h>  
#include <stdint.h>  
#include <windows.h>
#include <winternl.h>
#pragma comment(linker,"/INCLUDE:__tls_used")  
// 告诉链接器我要用到TLS

DWORD 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 <stdio.h>  
#include <stdint.h>  
#include <windows.h>
#include <winternl.h>
#pragma comment(linker,"/INCLUDE:__tls_used")  
// 告诉链接器我要用到TLS

DWORD 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 <stdio.h>  
#include <stdint.h>  
#include <windows.h>

#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*)&delta;
    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}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值