#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 |
댓글