调试TLS

来源:互联网 发布:最新义乌法院淘宝拍卖 编辑:程序博客网 时间:2024/05/21 09:05

前言

看资料时, 看到了TLS, 复习一下.
看看如果程序中带TLS回调, 如何找到并调试.
发现了一个知识点 : 在TLS函数中必须执行一个和Windows消息相关的API, 才会进(DLL_PROCESS_DETACH == Reason)
网上其他TLS资料, 演示TLS时, 都是在TLS中调用MessageBox, 都没有注意这个知识点.
在TLS中弹MessageBox, 实际程序中也不可能这么调用, 本来在TLS中做事, 就是想隐蔽一点,骗骗新手.
在程序中做TLS回调函数, 是在main函数之前跑代码的一种应用.

记录

测试程序

// @file TlsDebug.cpp// @brief TLS试验 on vc6#include "StdAfx.h"#include <windows.h>#include <stdlib.h>#include <time.h>DWORD g_StartAddressOfRawData = 0;DWORD g_EndAddressOfRawData = 0;DWORD g_AddressOfIndex = 0;             // PDWORDDWORD g_SizeOfZeroFill = 0;DWORD g_Characteristics = 0;DWORD g_dwData1 = 0;DWORD g_dwData2 = 0;VOID NTAPI tlsCb1(PVOID DllHandle, DWORD Reason, PVOID Reserved);VOID NTAPI tlsCb2(PVOID DllHandle, DWORD Reason, PVOID Reserved);// 声明 g_tlsCbAry, 关键是要加 extern "C"extern "C" PIMAGE_TLS_CALLBACK g_tlsCbAry[] = {    tlsCb1,    tlsCb2,    NULL};extern "C" IMAGE_TLS_DIRECTORY32 _tls_used = {    (DWORD)& g_StartAddressOfRawData,    (DWORD)& g_EndAddressOfRawData,    (DWORD)& g_AddressOfIndex,    (DWORD)g_tlsCbAry, // 这必须直接赋值为tls回调数组, PIMAGE_TLS_CALLBACK *    g_SizeOfZeroFill,    g_Characteristics};#pragma comment(linker, "/INCLUDE:__tls_used")int main(int argc, char* argv[]){    if (g_dwData1 > 0) {        printf("tlscb1 was called before main\r\n");    }    if (g_dwData2 > 0) {        printf("tlscb2 was called before main\r\n");    }    system("pause");    return 0;}/** run resulttlscb1 was called before maintlscb2 was called before main请按任意键继续. . .*/VOID NTAPI tlsCb1(PVOID DllHandle, DWORD Reason, PVOID Reserved){    // 发现一个很奇怪的问题, TLS函数中, 如果不调用MessageBox, 只有    // (DLL_PROCESS_DETACH == Reason)会来,    // 试验结论:    // * 在TLS函数中必须执行一个和Windows消息相关的API, 才会进(DLL_PROCESS_DETACH == Reason)    // 不能调用MessageBox, 有提示给用户, 太开玩笑了. 调用一个消息检测函数PeekMessageA    // * 不能调用内存分配函数(不能调用new 和 malloc, 会失败)    // * 这样看起来, 在TLS中做事很受限制.    MSG msg;    if (DLL_PROCESS_ATTACH == Reason) {        PeekMessageA(&msg, NULL, WM_KEYFIRST, WM_KEYLAST, PM_NOREMOVE);        g_dwData1++;    } else if (DLL_PROCESS_DETACH == Reason) {        g_dwData1--;    }}VOID NTAPI tlsCb2(PVOID DllHandle, DWORD Reason, PVOID Reserved){    if (DLL_PROCESS_ATTACH == Reason) {        g_dwData2++;    } else if (DLL_PROCESS_DETACH == Reason) {        g_dwData2--;    }}

在逆向时定位TLS函数

用CFF, LordPE, 或者其他工具, 查看PE文件的数据目录表, 可以看到是否存在TLS回调函数.
这里写图片描述
这里写图片描述
这里写图片描述
打开OD或IDA, 定位到CllBackTablerVA(VA值), 可以看到TLS函数有几个(最后一个TLS回调地址后面是0), VA是多少, 就可以分析TLS回调做的具体任务了.

CllBackTablerVA = 00426B40
在OD中定位TLS.CllBackTablerVA

00426B40 >0040100A  TlsDebug.0040100A00426B44  00401005  TlsDebug.0040100500426B48  0000000000426B4C  00000000

