《逆向工程核心原理》——TLS回调函数

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 <iostream>
#include <Windows.h>

//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();
}

 

输出:

 

posted @ 2020-08-14 20:42  DirWangK  阅读(542)  评论(0编辑  收藏  举报