• <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
            來源:www.shnenglu.com/Tim
            感謝您對我的支持!

            留言簿(9)

            隨筆分類(173)

            IT

            Life

            搜索

            積分與排名

            最新隨筆

            最新評論

            閱讀排行榜

            77777亚洲午夜久久多人| 久久五月精品中文字幕| 狠狠色丁香婷综合久久| 久久精品成人免费看| 精品99久久aaa一级毛片| 国产69精品久久久久观看软件 | 香蕉久久夜色精品国产2020| 怡红院日本一道日本久久 | 无码AV中文字幕久久专区| 精品国产乱码久久久久久郑州公司| 日韩精品国产自在久久现线拍| 久久久久国产亚洲AV麻豆| 中文字幕久久波多野结衣av| 青青草原1769久久免费播放| 污污内射久久一区二区欧美日韩 | 久久99精品九九九久久婷婷| 久久丫忘忧草产品| 国产AⅤ精品一区二区三区久久| 少妇被又大又粗又爽毛片久久黑人| 久久亚洲中文字幕精品有坂深雪| 99久久成人18免费网站| 久久久久青草线蕉综合超碰| 亚洲国产成人久久综合碰碰动漫3d| 久久亚洲精品国产精品婷婷| 91精品婷婷国产综合久久| 亚洲级αV无码毛片久久精品| 精品久久国产一区二区三区香蕉 | 精品国产乱码久久久久软件| 久久99精品久久久久久齐齐| 久久不见久久见免费视频7| 久久99热这里只有精品66| AA级片免费看视频久久| 久久久av波多野一区二区| 思思久久99热只有频精品66| 国产—久久香蕉国产线看观看| 国产精品美女久久久久| 伊人色综合久久天天人手人婷| 久久精品国产只有精品66| 免费国产99久久久香蕉| .精品久久久麻豆国产精品| 少妇人妻88久久中文字幕|