crackme杂记 006

本文探讨了C语言中TLS(Thread Local Storage)的使用,如何通过它实现反调试功能,以及利用TLS进行恒成立跳转(花指令)的技巧。作者介绍了如何在PE文件中创建TLS目录,并展示了如何在TLS回调中嵌入反调试代码以保护程序免受调试。
摘要由CSDN通过智能技术生成

c语言中什么函数执行的最早?
main函数吗?不是,还有更早执行的函数,比如初始化全局变量的构造函数。我们都知道,od在反汇编一个exe的时候会停止在oep的位置上,那么有比oep还要更早执行的函数吗?有的,比如TLS。

既然tls比ebp都早,那么我们是否可以利用到它呢?比如反调试,如下图代码

#include<iostream>
#include<tchar.h>
#include"ntdll/ntdll.h"
#include<windows.h>

DWORD isdebug = 0;

//下面这行告诉链接器在PE文件中要创建TLS目录
#pragma comment(linker,"/INCLUDE:_tls_used")

// 这是PIMAGE_TLS_CALLBACK()函数的原型
//其中第一个和第三个参数保留,第二个参数决定函数在那种情况下
void NTAPI my_tls_callback(PVOID h, DWORD reason, PVOID pv)
{
	///共有四个选项DLL_PROCESS_ATTACH、DLL_THREAD_ATTACH、DLL_THREAD_DETACH和DLL_PROCESS_DETACH
	//仅在进程初始化创建主线程时执行的代码
	if (reason == DLL_PROCESS_ATTACH)
	{
		//第一个参数L:线程句柄,第二个参数:你想干什么,ThreadHideFromDebugger(终端和内核之间调试信息的联系)
		//NtSetInformationThread(GetCurrentThread(), ThreadHideFromDebugger, 0, 0);
		//第一个参数:线程句柄,第二个参数:查询当前的调试窗口,如果当前是在被调试的话,返回一个PVOID类型的指针(参数3),如果为0则证明没有被调试,如果不为0,则证明被调试了。
		NtQueryInformationProcess(GetCurrentThread(), ProccessDebugPort, (PVOID)isDebug, sizeof(DWORD), NULL);
		MessageBox(NULL, "hi,this is a callback", "z1in", MB_OK);
	}
	return;
}

int main()
{
	char array2[] = { 0xc7,0xb2,0xa2,0xf1,0xa3,0xd9,0xa9,0xb6,0x10 };
	for (int i = 0; i < 9; i++)
	{
		array[i] = array[i] ^ 0x10 ^ isdebug;
	}
	MessageBoxA(NULL, "main函数执行", "提示", MB_OK);
	system("pause");
}

//新建一段数据,放到TLS这个目录表里面
#pragma data_seg(".CRT$XLX")
PIMAGE_TLS_CALLBACK pTLS_CALLBACKs[] = { TLS_CALLBACK,NULL };
#pragma data_seg()

通过创建一个TLS函数,然后再TLS函数里添加反调试函数,就可以阻止别人调试我们的exe。
这样会改变我们的pe结构,新增一个tls目录,里面存放着tls的结构体,AddressOfCallBacks 存放的就是回调函数的RVA,当然有时候也可能就是VA。TLS函数
在这里插入图片描述
既然可以反调试了,那么我们可以去利用这个反调试,如上代码,通过异或0x10对“注册成功”进行加密,然后再与变量isdebug进行异或运算,如果程序被调试了的话,就会使isdebug不为0,变成返回的指针值,从而使字符串变为乱码。

在这里插入图片描述
关于这里,有一个动态patch tls回调函数的骚操作,可以一直执行tls函数。原理没听懂,麻了。
先留着,以后解决。

花指令:
之前说过jmp实现的恒成立跳转从而实现花指令,也就是恒成立的eip跳转就能实现花指令,所以我们也可以这样实现:

call 00402032
add dword ptr ss:[esp],0x17
retn 

这样可以通过call会讲调用的地址压入栈中,然后其增加0x17,再通过retn实现恒成立跳转。

补充:在这里插入图片描述
这种[xxxxxxxx]的都是全局变量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值