我们知道TLS常用于反调试中
TLS的简单介绍:https://blog.csdn.net/Hotspurs/article/details/90298636
手工去除TLS要使用的工具:IDA,Winhex,PEview.exe
我在一个程序的代码中添加了两端TLS回调函数,用来进行反调试。
extern "C" NTSTATUS NTAPI NtQueryInformationProcess(HANDLE hProcess, ULONG InfoClass, PVOID Buffer, ULONG Length, PULONG ReturnLength);
void NTAPI __stdcall TLS_CALLBACK(PVOID DllHandle, DWORD dwReason, PVOID Reserved) //DllHandle模块句柄、Reason调用原因、 Reserved加载方式(显式/隐式)
{
if (IsDebuggerPresent())
{
MessageBoxA(NULL, "What are you doing??", "QUST-SEC warning", MB_ICONSTOP);
//MessageBoxA(NULL, "", "", MB_ICONSTOP);
ExitProcess(1);
}
}
void NTAPI __stdcall TLS_CALLBACK_2(PVOID DllHandle, DWORD Reason, PVOID Reserved)
{
HANDLE DebugPort = NULL;
if (!NtQueryInformationProcess(
NtCurrentProcess(),
7, // ProcessDebugPort
&DebugPort, // If debugger is present, it will be set to -1 | Otherwise, it is set to NULL
sizeof(HANDLE),
NULL))
{
if (DebugPort)
{
MessageBoxA(NULL, "", "", MB_ICONSTOP);
ExitProcess(1);
}
}
}
//使用TLS需要在程序中新建一个data段专门存放TLS数据,
//并且需要通知链接器在PE头中添加相关数据,所以有了这一段代码
#pragma comment (linker, "/INCLUDE:__tls_used")
#pragma comment (linker, "/INCLUDE:__tls_callback")
EXTERN_C
#pragma data_seg (".CRT$XLB")
//.CRT表明是使用C RunTime机制,$后面的XLB中:X表示随机的标识,L表示是TLS callback section,B可以被换成B到Y之间的任意一个字母,
//但是不能使用“.CRT$XLA”和“.CRT$XLZ”,因为“.CRT$XLA”和“.CRT$XLZ”是用于tlssup.obj的。
//共享数据段
PIMAGE_TLS_CALLBACK _tls_callback[] = { TLS_CALLBACK, TLS_CALLBACK_2, 0 };
//PIMAGE_TLS_CALLBACK _tls_callback[] = { 0 };
此时,在IDA中的导出窗口中,我们可以看到两个TLS函数以及start
下面就进行 TLS的手动去除
1.首先使用PEview打开目标文件
找到了TLS在头部的位置,在winhex中打开,找到1B0位置
将这一块填充为0
2.之后再找到TLS在数据段里的位置,并在winhex里将其填充为0
很明显,就是这一段
之后就可以保存文件,大功告成了