• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            無我

            讓內心永遠燃燒著偉大的光明的精神之火!
            靈活的思考,嚴謹的實現
            豪邁的氣魄、頑強的意志和周全的思考

            線程本地存儲TLS(Thread Local Storage)的原理和實現——實現探究

            本文為線程本地存儲TLS系列之實現探究。
            我們在上一篇線程本地存儲TLS(Thread Local Storage)的原理和實現——分類和原理中曾經說過TLS可以分為兩類:靜態TLS和動態TLS。然后又分別說明了兩者在程序實現時的用法,并且還說明了windows對這兩類TLS的實現原理,我們本文的目的是從底層實現的角度深入探究,深刻理解原理。
            先考慮以下兩個問題:
            1、在上一篇中,我們說到靜態TLS數據是在編譯時放入.tls節,然后在系統加載程序時,會去尋找.tls節,并且分配一個足夠大的內存空間來存放所有這些靜態TLS變量。那么問題是,當程序加載后,對靜態TLS數據分配的內存空間在哪里呢?用什么來表示呢?
            2、在上一篇中,我們說到動態TLS是存放在每一個線程獨立的TLS slot數組中,這個數組的大小是TLS_MINIMUM_AVAILABLE維,那么這個數組在哪里呢?TlsSetValue和TlsGetValue應該就是訪問的這個數組,在取得索引的情況下,如果我們知道這個數組的位置,那么我們是否完全就能拋開上面兩個函數自己讀寫來測試呢?

            一、線程環境塊TEB
            在給出具體程序之前,我們有必要先討論一下線程環境塊TEB。
            我們知道,每個線程都有屬于自己的一系列數據,這些數據就是通過TEB來管理,當然就包括像TLS這樣的線程私有數據。那么TEB的結構是什么樣的呢?在微軟的文檔和頭文件上,我沒有查到TEB完整的信息,不過我們還是可以通過Windbg得到的,以下是TEB的詳細展開信息:

            nt!_TEB

            這個結構體包含的信息很多,我們此處只需要關注與TLS相關的,對其他的都忽略。所以我在程序里定義了以下這個結構體,用一些保留字段來控制相關域的偏移:

            //通過windgb查看_TEB得到的我的系統(winXP+SP3)中的_TEB的實現
            struct STEB
            {
                NT_TIB NtTib;
                PVOID EnvironmentPointer;
                
            //中間若干數據,與此處研究無關,故不展開,只標記偏移。下面的Reserved2,Reserved3也是同理
                BYTE Reserved1[12]; 
                PVOID ThreadLocalStoragePointer;    
            //指向存放靜態TLS數據的地址的指針的地址
                BYTE Reserved2[3552];
                PVOID TlsSlots[
            64];                    //指向存放動態TLS數據的TLS Slot數組
                BYTE Reserved3[132];
                PVOID TlsExpansionSlots;             
            //當索引大于63時,TlsSlots數組存不下了,就會新分配內存來存放,并且將指針記錄在這里
                
            //后面還有若干數據,與此處研究無關,故省略
            }
            ;

            以上就是我在之后兩個程序中要用到的直接訪問相關內存的線程TEB定義了。那么這個結構又是存放在哪里的呢?在windows系統上,該結構體的起始地址總是FS:[0]。而為了更方便的用指針訪問,我們用到了NT_TIB結構中的Self字段,Self指針就是指向自身的其實地址,也就是NT_TIB的首地址,也就是我們的STEB的首地址。在winnt.h中,NT_TIB定義如下:

            NT_TIB

            如同_TEB一樣,因為其他字段我們不關心,所以都不討論了,此處只需要知道Self指針就是指向自身,有了他,可以方便的進行指針訪問操作了。

            二、靜態TLS實現探究
            我們通過下面的程序來研究靜態TLS的實現。先說明程序的基本框架:在文件最開始,聲明了3個靜態TLS變量,并定義了要啟動的線程數。然后main函數啟動若干個線程,在線程函數中分別對3個TLS變量賦值,然后調用一個分析函數TlsMemFunc:這個函數用臨界區來防止線程的輸出相互干擾,首先用正常的方式打印出TLS變量的值,然后直接訪問內存存放靜態TLS變量的地方,自己獲取相關的值打印出來。從這個過程中,我們可以深入探究windows對靜態TLS內存管理的實現。程序如下,對關鍵部分都做了注釋,就不再額外說明了,不過要格外留心的是TlsMemFunc中指針操作的代碼,這是非常有趣的:

            靜態TLS研究程序

            要說明的是:由于debug版本,編譯器會自動分配一段內存來存放調試信息,從上面的代碼中,可以看到我已經對我的編譯環境VS2010進行了代碼調整(_DEBUG宏部分),但是如果你用的是別的編譯器,那我不確定他分配的是和VS2010一樣的,所以可能結果不正確,建議用Release版本來分析。
            程序運行結果如下:

            可以看出,通過直接訪問靜態TLS變量和訪問TEB中相關內存得到的是一樣的,由此我們就更加深入的理解了上一篇中講的靜態TLS的原理,也知道操作系統是如何管理和實現靜態TLS的。

            三、動態TLS實現探究
            我們通過下面的程序來研究動態TLS的實現。本程序的基本框架和靜態TLS程序結構大致相同,但是不需要聲明靜態TLS變量了,而是用TlsXXX系列函數來創建動態TLS數據。然后關鍵是分析函數TlsMemFunc:這個函數用臨界區來防止線程的輸出相互干擾,首先用TlsGetValue的方式打印出TLS變量的值,然后直接訪問內存讀取動態TLS變量并打印出來。要特別注意的是:TEB中存放動態TLS的數組只有64維,但是windowsNT支持1000多個TLS數據,這是利用擴展Slot指針來實現的,為了模擬這種情況,我特意在main中調用TlsAlloc直至索引超過64,而需要訪問擴展空間的情況。這些代碼很有趣,讀者可以自己嘗試修改觀察。從這個過程中,我們可以深入探究windows對動態TLS內存管理的實現。程序的關鍵部分都做了注釋,就不再額外展開了,不過與上面的程序一樣,請一定要細心研究TlsMemFunc對指針操作的代碼:

            動態TLS研究

            程序運行結果如下:

            同樣可以看出,通過TlsGetValue訪問動態TLS變量和訪問TEB中相關內存得到的是一樣的,由此我們就更加深入的理解了上一篇中講的動態TLS的原理,已經底層的Tls slots數組的實現情況。抽絲剝繭,一目了然!

            posted on 2012-07-04 08:57 Tim 閱讀(7482) 評論(0)  編輯 收藏 引用 所屬分類: 逆向工程windows系統

            <2011年7月>
            262728293012
            3456789
            10111213141516
            17181920212223
            24252627282930
            31123456

            導航

            統計

            公告

            本博客原創文章,歡迎轉載和交流。不過請注明以下信息:
            作者:TimWu
            郵箱:timfly@yeah.net
            來源:m.shnenglu.com/Tim
            感謝您對我的支持!

            留言簿(9)

            隨筆分類(173)

            IT

            Life

            搜索

            積分與排名

            最新隨筆

            最新評論

            閱讀排行榜

            久久人人爽人人人人爽AV| 久久青青国产| 人妻无码中文久久久久专区| 狠狠色丁香婷婷久久综合五月 | 2021久久国自产拍精品| 久久九九青青国产精品| 久久精品国产清自在天天线| 国产69精品久久久久APP下载| 亚洲va中文字幕无码久久| 国产成人久久激情91| 性欧美大战久久久久久久| 国产精品免费福利久久| 日本久久久久久久久久| A狠狠久久蜜臀婷色中文网| 久久免费国产精品| 国产精品美女久久久久网| 久久久无码精品亚洲日韩京东传媒 | 亚洲人成无码久久电影网站| 久久丫精品国产亚洲av不卡| 亚洲国产天堂久久综合网站| 久久久久久国产精品美女| 激情综合色综合久久综合| 欧美熟妇另类久久久久久不卡| 久久国产成人| 91久久国产视频| 狠色狠色狠狠色综合久久| 亚洲AV无码久久精品成人 | 久久久久一本毛久久久| 久久综合综合久久97色| 久久人人爽人人爽人人AV东京热| 理论片午午伦夜理片久久| 人人狠狠综合久久亚洲婷婷| 欧美熟妇另类久久久久久不卡| 99久久精品国产一区二区蜜芽| 亚洲精品无码久久一线| 一本一本久久aa综合精品| 色婷婷噜噜久久国产精品12p | 久久久久国产精品嫩草影院| 久久国产一区二区| 久久国产精品久久国产精品| 久久99国产精品99久久|