Skip to content

Instantly share code, notes, and snippets.

@wbenny
Created September 29, 2018 19:36
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wbenny/6d7fc92e9b5c3194ce56bf8c60d6191d to your computer and use it in GitHub Desktop.
Save wbenny/6d7fc92e9b5c3194ce56bf8c60d6191d to your computer and use it in GitHub Desktop.
TLS callback minimal example
//
// Merge .CRT section to .rdata (read only)
//
#pragma comment(linker, "/merge:.CRT=.rdata")
//
// Define variables marking the begin and the end
// of the TLS callback array.
//
#pragma section(".CRT$XLA", read)
__declspec(allocate(".CRT$XLA"))
const PIMAGE_TLS_CALLBACK __xl_a = NULL;
#pragma section(".CRT$XLZ", read)
__declspec(allocate(".CRT$XLZ"))
const PIMAGE_TLS_CALLBACK __xl_z = NULL;
//
// Custom-defined "extern" variable, which can be
// later assigned to the real array of TLS callbacks.
//
#pragma section(".CRT$XLM", read)
__declspec(allocate(".CRT$XLM"))
extern const PIMAGE_TLS_CALLBACK TlsCallbackArray;
//
// Strictly speaking, _tls_start, _tls_end and _tls_index
// should be located in the '.tls' section (read-write),
// while _tls_used should be located in the '.rdata' section
// (read-only) - as defined in the tlssup.cpp of the MSVC
// runtime.
//
char _tls_start = 0;
char _tls_end = 0;
unsigned int _tls_index = 0;
const IMAGE_TLS_DIRECTORY _tls_used = {
(ULONG_PTR)&_tls_start, // Start of tls data
(ULONG_PTR)&_tls_end, // End of tls data
(ULONG_PTR)&_tls_index, // Address of tls_index
(ULONG_PTR)(&__xl_a + 1), // Pointer to call back array
(ULONG)0, // Size of tls zero fill
(ULONG)0 // Characteristics
};
//////////////////////////////////////////////////////////////////////////
VOID
NTAPI
TlsCallback(
PVOID DllHandle,
DWORD Reason,
PVOID Reserved
)
{
__debugbreak();
}
const PIMAGE_TLS_CALLBACK TlsCallbackArray = { &TlsCallback };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment