Windows逆向工程提升之IMAGE_TLS_DIRECTORY

  • 公開視頻 ->?鏈接點擊跳轉公開課程
  • 博客首頁 ->????鏈接點擊跳轉博客主頁

目錄

TLS的作用

TLS的實現

靜態 TLS??

動態 TLS??

內部實現

回調機制

TLS Directory 的結構


TLS的作用

  • TLS (Thread Local Storage) 是一種用于為多線程應用程序提供線程獨立存儲空間的機制。在多線程程序中,每個線程可以有自己獨特的一組數據,互不干擾。

  • 保存線程狀態數據(如線程上下文)。

  • 避免線程之間共享全局變量導致的競爭和沖突。

  • 為每個線程提供獨立的緩存、統計等,不需要使用鎖機制。

TLS的實現

靜態 TLS??

在編譯時分配空間(通過 __declspec(thread) 或 thread_local 關鍵字)。

  • 通過使用 __declspec(thread) 聲明 TLS 數據。

  • 靜態 TLS 在編譯時分配,系統會自動初始化和清理。

  • 適用于預定義的 TLS 數據場景。

  • #include <windows.h>  
    #include <stdio.h>  // 聲明線程局部存儲變量  
    __declspec(thread) int tlsData = 0;  // 線程函數  
    DWORD WINAPI ThreadProc(LPVOID lpParameter) {  // 為當前線程初始化 TLS 數據  tlsData = (int)(size_t)lpParameter;  // 使用 TLS 數據  printf("Thread %d: TLS Data = %d\n", GetCurrentThreadId(), tlsData);  // 模擬工作  Sleep(1000);  return 0;  
    }  int main() {  // 創建線程  const int threadCount = 3;  HANDLE threads[threadCount];  for (int i = 0; i < threadCount; ++i) {  threads[i] = CreateThread(NULL, 0, ThreadProc, (LPVOID)(size_t)(i + 1), 0, NULL);  }  // 等待線程完成  WaitForMultipleObjects(threadCount, threads, TRUE, INFINITE);  // 清理句柄  for (int i = 0; i < threadCount; ++i) {  CloseHandle(threads[i]);  }  return 0;  
    }

動態 TLS??

運行時通過 API(如 TlsAlloc, TlsFree)動態管理。

  • 使用 TlsAlloc() 分配一個 TLS 索引,動態管理每個線程的 TLS 數據。

  • 每個線程負責分配、獲取和釋放自己的數據。

#include <windows.h>  
#include <stdio.h>  // 全局 TLS 索引  
DWORD g_TlsIndex;  // 線程函數  
DWORD WINAPI ThreadProc(LPVOID lpParameter) {  // 為當前線程分配 TLS 數據  int* tlsData = (int*)malloc(sizeof(int));  *tlsData = (int)(size_t)lpParameter; // 將線程傳遞的參數放入 TLS 數據  TlsSetValue(g_TlsIndex, tlsData);  // 使用 TLS 數據  printf("Thread %d: TLS Data = %d\n", GetCurrentThreadId(), *tlsData);  // 模擬工作  Sleep(1000);  // 釋放 TLS 數據  free(tlsData);  return 0;  
}  int main() {  // 1. 分配 TLS 索引  g_TlsIndex = TlsAlloc();  if (g_TlsIndex == TLS_OUT_OF_INDEXES) {  printf("Failed to allocate TLS Index\n");  return 1;  }  // 2. 創建線程  const int threadCount = 3;  HANDLE threads[threadCount];  for (int i = 0; i < threadCount; ++i) {  threads[i] = CreateThread(NULL, 0, ThreadProc, (LPVOID)(size_t)(i + 1), 0, NULL);  }  // 等待線程完成  WaitForMultipleObjects(threadCount, threads, TRUE, INFINITE);  // 3. 清理  for (int i = 0; i < threadCount; ++i) {  CloseHandle(threads[i]);  }  // 釋放 TLS 索引  TlsFree(g_TlsIndex);  return 0;  
}

