I have an app, obfuscated by FSG protector. When i tried to unpack it, the first thign that i had is, when i start the process with the debugger/or attach debugger later, i immediatly receive ACCESS VIOLATION exception, because Tls callback gets executed, with the following content:

.text:0063EE70 public TlsCallback_0
.text:0063EE70 TlsCallback_0:                          ; DATA XREF: .CRT:TlsCallbacks_0
.text:0063EE70 mov     [esi-6Dh], ebx
.text:0063EE73 xlat    byte ptr gs:[ebx]
.text:0063EE75 retf    155h

How is that even possible?? Are the registers inside tlscallback by default point to some sections/segments? Here the esi is used, but it has some default value, from the ntdll:ntdll_LdrShutdownThread+386

I attach the full stack trace, this is the stack trace from which this callback is called, when i run the application under ida pro+windbg, tls callback is hit prior to entry point.

stack trace

esi points to some DATA segment inside the application, is this the default os behaviour? Also the TLS directory here is defined like so:


As you can see TLS_end and TLS_start points to the image base.

So my question is, how is this callback not crashing the program without debugger? And why it is when i attach the debugger? It is some kind of anti-debuggin technique i can't understand

tls callback

3 Answers 3


It is an old anti-debugging trick to use the TLS callback. The code in the TLS gets executed before the executables entry point and the debugger gains control. This allows the TLS to check for the presence of the debugger and act accordingly.

One method to bypass it is using OllyDbg is to pause at "System breakpoint" instead of the default "WinMain" and I believe the Olly Advanced plugin allows you to break on TLS.

Possibly putting an INT 3 (0xCC) at the start of the TLS (and replacing the original byte) would break and allow you to step through to find the offending code, but I dont remember if this actually works or not, youll have to test it.


Exceptions in TLSCallbacks are discarded by Windows, but stop further callbacks from being called, and then control is transferred to the main entrypoint.

However, the code that you've shown for the TLSCallback looks like garbage, the registers aren't predictable, and I doubt that what you've shown is actually executed.

Note that the TLSCallback field not a single callback, it's a pointer to an array, but your screenshot has obscured the array pointer. Each callback is executed in turn, and any callback can alter the entries in the array for later callback entries.

The label for TlsEnd is not correct. The zero marks unused values in the first two fields (start and end of the memory region to reserve).

You can see examples of TLS on my site: http://pferrie.host22.com (assuming that it's working today) in the Company presentations section from 2008.


TLS callbacks may be executed on attach because the OS creates a new thread pointing to DbgUiBreakin with a software breakpoint to stop the execution of the program, and the new thread causes the TLS callback to be executed.

  • But on a process start, the tls callback is executed too right? The callback loooks exactly the same in static disassembly, how did they make it, that this callback is not getting executed, on process start ? And only run with debugger attaching Nov 27, 2017 at 21:40
  • Also this instructions here: mov [esi-6Dh], ebx, xlat byte ptr gs:[ebx] do not cause access violation for some reason, how is it that ebx and esi points to valid locations ? Nov 27, 2017 at 21:41
  • I don’t know, it’s difficult to say without the binary.
    – Igor Skochinsky
    Nov 27, 2017 at 21:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.