一般的,我们用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
*************************************************************************************************
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)