內部實現

  • 每個線程都會分配一個線程環境塊(Thread Environment Block,TEB),TEB 結構中包含一個用于存儲 TLS 數據的區域:

  • 動態 TLS 的數據存儲在 TEB 的 TlsSlots 數組中,每個槽對應一個 TlsAlloc() 返回的索引。

  • 靜態 TLS 的數據在程序加載時由系統內存分配,并初始化到對應的線程。

    特性動態分配 TLS (Win32 API)靜態分配 TLS (__declspec(thread))
    易用性手動管理,需自己分配和釋放 TLS 數據自動完成線程初始化和銷毀,使用方便
    性能每個訪問可能需要一層索引查找,性能稍低編譯時分配,直接訪問內存,性能高
    生命周期動態分配,程序員負責管理生命周期由操作系統控制
    靈活性可以動態創建任意數量的 TLS只能事先聲明固定的 TLS 變量

回調機制

  • TLS 提供線程生命周期管理的機制:TLS 回調函數。這些回調函數會在以下情況下被調用:

  • 線程附加(Thread Attach):當線程啟動時,初始化 TLS 數據。

  • 線程分離(Thread Detach):當線程結束時,清理 TLS 數據。

#include <windows.h>  #ifdef _WIN64  
#pragma comment (linker, "/INCLUDE:_tls_used")  
#else  
#pragma comment (linker, "/INCLUDE:__tls_used")  
#endif  //#pragma comment (linker, "/INCLUDE:pTLS_CALLBACKs")  _declspec(thread) DWORD dw = 0x12345678;
_declspec(thread) DWORD dw1 = 0xCCCCCCCC;void NTAPI TLS_CALLBACK(PVOID DllHandle, DWORD Reason, PVOID Reserved) //TLS callback function  
{}void NTAPI TLS_CALLBACK1(PVOID DllHandle, DWORD Reason, PVOID Reserved) //TLS callback function  
{}#ifdef _WIN64  
#pragma const_seg(".CRT$XLB")  
EXTERN_C const
#else  
#pragma data_seg(".CRT$XLX")  
#endif  PIMAGE_TLS_CALLBACK pTLS_CALLBACKs[] = { TLS_CALLBACK, TLS_CALLBACK1,0 };#ifdef _WIN64  
#pragma const_seg()  
#else  
#pragma data_seg()  
#endif  int main(void)
{return 0;
}

TLS Directory 的結構

TLS 數據由 IMAGE_TLS_DIRECTORY 結構描述,其定義如下

  typedef struct _IMAGE_TLS_DIRECTORY {  ULONGLONG StartAddressOfRawData;   // TLS 數據起始地址(RVA)  ULONGLONG EndAddressOfRawData;     // TLS 數據結束地址(RVA)  ULONGLONG AddressOfIndex;          // TLS 索引表地址  ULONGLONG AddressOfCallBacks;      // TLS 回調數組地址  DWORD SizeOfZeroFill;              // 初始化為零的大小  DWORD Characteristics;            // 保留字段(通常為 0)  
} IMAGE_TLS_DIRECTORY64, *PIMAGE_TLS_DIRECTORY64;  
  • StartAddressOfRawData:

    • 指的是 TLS 初始化數據段的起始地址。

    • 這部分數據會復制到每個線程的 TLS 段中,作為初始化狀態。

  • EndAddressOfRawData:

    • TLS 初始化數據段的結束地址。

  • AddressOfIndex:

    • 指向一個 TLS 索引(通常位于線程環境塊 TEB 中),用于標識當前線程的 TLS 段。

  • AddressOfCallBacks:

    • 指向一個回調函數指針數組。在線程創建或退出時,這些回調函數會依次被調用。

  • SizeOfZeroFill:

    • 表示未初始化數據的大小,如果存在,則這部分數據會在 TLS 數據段初始化時清零。

  • Characteristics:

    • 通常保留字段,值通常為 0。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/82714.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/82714.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/82714.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

云效流水線Flow使用記錄

概述 最近在頻繁使用阿里云云效的幾款產品&#xff0c;如流水線。之前寫過一篇&#xff0c;參考云效流水線緩存問題。 這篇文章來記錄更多問題。 環境變量 不管是云效流水線Flow還是應用交付AppStack&#xff08;基于流水線&#xff0c;后文不再贅述&#xff09;&#xff0…

