• <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 閱讀(7512) 評論(0)  編輯 收藏 引用 所屬分類: 逆向工程windows系統

            <2009年8月>
            2627282930311
            2345678
            9101112131415
            16171819202122
            23242526272829
            303112345

            導航

            統計

            公告

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

            留言簿(9)

            隨筆分類(173)

            IT

            Life

            搜索

            積分與排名

            最新隨筆

            最新評論

            閱讀排行榜

            欧美午夜精品久久久久久浪潮| 久久久精品国产sm调教网站| 亚洲精品tv久久久久久久久久| 狠狠色丁香婷婷久久综合不卡| 国产欧美久久久精品影院| 国产免费久久久久久无码| 久久综合亚洲色一区二区三区| 久久精品国产男包| 国产精品一区二区久久国产| 人妻无码αv中文字幕久久琪琪布| av色综合久久天堂av色综合在| 国产综合久久久久久鬼色| 亚洲国产二区三区久久| 一级a性色生活片久久无少妇一级婬片免费放 | 亚洲成色WWW久久网站| 粉嫩小泬无遮挡久久久久久| 久久久久黑人强伦姧人妻| 欧美熟妇另类久久久久久不卡| 久久精品这里只有精99品| 亚洲精品国产美女久久久| 久久青青草原精品国产不卡| 国产∨亚洲V天堂无码久久久| 亚洲伊人久久综合影院| 伊人色综合久久天天人手人婷| 久久国产精品国产自线拍免费| 久久精品国产亚洲αv忘忧草 | 久久久精品久久久久特色影视| 青青草原综合久久大伊人| 日韩亚洲欧美久久久www综合网| 亚洲人AV永久一区二区三区久久| 波多野结衣久久精品| 国产福利电影一区二区三区久久老子无码午夜伦不 | 久久久国产精华液| 91精品国产高清久久久久久91| 国内精品伊人久久久影院| 久久狠狠色狠狠色综合| 久久婷婷五月综合色奶水99啪| 狠狠色综合网站久久久久久久高清| 97久久精品人人澡人人爽| 精品999久久久久久中文字幕| 久久无码AV一区二区三区|