안티-리버싱 기법중에 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 을 사용하려는 분들 참고하시라고.. 살포시 올려봤습니다... ( 쿨럭;; )

YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST
  1. BlogIcon window31 2009.03.11 23:32  댓글주소  수정/삭제  댓글쓰기

    ㅋㅋ 그렇군. 근데 TLS Callback 크랙미 문제 말고는 실전에서 본적이 거의 없는듯 -_-;;

    • BlogIcon vbdream 2009.03.12 00:18  댓글주소  수정/삭제

      저도 악성코드 하나 빼곤 못봤다는...^^;;;

    • BlogIcon XeroNic(HS) 2009.03.12 09:29 신고  댓글주소  수정/삭제

      물론 일반적인 상황에서는 TLS Callback ..
      거의 안쓰이겠지만..뭐;;
      패커(프로텍터) 계열에서는 또 쓰이더라구요..ㅋ
      게다가 자기가 만든 프로그램에 보안코드를 넣을때..
      TLS Callback 을 이용하는 것도 괜찮은 방법이고해서..
      =0= 살포시.. :)

    • BlogIcon vbdream 2009.03.18 17:48  댓글주소  수정/삭제

      쓰이는 패커/프로텍터가 무엇이 있는지 알고 싶습니다...^^;;

      지금까지 TLS Callback을 쓰는 패커/프로텍터를 한번도 본적이 없어서요...

    • BlogIcon XeroNic(HS) 2009.03.18 18:11 신고  댓글주소  수정/삭제

      NoobyProtect 란게 있는데.. 이 녀석이 TLS Callback 을 참 멋지게 사용하더군요;;
      =0= 제가 사용하는 OllyDBG 1.10 시리즈랑~ 이뮤니티~
      파일을 오픈하거나 어태치 하면~ 그냥 디버거가 꺼져버린다는;;
      ( OllyDBG 2.0 으로 어느정도 분석이 가능합니다.. )
      요놈을 한번 찾아서 분석해보시면 되겠네요..^^

      아 참고로~ Nooby 로 패킹한것들.. Win98 에서는 실행안됩니다.^^;
      ( 업무상 아직까지 Win98 호환성을 고려해야되서리;; )

    • BlogIcon vbdream 2009.03.30 18:42  댓글주소  수정/삭제

      WoW... 쓰이고 있네요...*^^*

      좋은 정보 감사합니다.

  2. BlogIcon seyool 2009.03.12 17:57  댓글주소  수정/삭제  댓글쓰기

    감사합니다.. 유용한 정보네요.. :-)

  3. BlogIcon codewiz 2009.03.23 10:18  댓글주소  수정/삭제  댓글쓰기

    오홋. 유용한 정보네용...
    회사 개발자가 tls 콜백이 호출이 안된다고 하던게 저 문제 때문이었던 것 같네용.
    오늘 가서 아는척 해야겠습니당. ㅋㅋㅋㅋ~~

    • BlogIcon XeroNic(HS) 2009.03.23 11:36 신고  댓글주소  수정/삭제

      UI가 들어가는 개발을 하거나~~ 대부분의 경우엔
      USER32.DLL 이 로딩되니까 잘 동작하고...
      그래서 전혀 신경을 안썼는데,

      TLS Callback 만 집중해서 보려고~~
      콘솔용 테스트 코드를 작성해보니~~
      저런 현상이 발생하더라구요..^^;;

      아;; 또 TLS Callback 루틴에서..
      printf() 등의 런타임 함수 사용도 안되는거 같아요;
      ( 이건 실행될때의 문제겠지만요..ㅋㅋ )

  4. BlogIcon Sone 2010.04.04 13:57 신고  댓글주소  수정/삭제  댓글쓰기

    오래된 포스팅이긴 하지만...
    윈도 세븐에서는 user32 모듈이 로딩되지 않아도 tlscallback이 사용되는군요.
    또한 printf도 사용 가능합니다~