2018 04 26 24 33 [c] 一個簡單方法讓window程式有anti-debug的能力

在網路上看到這段antidebug 的 code, 還蠻有趣的, 在這裡紀錄一下.
簡單說明, 就是靠一般的debugger並沒有debug tls 的能力.
所以, 安插code在initialize tls的時候檢查debugger是不是存在,
如果Debugger存在, 就直接terminate Process.
比較Tricky的部分是, 宣告了個per thread 的 var 變數,
而 var = 0xB15BADB0 這行是要讓 Visual C++知道有tls被使用.


#pragma section(".CRT$XLY", long, read)
__declspec(thread) int var = 0xDEADBEEF;
typedef VOID(NTAPI *PIMAGE_TLS_CALLBACK) (
    PVOID DllHandle,
    DWORD Reason,
    PVOID Reserved);

void WINAPI  TlsCallback(PVOID DllHandle, DWORD Reason, PVOID Reserved)
{
    var = 0xB15BADB0; // Required for TLS Callback call
    if (IsDebuggerPresent()) {
        TerminateProcess(GetCurrentProcess(), 0xBABEFACE);
    }
}
__declspec(allocate(".CRT$XLY"))PIMAGE_TLS_CALLBACK g_tlsCallback = TlsCallback;
Ref: https://www.codeproject.com/Articles/1090943/Anti-Debug-Protection-Techniques-Implementation-an

update 1:
找到方法, 不需要宣告 tls 的變數.
只需要告訴 linker 有要用 tls .
多加這段 #pragma comment (linker, "/INCLUDE:__tls_used")
程式就如下:


#pragma comment (linker, "/INCLUDE:__tls_used")
#pragma section(".CRT$XLY", long, read)

typedef VOID(NTAPI *PIMAGE_TLS_CALLBACK) (
    PVOID DllHandle,
    DWORD Reason,
    PVOID Reserved);

void WINAPI  TlsCallback(PVOID DllHandle, DWORD Reason, PVOID Reserved)
{
    if (IsDebuggerPresent()) {
        TerminateProcess(GetCurrentProcess(), 0xBABEFACE);
    }
}
__declspec(allocate(".CRT$XLY"))PIMAGE_TLS_CALLBACK g_tlsCallback = TlsCallback;