逆向 | windows TLS回调
之前逆向的时候偶尔会碰到tls回调,但是没有自己实现过,今天想着实现一下。
参考的代码来自 逆向工程核心原理。
代码如下:
#include <windows.h>
#pragma comment (linker, "/INCLUDE:__tls_used")
void print_console(char* msg) {
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
WriteConsoleA(hStdout, msg, strlen(msg), NULL, NULL);
}
DWORD WINAPI ThreadProc(LPVOID lParam) {
print_console("thread proc start \n");
print_console("thread proc end \n");
return 0;
}
VOID NTAPI TLS_CALLBACK1(PVOID DllHandle, DWORD Reason, PVOID Reversed) {
char msg[55] = { 0 };
wsprintfA(msg, "callback1: DllHandle=%X, Reason:%d \n", DllHandle, Reason);
print_console(msg);
MessageBox(0, 0, 0, 0);
}
VOID NTAPI TLS_CALLBACK2(PVOID DllHandle, DWORD Reason, PVOID Reversed) {
char msg[55] = { 0 };
wsprintfA(msg, "callback2: DllHandle=%X, Reason:%d \n", DllHandle, Reason);
print_console(msg);
}
#pragma data_seg(".CRT$XLB")
PIMAGE_TLS_CALLBACK pTLS_CALLBACKs[] = { TLS_CALLBACK1, TLS_CALLBACK2, 0 };
#pragma data_seg()
int main() {
print_console("main hello \n");
HANDLE hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);
WaitForSingleObject(hThread, 60 * 1000);
CloseHandle(hThread);
print_console("main bye\n");
return 0;
}
有一个很魔幻的事情出现了,我的编译环境是vc6 x86,然后编译完我的tls回调并没有执行。
于是我去查了pe,发现tls回调表的位置上并没有回调函数,回调函数地址呗填写在了一个很靠后的位置(应该是链接器填写的问题)
经过patch以后可以执行回调,ida也能成功识别。
tls表结构可以参考这个文章:https://blog.csdn.net/weixin_30615767/article/details/98577560
主要的结构就是这个:
typedef struct _IMAGE_TLS_DIRECTORY32
{
DWORD StartAddressOfRawData; // TLS初始化数据的起始地址
DWORD EndAddressOfRawData;// TLS初始化数据的结束地址 两个正好定位一个范围,范围放初始化的值
PDWORD AddressOfIndex;// TLS 索引的位置
PIMAGE_TLS_CALLBACK *AddressOfCallBacks;// Tls回调函数的数组指针
DWORD SizeOfZeroFill;// 填充0的个数
DWORD Characteristics;
} IMAGE_TLS_DIRECTORY32
就是回调数组指针上是一系列回调函数地址,结果链接器给我填错位置了,嗐。
标签:TLS,逆向,console,windows,print,msg,DWORD,回调 From: https://www.cnblogs.com/Mz1-rc/p/17296549.html