Reverse Engineering for Beginners

(avery) #1

CHAPTER 65. THREAD LOCAL STORAGE CHAPTER 65. THREAD LOCAL STORAGE


.tls:00404000 ; Segment type: Pure data
.tls:00404000 ; Segment permissions: Read/Write
.tls:00404000 _tls segment para public 'DATA' use32
.tls:00404000 assume cs:_tls
.tls:00404000 ;org 404000h
.tls:00404000 TlsStart db 0 ; DATA XREF: .rdata:TlsDirectory
.tls:00404001 db 0
.tls:00404002 db 0
.tls:00404003 db 0
.tls:00404004 dd 1234
.tls:00404008 TlsEnd db 0 ; DATA XREF: .rdata:TlsEnd_ptr
...


1234 is there and every time a new thread starts, a newTLSis allocated for it, and all this data, including 1234, will be
copied there.


This is a typical scenario:



  • Thread A is started. ATLSis created for it, 1234 is copied torand_state.

  • Themy_rand()function is called several times in thread A.rand_stateis different from 1234.

  • Thread B is started. ATLSis created for it, 1234 is copied torand_state, while thread A has a different value in the
    same variable.


TLScallbacks


But what if the variables in theTLShave to be filled with some data that must be prepared in some unusual way? Let’s say,
we’ve got the following task: the programmer can forget to call themy_srand()function to initialize thePRNG, but the
generator has to be initialized at start with something truly random, instead of 1234. This is a case in whichTLScallbacks
can be used.


The following code is not very portable due to the hack, but nevertheless, you get the idea. What we do here is define a
function (tls_callback()) which is to be calledbeforethe process and/or thread start. The function initializes thePRNG
with the value returned byGetTickCount()function.


#include <stdint.h>
#include <windows.h>
#include <winnt.h>


// from the Numerical Recipes book:
#define RNG_a 1664525
#define RNG_c 1013904223


__declspec( thread ) uint32_t rand_state;


void my_srand (uint32_t init)
{
rand_state=init;
}


void NTAPI tls_callback(PVOID a, DWORD dwReason, PVOID b)
{
my_srand (GetTickCount());
}


#pragma data_seg(".CRT$XLB")
PIMAGE_TLS_CALLBACK p_thread_callback = tls_callback;
#pragma data_seg()


int my_rand ()
{
rand_state=rand_state*RNG_a;
rand_state=rand_state+RNG_c;
return rand_state & 0x7fff;
}


int main()
{
// rand_state is already initialized at the moment (using GetTickCount())

Free download pdf