Skip to content

Instantly share code, notes, and snippets.

@gofman
Created July 11, 2022 23:43
#include <windows.h>
#include <stdio.h>
static int v1, v2, v3, v4;
static BYTE zero_rbx_code[] = { 0x48, 0x31, 0xdb, 0xc3, };
static void* exec_mem;
void (WINAPI *zero_rbx)(void);
VOID WINAPI tls_callback1(
PVOID DllHandle,
DWORD Reason,
PVOID Reserved)
{
if (!zero_rbx)
{
void* exec_mem;
exec_mem = VirtualAlloc(NULL, 0x1000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!exec_mem) printf("Error: VirtualAlloc failed.\n");
memcpy(exec_mem, zero_rbx_code, sizeof(zero_rbx_code));
zero_rbx = exec_mem;
}
if (Reason == DLL_PROCESS_ATTACH)
v1 = 1;
else if (Reason == DLL_THREAD_ATTACH)
v3 = 10;
printf("cb1 called, reason %u.\n", Reason);
zero_rbx();
}
VOID WINAPI tls_callback2(
PVOID DllHandle,
DWORD Reason,
PVOID Reserved)
{
printf("cb2 called, reason %u.\n", Reason);
if (Reason == DLL_PROCESS_ATTACH)
v2 = 2;
else if (Reason == DLL_THREAD_ATTACH)
v4 = 20;
}
//-------------------------------------------------------------------------
// TLS 32/64 bits example by Elias Bachaalany <lallousz-x86@yahoo.com>
#ifdef _M_AMD64
#pragma comment (linker, "/INCLUDE:_tls_used")
#pragma comment (linker, "/INCLUDE:p_tls_callback1")
#pragma comment (linker, "/INCLUDE:p_tls_callback2")
#pragma const_seg(push)
#pragma const_seg(".CRT$XLAAA")
EXTERN_C const PIMAGE_TLS_CALLBACK p_tls_callback1 = tls_callback1;
#pragma const_seg(".CRT$XLAAB")
EXTERN_C const PIMAGE_TLS_CALLBACK p_tls_callback2 = tls_callback2;
#pragma const_seg(pop)
#endif
#ifdef _M_IX86
#pragma comment (linker, "/INCLUDE:__tls_used")
#pragma comment (linker, "/INCLUDE:_p_tls_callback1")
#pragma data_seg(push)
#pragma data_seg(".CRT$XLAAA")
EXTERN_C PIMAGE_TLS_CALLBACK p_tls_callback1 = tls_callback1;
#pragma data_seg(".CRT$XLAAB")
EXTERN_C PIMAGE_TLS_CALLBACK p_tls_callback2 = tls_callback2;
#pragma data_seg(pop)
#endif
static DWORD WINAPI thread_proc(void* dummy)
{
return 0;
}
//-------------------------------------------------------------------------
int main(int argc, char* argv[])
{
HANDLE thread;
thread = CreateThread(NULL, 0, thread_proc, NULL, 0, NULL);
WaitForSingleObject(thread, INFINITE);
printf("%d, %d, %d, %d\n", v1, v2, v3, v4);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment