《逆向工程核心原理》——TLS回调函数
阅读原文时间:2023年07月11日阅读:1

pe中TLS(thread local storage)中函数的执行时机早于入口函数(entry point),

相关结构:

//
// Thread Local Storage
//

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

typedef struct _IMAGE_TLS_DIRECTORY64 {
ULONGLONG StartAddressOfRawData;
ULONGLONG EndAddressOfRawData;
ULONGLONG AddressOfIndex; // PDWORD
ULONGLONG AddressOfCallBacks; // PIMAGE_TLS_CALLBACK *;
DWORD SizeOfZeroFill;
union {
DWORD Characteristics;
struct {
DWORD Reserved0 : 20;
DWORD Alignment : 4;
DWORD Reserved1 : 8;
} DUMMYSTRUCTNAME;
} DUMMYUNIONNAME;

} IMAGE_TLS_DIRECTORY64;

typedef IMAGE_TLS_DIRECTORY64 * PIMAGE_TLS_DIRECTORY64;

typedef struct _IMAGE_TLS_DIRECTORY32 {
DWORD StartAddressOfRawData;
DWORD EndAddressOfRawData;
DWORD AddressOfIndex; // PDWORD
DWORD AddressOfCallBacks; // PIMAGE_TLS_CALLBACK *
DWORD SizeOfZeroFill;
union {
DWORD Characteristics;
struct {
DWORD Reserved0 : 20;
DWORD Alignment : 4;
DWORD Reserved1 : 8;
} DUMMYSTRUCTNAME;
} DUMMYUNIONNAME;

} IMAGE_TLS_DIRECTORY32;
typedef IMAGE_TLS_DIRECTORY32 * PIMAGE_TLS_DIRECTORY32;

例子:

#include
#include

//TLS回调函数测试
void NTAPI MY_TLS_CALLBACK(PVOID DllHandle, DWORD Reason, PVOID Reserved)
{
printf("CALL TLS 1\n");
switch (Reason)
{
case DLL_PROCESS_ATTACH:
printf("DLL_PROCESS_ATTACH\ttls 1\n");
break;
case DLL_THREAD_ATTACH:
printf("DLL_THREAD_ATTACH\ttls 1\n");
break;
case DLL_THREAD_DETACH:
printf("DLL_THREAD_DETACH\ttls 1\n");
break;
case DLL_PROCESS_DETACH:
//printf("DLL_PROCESS_DETACH\ttls 1\n");//进程结束时并没有输出,可能关闭了通道??
break;
}
}
void NTAPI MY_TLS_CALLBACK2(PVOID DllHandle, DWORD Reason, PVOID Reserved)
{
printf("CALL TLS 2\n");
switch (Reason)
{
case DLL_PROCESS_ATTACH:
printf("DLL_PROCESS_ATTACH\ttls 2\n");
break;
case DLL_THREAD_ATTACH:
printf("DLL_THREAD_ATTACH\ttls 2\n");
break;
case DLL_THREAD_DETACH:
printf("DLL_THREAD_DETACH\ttls 2\n");
break;
case DLL_PROCESS_DETACH:
//printf("DLL_PROCESS_DETACH\ttls 2\n");
break;
}
}
/*
#ifdef _M_AMD64
#pragma comment (linker, "/INCLUDE:_tls_used")
#pragma comment (linker, "/INCLUDE:p_tls_callback1")
#pragma const_seg(push)
#pragma const_seg(".CRT$XLX")
EXTERN_C const PIMAGE_TLS_CALLBACK p_tls_callback1[] = { MY_TLS_CALLBACK,MY_TLS_CALLBACK2,0 };
#pragma const_seg(pop)
#endif
#ifdef _M_IX86
#pragma comment (linker, "/INCLUDE:__tls_used")
#pragma comment (linker, "/INCLUDE:_p_tls_callback1")
#pragma const_seg(push)
#pragma const_seg(".CRT$XLX")
EXTERN_C const PIMAGE_TLS_CALLBACK p_tls_callback1[] = { MY_TLS_CALLBACK,MY_TLS_CALLBACK2,0 };
#pragma const_seg(pop)
#endif
*/

#ifdef _M_AMD64
#pragma comment(linker,"/INCLUDE:_tls_used")
#pragma const_seg(".CRT$XLX")
EXTERN_C const PIMAGE_TLS_CALLBACK p_tls_callback1[] = { MY_TLS_CALLBACK,MY_TLS_CALLBACK2,0 };
#pragma const_seg()
#endif

#ifdef _M_IX86
#pragma comment (linker, "/INCLUDE:__tls_used")
#pragma const_seg(".CRT$XLX")
EXTERN_C const PIMAGE_TLS_CALLBACK p_tls_callback1[] = { MY_TLS_CALLBACK,MY_TLS_CALLBACK2,0 };
#pragma const_seg()
#endif

DWORD WINAPI MyThreadFunction(LPVOID lpParam) {
int nb = *(int*)lpParam;
for (int i = 0; i < nb; ++i) {
printf("number: %d\n", i);
Sleep(1000);
}
return 1;
}
int main()
{
std::cout << "Hello World!\n";
DWORD dwThreadId=0;
int number = 3;

HANDLE hThread= CreateThread(  
    NULL,                   // default security attributes  
    0,                      // use default stack size  
    MyThreadFunction,       // thread function name  
    &number,          // argument to thread function  
    0,                      // use default creation flags  
    &dwThreadId);   // returns the thread identifier  
getchar();  

}

输出:

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器