这个反调试的手法有一定的局限性,因为 TLS (线程局部存储)只是优先于 main 函数运行而已,并不是专门的反调试,所以 —— 这种反调试只能放置 OD ~ 打开,而不能防止 OD ~ 附加。
上代码:
// 指定一个 "/INCLUDE:__tls_used" 连接选项
#pragma comment(linker, "/INCLUDE:__tls_used")
VOID NTAPI TLS_CALLBACK(PVOID DllHandle,DWORD Reason,DWORD Reserved)
{
// Flag = PEB.BingDebugged,判断是否被调试
DWORD Flag;
__asm{
mov eax,fs:[0x30]
movzx eax,BYTE PTR DS:[eax+2]
mov Flag,eax
}
if(Flag==1){
MessageBox(NULL,"发现调试器,程序即将退出","LYSM",NULL);
ExitProcess(0);
}
else{MessageBox(NULL,"没有被调试,程序正常运行","LYSM",NULL);}
}
// 设置共享数据
#pragma data_seg(".CRT$XLX")
PIMAGE_TLS_CALLBACK pTLS_CALLBACKs[] ={(PIMAGE_TLS_CALLBACK)TLS_CALLBACK,0};
#pragma data_seg()
int main(int argc,char *argv[])
{
MessageBox(NULL,"现在运行到了 Main 函数","LYSM",NULL);
getchar();
return 0;
}
效果图:
注意:
此方法很 LOW,所以目前只对原版 OD 有效果,民间包 OD 是检测不到的。
补充
TLS是为了解决多线程变量同步问题,声明为TLS变量后,当线程去访问全局变量时,会将这个变量拷贝到自己线程中的TLS空间中,以防止同一时刻内多次修改全局变量导致变量不稳定的情况.