可以看到TLS回调有2个, 分别是sub_0040100A, sub_00401005
分析TLS回调

00401005   . /E9 D6010000   jmp     tlsCb20040100A   . |E9 31010000   jmp     tlsCb1

定位了TLS回调函数地址, 就可以分析TLS函数的反汇编代码了

00401140 >/> \55            push    ebp00401141  |.  8BEC          mov     ebp, esp00401143  |.  83EC 5C       sub     esp, 5C00401146  |.  53            push    ebx00401147  |.  56            push    esi00401148  |.  57            push    edi00401149  |.  8D7D A4       lea     edi, dword ptr [ebp-5C]0040114C  |.  B9 17000000   mov     ecx, 1700401151  |.  B8 CCCCCCCC   mov     eax, CCCCCCCC00401156  |.  F3:AB         rep     stos dword ptr es:[edi]00401158  |.  837D 0C 01    cmp     dword ptr [ebp+C], 10040115C  |.  75 32         jnz     short 004011900040115E  |.  8BF4          mov     esi, esp00401160  |.  6A 00         push    0                                ; /RemoveMsg = PM_NOREMOVE00401162  |.  68 08010000   push    108                              ; |MsgFilterMax = MSG(108)00401167  |.  68 00010000   push    100                              ; |MsgFilterMin = WM_KEYDOWN0040116C  |.  6A 00         push    0                                ; |hWnd = NULL0040116E  |.  8D45 E4       lea     eax, dword ptr [ebp-1C]          ; |00401171  |.  50            push    eax                              ; |pMsg00401172  |.  FF15 ECC24200 call    dword ptr [<&USER32.PeekMessageA>; \PeekMessageA00401178  |.  3BF4          cmp     esi, esp0040117A  |.  E8 D1000000   call    _chkesp0040117F  |.  8B0D B89D4200 mov     ecx, dword ptr [g_dwData1]00401185  |.  83C1 01       add     ecx, 100401188  |.  890D B89D4200 mov     dword ptr [g_dwData1], ecx0040118E  |.  EB 15         jmp     short 004011A500401190  |>  837D 0C 00    cmp     dword ptr [ebp+C], 000401194  |.  75 0F         jnz     short 004011A500401196  |.  8B15 B89D4200 mov     edx, dword ptr [g_dwData1]0040119C  |.  83EA 01       sub     edx, 10040119F  |.  8915 B89D4200 mov     dword ptr [g_dwData1], edx004011A5  |>  5F            pop     edi004011A6  |.  5E            pop     esi004011A7  |.  5B            pop     ebx004011A8  |.  83C4 5C       add     esp, 5C004011AB  |.  3BEC          cmp     ebp, esp004011AD  |.  E8 9E000000   call    _chkesp004011B2  |.  8BE5          mov     esp, ebp004011B4  |.  5D            pop     ebp004011B5  \.  C2 0C00       retn    0C
004011E0 >/> \55            push    ebp004011E1  |.  8BEC          mov     ebp, esp004011E3  |.  83EC 40       sub     esp, 40004011E6  |.  53            push    ebx004011E7  |.  56            push    esi004011E8  |.  57            push    edi004011E9  |.  8D7D C0       lea     edi, dword ptr [ebp-40]004011EC  |.  B9 10000000   mov     ecx, 10004011F1  |.  B8 CCCCCCCC   mov     eax, CCCCCCCC004011F6  |.  F3:AB         rep     stos dword ptr es:[edi]004011F8  |.  837D 0C 01    cmp     dword ptr [ebp+C], 1004011FC  |.  75 0F         jnz     short 0040120D004011FE  |.  A1 BC9D4200   mov     eax, dword ptr [g_dwData2]00401203  |.  83C0 01       add     eax, 100401206  |.  A3 BC9D4200   mov     dword ptr [g_dwData2], eax0040120B  |.  EB 15         jmp     short 004012220040120D  |>  837D 0C 00    cmp     dword ptr [ebp+C], 000401211  |.  75 0F         jnz     short 0040122200401213  |.  8B0D BC9D4200 mov     ecx, dword ptr [g_dwData2]00401219  |.  83E9 01       sub     ecx, 10040121C  |.  890D BC9D4200 mov     dword ptr [g_dwData2], ecx00401222  |>  5F            pop     edi00401223  |.  5E            pop     esi00401224  |.  5B            pop     ebx00401225  |.  8BE5          mov     esp, ebp00401227  |.  5D            pop     ebp00401228  \.  C2 0C00       retn    0C
0 0