안티-리버싱 기법중에 TLS Callback 을 이용하는 방법이 있습니다.

( TLS Callback 에 대한 자세한 내용은 여기[Zesrever님 블로그]를  참조하시면 되겠네용... ^^ )

회사 프로젝트 때문에 TLS Callback 을 이리저리~~ 공부를 하는 중에 한가지를 알아냈는데요;;
( 이미 알고 계신 분들도 있겠지만.. 뭐..^^;; )


XP 이상에서 TLS Callback 을 사용하려면 USER32.DLL 이 꼭(?) 필요하더군요...

이런저런 유저레벨 디버거들을 방지하기 위한 코드를 TLS Callback 에서 실행시키려고...

온갖 삽질(?)을 다 해가며 결국 구현을 했는데..

이게 왠일..;;; 코드상으로는 특별히 문제가 될만한 부분이 없는데...

제가 원한대로 동작을 하지 않는거였습니다;;;;


이것땜에 한참 =0= 난감해했었는데...

알고보니 "USER32.DLL 이 로딩되지 않아서..." 라는 심히 허탈한 이유때문이더군요;;

궁금하신 분들은 아래의 샘플코드 긁어서 테스트해보시기 바랍니다.. -0- ㅎㅎㅎ; ( oTL;; )

#include <windows.h>
#include <stdio.h>

#pragma comment(linker, "/INCLUDE:__tls_used")

#pragma comment(lib, "KERNEL32.LIB")
#pragma comment(lib, "USER32.LIB")

DWORD g_dwValue = 0;

// TLS_Callback #1
void NTAPI tls_callback1(PVOID instance, DWORD reason, PVOID reserved)
{
    if (reason == DLL_PROCESS_ATTACH) {
        OutputDebugString("TLS_CALLBACK #1");

        g_dwValue += 1234;
    }
}

// TLS_Callback #2
void NTAPI tls_callback2(PVOID instance, DWORD reason, PVOID reserved)
{
    if (reason == DLL_PROCESS_ATTACH) {
        OutputDebugString("TLS_CALLBACK #2");

        g_dwValue *= 20;
    }
}

#pragma data_seg(".CRT$XLB")
PIMAGE_TLS_CALLBACK p_thread_callback[] = { tls_callback1, tls_callback2, 0 };
#pragma data_seg()

int main(void)
{
    // FindWindow(NULL, NULL);     // USER32.DLL 로드를 위해...

    printf("g_dwValue = %d\n\r", g_dwValue);

    return 0;
}

참고로 main() 의 FindWindow() 는 어디까지나 USER32.DLL 을 포함시키기 위해 들어간거랍니다;;

해당 FindWindow() 의 주석을 제거하면 tls_callback1, tls_callback2 가 제대로 호출되지만..

주석을 한 상태에서는 TLS Callback 루틴 자체를 타지 않습니다;;;

Win2000 에서는 USER32.DLL 이 있든 없든 상관없이... 정상적으로 TLS Callback 이 호출되는데 말이죠..

XP 이상에서는 꼭(?) USER32.DLL 이 로딩되어야 되는거 같네요;;..

TLS Callback 을 사용하려는 분들 참고하시라고.. 살포시 올려봤습니다... ( 쿨럭;; )