一般的,我们用OllyDbg调试的时候,都是设置断在OEP(改第一个字节为0xcc)处,而TLS可以在OEP前被执行,
所以就可以玩玩了,就是把第一个字节再改过来,继续跑,不过应该没多大实用价值的,不过还是要分享下
直接上代码,TLS模板来自玩命大哥的《【成果6.3】软件保护壳专题 - 处理TLS表》
*************************************************************************************************
;加链接参数:/section:.text,RWE
.386
.model   flat,stdcall
option   casemap:none

include windows.inc
include user32.inc
include kernel32.inc

includelib user32.lib
includelib kernel32.lib

.data?
dwTLS_Index dd  ?

OPTION    DOTNAME       
.tls  SEGMENT                        
TLS_Start LABEL  DWORD
 dd    050h    dup ("slt.")
TLS_End   LABEL  DWORD
.tls   ENDS
OPTION    NODOTNAME

.data
TLS_CallBackStart   dd TlsCallBack0
TLS_CallBackEnd     dd 0

g_szTitle           db "Hello TLS",0
g_szInTls           db "我在TLS里",0
g_szInNormal        db "我在正常代码内",0
PUBLIC _tls_used
_tls_used IMAGE_TLS_DIRECTORY <TLS_Start, TLS_End, dwTLS_Index, TLS_CallBackStart, 0, ?>

.code
Start:
    db 055h, 08Bh, 0ECh, 06Ah, 0FFh, 068h, 0D0h, 070h, 040h, 000h
    db 068h, 08Ch, 032h, 040h, 000h, 064h, 0A1h, 000h, 000h, 000h
    db 000h, 050h, 064h, 089h, 025h, 000h, 000h, 000h, 000h, 083h
    db 0ECh, 058h, 053h, 056h, 057h, 0B8h  ;随便抠过来VC6.0入口的一段(24h)
    invoke MessageBox, NULL, addr g_szInNormal, addr g_szTitle, MB_OK
    invoke ExitProcess, 1
    ret

;; TLS的回调函数
TlsCallBack0 proc Dllhandle : LPVOID, dwReason : DWORD, lpvReserved : LPVOID
   mov eax, dwReason
   cmp eax, DLL_PROCESS_ATTACH
   jnz ExitTlsCallBack0
   invoke MessageBox, NULL, addr g_szInTls, addr g_szTitle, MB_OK
    ;mov BYTE   ptr[Start],06Ah     ;改回OEP继续跑,不被调试器断在入口
  ; cmp BYTE ptr[Start],0CCh      ;判断是否被下断和调试
  ; je Bye
    mov WORD ptr[Start],22EBh  ;直接jmp无用代码
   mov dword ptr[TLS_Start],0  
   xor eax, eax
   inc eax
ExitTlsCallBack0:   
   ret
Bye:
   invoke ExitProcess,0
TlsCallBack0   ENDP

end Start
*************************************************************************************************