0x00 前言
做看雪ctf的时候,程序有TLS反调试机制,OD,WINDBG,没用。知己知彼,百战不殆,了解它,才能干掉它,结合前人经验和自己理解写了这篇文章。 —-
0x01 TLS简述
ThreadLocalStorage(TLS),是Windows为解决一个进程中多个线程同时访问全局变量而提供的机制。TLS可以简单地由操作系统代为完成整个互斥过程,也可以由用户自己编写控制信号量的函数。当进程中的线程访问预先制定的内存空间时,操作系统会调用系统默认的或用户自定义的信号量函数,保证数据的完整性与正确性。
而当Coder选择使用自己编写的信号量函数时,在应用程序初始化阶段,系统将要调用一个由用户编写的初始化函数以完成信号量的初始化以及其他的一些初始化工作。此调用必须在程序真正开始执行到入口点之前就完成,以保证程序执行的正确性。
划重点:TLS回调函数的执行,与数据的初始化,都在程序入口点之前执行,TLS是整个程序最最最最最早运行的地方,所以可以用这个特性,执行一些特殊操作。然后在最后程序退出时还会调用一次。
0x02 如何反调试?
往定义的TLS函数里写代码。 OD调试程序的时候,要先找到程序的入口点,跟拿着钥匙开门一样,找到孔,才能插钥匙。TLS回调函数,由于可以在程序中最最最最最早运行的时候执行,可以把在调试器检测到入口点之前,它自己检测是否存在调试。例如,检测加载环境是不是“OllyDbg”等。
0x03 验证一下
1.配置环境:VS2010,OllyDbg
2.测试代码
#include <Windows.h>
#include <stdio.h>
#include <tlhelp32.h>
void NTAPI __stdcall TLS_CALLBACK(PVOID DllHandle, DWORD dwReason, PVOID Reserved)
{
if (IsDebuggerPresent())
{
printf("Debugger detected\n");
MessageBox(NULL,TEXT("what are you doing?"),TEXT("warning"),MB_OK);
exit(0);
}
else
{
printf("No debugger\n");
}
}
#pragma comment (linker, "/INCLUDE:__tls_used")
#pragma comment (linker, "/INCLUDE:__tls_callback")
EXTERN_C
#pragma data_seg (".CRT$XLB")
PIMAGE_TLS_CALLBACK _tls_callback = TLS_CALLBACK;
#pragma data_seg ()
int main()
{
printf("main\n");
return 0;
}
** 注:由于运行环境造成的代码错误,自行解决 **
3.测试结果
整个代码的逻辑 一个TLS_CALLBALCK函数,如果检测到调试,输出Debugger detected,并且弹窗,退出程序。如果没有检测到,输出No debugger。 一个main函数,输出main。 正常情况下,运行程序的结果如下。
把他加载到od,点击运行,过了一会,出现了下图。
在此点击运行,可以发现程序直接结束了,并没有执行main函数的内容,而是直接调用两次tls。
0x04 反反调试
碰到这种程序,非要调试怎么办?
使用吾爱破解出品的od(本人太菜,目前只能这样,以后学习到了其他方法再来补~)