본문 바로가기
reversing

TLS CALLBACK

by 코끼리_땃쥐 2022. 8. 31.
반응형
#include <windows.h>

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

void print_console(char* szMsg)
{
    HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);

    WriteConsoleA(hStdout, szMsg, strlen(szMsg), NULL, NULL);
}

void NTAPI TLS_CALLBACK1(PVOID DllHandle, DWORD Reason, PVOID Reserved)
{
    char szMsg[80] = {0,};
    wsprintfA(szMsg, "TLS_CALLBACK1() : DllHandle = %X, Reason = %d\n", DllHandle, Reason);
    print_console(szMsg);
}

void NTAPI TLS_CALLBACK2(PVOID DllHandle, DWORD Reason, PVOID Reserved)
{
    char szMsg[80] = {0,};
    wsprintfA(szMsg, "TLS_CALLBACK2() : DllHandle = %X, Reason = %d\n", DllHandle, Reason);
    print_console(szMsg);
}

#pragma data_seg(".CRT$XLX")
    PIMAGE_TLS_CALLBACK pTLS_CALLBACKs[] = { TLS_CALLBACK1, TLS_CALLBACK2, 0 };
#pragma data_seg()

DWORD WINAPI ThreadProc(LPVOID lParam)
{
    print_console("ThreadProc() start\n");

    print_console("ThreadProc() end\n");

    return 0;
}

int main(void)
{
    HANDLE hThread = NULL;

    print_console("main() start\n");

    hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
    WaitForSingleObject(hThread, 60*1000);
    CloseHandle(hThread);

    print_console("main() end\n");

    return 0;
}

두개의 TLS 콜백 함수(TLS_CALLBACK1, TLS)CALLBACK2)를 등록합니다. 그리고 콜백 함수에서 간단히 DllHandle과 REASON파라미터를 출력하고 종료합니다. main() 함수는 사용자 스레드(ThreadProc)를 생성 한 후 종료하는데, main()과 ThreadProc()내부에 각각 함수의 시작과 종료 로그를 출력합니다.

 

Reason

#define DLL_PROCESS_ATTACH    1

#define DLL_THREAD_ATTACH       2

#define DLL_THREAD_DETACH      3

#define DLL_PROCESS_DETACH    0

 

 

DLL_PROCESS_ATTACH

프로세스의 메인 스레드가 main() 함수를 호출 하기전에 등록된 TLS 콜백 함수들(TLS_CALLBACK1, TLS_CALLBACK2)이 호출됩니다. 이때 Reason 값은 1(DLL_PROCESS_ATTACH) 입니다.

 

DLL_THREAD_ATTACH

TLS 콜백 함수들이 모두 종료되면 main() 함수가 실행됩니다. 그리고 사용자 스레드(ThreadProc)를 생성하는 순간 Reason = 2(DLL_THREAD_ATTACH)로 TLS 콜백 함수들이 호출됩니다.

 

DLL_THREAD_DETACH

TLS 콜백 함수들이 모두 종료되면, ThreadProc() 스레드 함수가 실행 됩니다. 그리고 스레드 함수가 종료되는 순간 Reason = 3(DLL_THREAD_DETACH)로 TLS 콜백 함수들이 호출 됩니다.

 

DLL_PROCESS_DETACH

ThreadProc() 스레드가 종료되면 스레드의 종료를 기다리던 main()함수(메인스레드) 역시 종료합니다. 이때 마지막으로 Reason = 0(DLL_PROCESS_DETACH)값으로 TLS 콜백 함수들이 호출됩니다.

반응형

'reversing' 카테고리의 다른 글

IA-32 Instruction 포맷  (0) 2022.09.27
TEB  (0) 2022.09.16
CreateRemoteThread() API 호출 흐름  (0) 2022.08.29
Session in Kernel 6  (0) 2022.08.29
ASLR 이란?  (1) 2022.07.25

댓글