日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

PE学习(九)第九章:TLS 动态TLS与静态TLS

發布時間:2025/3/20 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PE学习(九)第九章:TLS 动态TLS与静态TLS 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

第九章:線程局部存儲

PEB,在NT中,該結構可以從進程空間的FS:[0x30]處找到,PEB描述的信息主要包括:進程狀態、進程堆、PE映像信息等,其中Ldr記錄了進程加載進內存的所有模塊的基地址。
TLS技術:
動態線程局部存儲技術、靜態線程局部存儲技術
OS動態申請通過四個API,靜態則通過預先在PE文件中聲明數據存儲空間。
TlsAlloc函數一旦得到一個可用的索引值后,還會遍歷進程中的每個線程,并將對應的TLS存儲槽全部清0,再返回。
TlsSetValue/TlsGetValue為了速度沒有參數驗證的錯誤檢查,可以傳不是TlsAlloc返回的值作為參數。
TLS存儲槽實際對應于TEB中TlsSlot字段,用戶可以直接操作此字段

靜態線程局部存儲預先將變量定義在PE文件內部,一般使用.tls節存儲,在Visual C++中只要如下聲明
_declspec (thread) int tlsFlag = 1;
靜態線程局部存儲只有用于靜態加載,靜態連接到該DLL的其他DLL也要確保不被動態加載。

//動態TLS實例.386.model flat,stdcalloption casemap:noneinclude windows.inc include user32.inc includelib user32.lib include kernel32.inc includelib kernel32.libMAX_THREAD_COUNT equ 4;數據段.data hTlsIndex dd ? dwThreadID dd ? hThreadID dd MAX_THREAD_COUNT dup(0)dwCount dd ?szBuffer db 500 dup(0) szOut1 db '線程%d終止,用時:%d毫秒。',0 szErr1 db '讀取TLS槽數據時失敗!',0 szErr2 db '寫入TLS槽數據時失敗!',0;代碼段.code;---------- ; 初始化 ;---------- _initTime proc local @dwStartpushad;獲得當前時間,;將線程的創建時間與線程對象相關聯invoke GetTickCountmov @dwStart,eaxinvoke TlsSetValue,hTlsIndex,@dwStart.if eax==0invoke MessageBox,NULL,addr szErr2,\NULL,MB_OK.endifpopadret _initTime endp;---------- ; 獲取用時 ;---------- _getLostTime proc local @dwTemppushad;獲得當前時間,;返回當前時間和線程創建時間的差值invoke GetTickCountmov @dwTemp,eaxinvoke TlsGetValue,hTlsIndex.if eax==0invoke MessageBox,NULL,addr szErr2,\NULL,MB_OK.endifsub @dwTemp,eaxpopadmov eax,@dwTempret _getLostTime endp;---------- ; 線程函數 ;---------- _tFun proc uses ebx ecx edx esi edi,lParamlocal @dwCountlocal @tIDpushadinvoke _initTime;模擬耗時操作mov @dwCount,1000*10000mov ecx,@dwCount.while ecx>0dec @dwCountdec ecx.endw invoke GetCurrentThreadIdmov @tID,eaxinvoke _getLostTimeinvoke wsprintf,addr szBuffer,\addr szOut1,@tID,eaxinvoke MessageBox,NULL,addr szBuffer,\NULL,MB_OKpopadret _tFun endpstart:;通過在進程位數組中申請一個索引,;初始化線程運行時間記錄系統invoke TlsAllocmov hTlsIndex,eaxmov dwCount,MAX_THREAD_COUNTmov edi,offset hThreadID.while dwCount>0invoke CreateThread,NULL,0,\offset _tFun,NULL,\NULL,addr dwThreadIDmov dword ptr [edi],eaxadd edi,4dec dwCount.endw;等待結束線程mov dwCount,MAX_THREAD_COUNTmov edi,offset hThreadID.while dwCount>0mov eax,dword ptr [edi]mov dwThreadID,eaxpush ediinvoke WaitForSingleObject,eax,\INFINITEinvoke CloseHandle,dwThreadIDpop ediadd edi,4dec dwCount.endw;通過釋放線程局部存儲索引,;釋放時間記錄系統占用的資源invoke TlsFree,hTlsIndexend start


?

//靜態TLS實例.386.model flat,stdcalloption casemap:noneinclude windows.inc include user32.inc includelib user32.lib include kernel32.inc includelib kernel32.lib.dataszText db 'HelloWorldPE',0,0,0,0 ; 構造IMAGE_TLS_DIRECTORYTLS_DIR dd offset Tls1dd offset Tls2dd offset Tls3dd offset TlsCallBackdd 0dd 0 Tls1 dd 0 Tls2 dd 0 Tls3 dd 0 TlsCallBack dd offset TLSdd 0dd 0.data?TLSCalled db ? ;重進標志.codestart:invoke ExitProcess,NULLRET; 以下代碼將會在.code之前執行一次 TLS:; 變量TLSCalled是一個防重進標志。正常情況下該部分代碼; 會被執行兩次,但使用了該標識后,該代碼只在開始運行前; 執行一次cmp byte ptr [TLSCalled],1je @exitmov byte ptr [TLSCalled],1invoke MessageBox,NULL,addr szText,NULL,MB_OK@exit:RETend start

靜態TLS實例生成的exe需要手動修改下數據目錄表
根據 .data節???? 800文件偏移地址?? 3000內存偏移,szText占10字節
所有TLS數據目錄起始RVA修改為3010,大小為一個TLS數據目錄大小。能170文件偏移位置修改為10 30 00 00 18 00...

總結

以上是生活随笔為你收集整理的PE学习(九)第九章:TLS 动态TLS与静态TLS的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。