Results 1 to 2 of 2

Thread: # dynamic TLS callbacks instead of SEH

  1. #1
    Imported blog (Kris Kaspersky)
    Join Date
    May 2008

    # dynamic TLS callbacks instead of SEH

    static TLS are not static at all! actually, they’re dynamic. statically declared TLS could be changed in run-time without using any API. it’s possible to register/unregistered new TLS callbacks on the fly even after the file has been loaded.

    it was a long story - I tried to found where OS keeps TLS info, but was unable to do it. suddenly something hit me - maybe OS does not keep TLS info at all? maybe OS reads PE file directly? quick investigation confirmed this suggestion. as a matter of fact: OS re-reads PE-header and .tls every time it need the data.

    on any following even DLL_PROCESS_ATTACH, DLL_THREAD_ATTACH, DLL_THREAD_DETACH, DLL_PROCESS_DETACH Windows NT reads Data Directories -> TLS Directory. if VirtualAddress isn’t zero, OS reads Address of Callbacks Array and executes the first callback in the list. after it, OS reads the next element of Address of Callbacks Array.

    what does it mean? it means: a) we can add/remove new TLS callbacks from another TLS callback or the program; b) if TLS Directory does not fit our needs it’s possible to create the new one on the fly;

    guess, we have a program with statically declared TLS callbacks or without TLS at all. the program changes TLS array or creates it from the scratch. how interesting and how useful for malware!

    shell-codes and malware sometimes make errors leading to exceptions. not good! thus, malware uses SEH to intercept expectations and suppress them. it was easy. “was” because SafeSEH mechanism has been infixed. too bad for hackers! well, what’s about TLS? if TLS data or TLS callback array belongs to writable memory - no problem to change it on the fly. as it was mentioned before, any exception generated by TLS is suppressed by OS. so, we got what we want.

    moreover. guess, a hacker attacking an application, does something wrong and the application crashes. OS terminates it, Dr. Wantons saves the log for future analysis. quite common scenario, isn’t? well, dynamic TLS callbacks is absolute differing thing. TLS callback is called after the critical error, but _before_ process will be finished. in other words, malicious code inside TLS callbacks will be called _after_ Dr. Watson have finished loggin!!!

    another thing. add new TLS callback (or create TLS Dir from the scratch), raise an exception (kind of XOR EAX, EAX/MOV EAX, [EAX]) and… pass control to TLS. of course, critical message will appear, but… not every reverser will find out where control is passed after pressing “OK” key.

    no matter how TLS info is changed, it might be a local process or something else. yes, it’s possible to add new callback to another process, using WriteProcessMemory.

    to demonstrate this I wrote a simple test program adding TLS callback on the fly. download it and run. if you speaker makes “buzz” before and after Message Box it means the program works fine. otherwise: either you have no speaker, either something wrong.

    source code is very simple. see it bellow:

    BOOL WINAPI TLS_callback_01(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved);
    BOOL WINAPI TLS_callback_02(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved);

    // TLS callback_01 is declared statically
    // TLS callback_02 is not declared yet (will be added dynamically)
    DWORD ptr[] = { (DWORD) TLS_callback_01, 0, 0 };
    DWORD *xl[] = { (DWORD*) 0xEFBEADDE, ptr, ptr, (DWORD*) xl, ptr, 0, 0};

    // this callback is declared statically
    BOOL WINAPI TLS_callback_01(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
    // add new call-back
    if (fdwReason == 1) ptr[1] = (DWORD) TLS_callback_02;
    return 0×666;

    // this callback is not declared statically, will be added dynamically
    BOOL WINAPI TLS_callback_02(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
    // make sound
    Beep(96, 6000); return 0×999;

    // main function, just to be
    nezumi() { MessageBox(0, “press ok to hear buzz”, “[x]“, 0); }

  2. #2


    Sorry for my bad english

    the pointer of tls is in the header, if different of zero, go and look the address pointed by this and execute the code in this address, and you can change out of the header this pointer, and redirect the execution.
    But if the tls pointer in the header is zero, the header is not writable, and we cannot change this pointer, and 99% of the programs have this pointer with value zero in the header, in this cases, tls will be not executed at all, and we cannot change this value of zero in the header, only this is valid for programs users of tls with value different of zero, not for all, i think, correct me if i'm wrong.


Similar Threads

  1. Replies: 4
    Last Post: December 1st, 2011, 21:38
  2. TLS callbacks
    By omega_red in forum Advanced Reversing and Programming
    Replies: 3
    Last Post: January 10th, 2009, 03:20
  3. IDA and TLS callbacks
    By nezumi-lab in forum Blogs Forum
    Replies: 0
    Last Post: January 7th, 2009, 01:35
  4. Replies: 4
    Last Post: May 26th, 2006, 13:08
  5. SoftIce Server - dynamic stopping & restarting
    By Aimless in forum Tools of Our Trade (TOT) Messageboard
    Replies: 0
    Last Post: January 17th, 2003, 04:29

Tags for this Thread


Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts