调试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
- 调试TLS
- TLS及TLS反调试
- TLS中检测断点反调试
- TLS线程本地存储进行反调试
- TLS
- TLS
- TLS
- TLS
- TLS
- TLS
- TLS
- TLS
- tls
- TLS
- TLS
- TLS(线程局部存储)以及基于TLS技术的反调试技术
- 错误调试:configure: error: ...No recognized SSL/TLS toolkit detected
- 一种基于TLS的高级反调试技术
- 程序员的沟通之痛
- 如何在textview中的字符串中添加图片显示
- 普通表转分区表
- python函数总结(更新中。。。)
- JavaScript项目中封装的util常用工具
- 调试TLS
- 动态规划之背包问题(一)
- YDB技术原理
- 分组统计
- Javascript的简单测试环境
- CentOS6.5下docker的安装及遇到的问题和简单使用
- 用SRS和FFMPEG进行直播流转码
- Loadrunner性能指标分析
- 升级nodejs方法