Reverse Engineering for Beginners

(avery) #1

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


printf ("%d\n", my_rand());
};


Let’s see it in IDA:


Listing 65.4: Optimizing MSVC 2013

.text:00401020 TlsCallback_0 proc near ; DATA XREF: .rdata:TlsCallbacks
.text:00401020 call ds:GetTickCount
.text:00401026 push eax
.text:00401027 call my_srand
.text:0040102C pop ecx
.text:0040102D retn 0Ch
.text:0040102D TlsCallback_0 endp


.rdata:004020C0 TlsCallbacks dd offset TlsCallback_0 ; DATA XREF: .rdata:TlsCallbacks_ptr


.rdata:00402118 TlsDirectory dd offset TlsStart
.rdata:0040211C TlsEnd_ptr dd offset TlsEnd
.rdata:00402120 TlsIndex_ptr dd offset TlsIndex
.rdata:00402124 TlsCallbacks_ptr dd offset TlsCallbacks
.rdata:00402128 TlsSizeOfZeroFill dd 0
.rdata:0040212C TlsCharacteristics dd 300000h


TLS callback functions are sometimes used in unpacking routines to obscure their processing. Some people may be confused
and be in the dark that some code executed right before theOEP^2.


65.1.2 Linux


Here is how a thread-local global variable is declared in GCC:


__thread uint32_t rand_state=1234;


This is not the standard C/C++ modifier, but a rather GCC-specific one^3.


TheGS:selector is also used to access theTLS, but in a somewhat different way:


Listing 65.5: Optimizing GCC 4.8.1 x86

.text:08048460 my_srand proc near
.text:08048460
.text:08048460 arg_0 = dword ptr 4
.text:08048460
.text:08048460 mov eax, [esp+arg_0]
.text:08048464 mov gs:0FFFFFFFCh, eax
.text:0804846A retn
.text:0804846A my_srand endp


.text:08048470 my_rand proc near
.text:08048470 imul eax, gs:0FFFFFFFCh, 19660Dh
.text:0804847B add eax, 3C6EF35Fh
.text:08048480 mov gs:0FFFFFFFCh, eax
.text:08048486 and eax, 7FFFh
.text:0804848B retn
.text:0804848B my_rand endp


More about it: [Dre13].


(^2) Original Entry Point
(^3) http://go.yurichev.com/17062

Free download pdf