Android中獲取控件尺寸進階方案

在Android開發中,很多場景都需要獲取控件(View)的寬高信息,比如動態布局調整、動畫效果實現等。然而,直接在Activity的onCreate()中調用控件的getWidth()或getHeight()`方法,得到結果卻是0,因為控件還沒完成布局測量。 本文總結了幾種獲取控件大小的實用方法,并對各方…

android 輸入系統

一、輸入系統的核心角色與分層架構 Android 輸入系統的本質是橋梁&#xff1a;一端連接硬件驅動產生的原始事件&#xff0c;另一端將事件精準派發給應用窗口。整個過程涉及三層架構和多個關鍵組件&#xff0c;可類比為 “快遞分揀系統”&#xff1a; 1. 硬件與內核層&#xf…

ubuntu中,c和c+程序,預編譯、編譯、鏈接和運行命令

目錄 安裝編譯器一.c編譯運行&#xff08;粗暴簡單&#xff09;1.編寫 C 程序&#xff1a;2. 預處理&#xff1a;3.編譯&#xff1a;4. 匯編&#xff1a;5. 鏈接&#xff1a;6.運行 二.c編譯運行&#xff08;粗暴簡單&#xff09;1.編寫 C 程序&#xff1a;2.預處理&#xff1a…

【FastAPI】--2.進階教程(一)

【FastAPI】--基礎教程-CSDN博客 app.get和post的參數&#xff1a; 參數類型說明pathstr路由路徑&#xff08;如 "/marks"&#xff09;&#xff0c;必填。response_modelType[T]定義響應數據的模型&#xff08;如 percent&#xff09;&#xff0c;會自動校驗和序列…

KT6368A通過藍牙芯片獲取手機時間詳細說明,對應串口指令舉例

一、功能簡介 KT6368A雙模藍牙芯片支持連接手機&#xff0c;獲取手機的日期、時間信息&#xff0c;可以同步RTC時鐘 1、無需安裝任何app&#xff0c;直接使用系統藍牙即可實現 2、同時它不影響音頻藍牙&#xff0c;還支持一些簡單的AT指令進行操作 3、實現的方式&#xff1…

【平面波導外腔激光器專題系列】用于光纖傳感的低噪聲PLC外腔窄線寬激光器

----翻譯自Mazin Alalusi等人的文章 摘要 高性價比的 1550 nm DWDM平面外腔 &#xff08;PLANEX&#xff09; 激光器是干涉測量、布里淵、LIDAR 和其他光傳感應用的最佳選擇。其線寬<3kHz、低相位/頻率噪聲和極低的RIN。 簡介 高性能光纖分布式傳感技術是在過去幾年中開發…

企業微信內部網頁開發流程筆記

背景 基于ai實現企微側邊欄和工作臺快速問答小助&#xff0c;需要h5開發&#xff0c;因為流程不清楚摸索半天&#xff0c;所以記錄一下 一、網頁授權登錄 1. 配置步驟 1.1 設置可信域名 登錄企業微信管理后臺 進入"應用管理" > 選擇開發的具體應用 > “網…

WORD 轉 PDF 工具:排版 / 圖片 / 表格批量轉換提升辦公效率

各位辦公小能手們&#xff0c;今天來聊聊文檔工具里的WORD轉PDF工具&#xff01;這玩意兒到底是干啥的呢&#xff1f;咱來好好說道說道。 先說核心功能。第一個就是格式轉換&#xff0c;能把Word文檔轉換成PDF&#xff0c;不管是格式、排版&#xff0c;還是圖片、表格啥的&…

從逆流監測到智慧用電:ADL200N-CT系列單相導軌表賦能家庭綠色能源

在新能源浪潮席卷全球的當下&#xff0c;陽臺光伏以及家庭儲能&#xff08;戶儲&#xff09;系統逐漸成為眾多追求綠色生活、渴望實現能源自主家庭的新選擇。它不僅能有效利用太陽能等清潔能源&#xff0c;還能在用電高峰時段為家庭提供穩定電力支持&#xff0c;降低用電成本。…

std::thread的說明與示例

源于通義千問 在 C 中&#xff0c;std::thread 支持傳遞多種類型的函數作為線程入口點。你可以傳遞普通函數、類的成員函數、Lambda 表達式、函數對象&#xff08;仿函數&#xff09;等。以下是詳細的說明和示例。 1. 傳遞普通函數 普通函數是最簡單的用法。 示例 #include…

【Day38】

DAY 38 Dataset和Dataloader類 對應5. 27作業 知識點回顧&#xff1a; Dataset類的__getitem__和__len__方法&#xff08;本質是python的特殊方法&#xff09;Dataloader類minist手寫數據集的了解 作業&#xff1a;了解下cifar數據集&#xff0c;嘗試獲取其中一張圖片 import …

RabbitMQ 集群與高可用方案設計(三)

五、高可用方案設計與實現 &#xff08;一&#xff09;負載均衡與代理 1. HAProxy 配置 HAProxy 是一款廣泛應用的開源負載均衡器和代理服務器&#xff0c;它能夠實現對 RabbitMQ 集群節點的負載均衡和健康檢查&#xff0c;有效提高系統的可用性和性能。以下是使用 HAProxy …

機器學習第二十四講:scikit-learn → 機器學習界的瑞士軍刀

機器學習第二十四講&#xff1a;scikit-learn → 機器學習界的瑞士軍刀 資料取自《零基礎學機器學習》。 查看總目錄&#xff1a;學習大綱 關于DeepSeek本地部署指南可以看下我之前寫的文章&#xff1a;DeepSeek R1本地與線上滿血版部署&#xff1a;超詳細手把手指南 Scikit-…

百度ocr的簡單封裝

百度ocr地址 以下代碼為對百度ocr的簡單封裝,實際使用時推薦使用baidu-aip 百度通用ocr import base64 from enum import Enum, unique import requests import logging as logunique class OcrType(Enum):# 標準版STANDARD_BASIC "https://aip.baidubce.com/rest/2.0…

Ubuntu20.04 gr-gsm完整安裝教程

gr-gsm完整安裝教程 安裝gnuradio3.8安裝依賴項指定gnuradio源安裝gnuradio 安裝gr-gsm安裝依賴項安裝gr-gsm修改環境變量 安裝成功 安裝gnuradio3.8 安裝依賴項 sudo apt install git cmake g libboost-all-dev libgmp-dev swig python3-numpy python3-mako python3-sphinx …

(自用)Java學習-5.15(模糊搜索,收藏,購物車)

1. 模糊搜索商品功能 前端實現&#xff1a; 通過解析URL參數&#xff08;如search聯想&#xff09;獲取搜索關鍵字&#xff0c;發送AJAX GET請求到后端接口/product/searchGoodsMessage。 動態渲染搜索結果&#xff1a;若結果非空&#xff0c;循環遍歷返回的商品數據&#xff…

STM32 TIM 定時器深度剖析:結構、時基、中斷與應用開發(超形象詳解)

文章目錄 定時器&#xff08;TIM&#xff09;定時器種類與分布定時器的基本結構時基單元時基單元基本結構計數器計數方向時基單元時鐘來源計算寄存器預加載機制 自制延時函數獲取單片機當前時間實現延遲函數初始化定時器3的時基單元配置中斷編寫中斷響應函數測試延遲函數 定時器…

Java使用minio上傳整個目錄下的所有內容

目錄 1、添加相關配置 2、添加依賴 3、實現方法 1??基礎版&#xff1a; 2??優化版&#xff08;推薦使用&#xff09;&#xff1a; 3??上傳遠程主機上的目錄內容&#xff1a; 4??直接上傳遠程主機中的目錄內容 業務背景&#xff1a;需要需要minio進行上傳指定目錄下所有…

Python的分布式網絡爬蟲系統實現

1. 系統架構概述 一個典型的分布式網絡爬蟲系統通常包含以下幾個核心組件&#xff1a; 1.主節點&#xff08;Master Node&#xff09;&#xff1a; 任務調度&#xff1a;負責將抓取任務分配給各個工作節點。URL 管理&#xff1a;維護待抓取的 URL 隊列和已抓取的 URL 集合&a…