• <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>

            牽著老婆滿街逛

            嚴以律己,寬以待人. 三思而后行.
            GMail/GTalk: yanglinbo#google.com;
            MSN/Email: tx7do#yahoo.com.cn;
            QQ: 3 0 3 3 9 6 9 2 0 .

            TLS 處理

            轉載自:http://bbs.pediy.com/showthread.php?threadid=17839

            標 題: 翻譯 TLS 處理
            作 者: forgot
            時 間: 2005-10-23,12:19
            鏈 接: http://bbs.pediy.com/showthread.php?t=17839

            英語又退步了唉,不準就不準吧湊或看。

            支持 TLS

            原文:Writing Your Own Packer - by BigBoote

            TLS(Thread Local Storage,線程局部存儲)是一種便利的編程機制。我們通常不使用,因此并不太關心。但是要壓縮的原程序可能會用到它。事實上,Delphi 總是使用它,如果我們打算支持 Delphi 程序,最好兼容它。

            TLS 基本上是通過 API 實現。大致過程是,你分配一個“ Index(索引)”并存儲在一個全局變量中。通過這個 Index 獲得針對每個線程的一個雙字值。通常使用這個值保存一個為每個線程分配好的內存塊的指針。人們認為這樣很乏味,一個特殊機制的出現使得實現它更容易些。因此,你可以這樣寫代碼:

            __declspec ( thread ) int tls_int_value = 0;


            每個線程可以通過名稱訪問它獨特的實例,就像訪問其他變量一樣。我不知道這種 TLS 形式是否有官方名稱,所以我叫它“簡化 TLS”。這種機制與操作系統兼容,并且 PE 文件中有對應的結構。這些結構包含在數據目錄的一個塊中:

            origdirinfo[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress

            問題是, 處理這信息發生在由 OS 在每個線程的創建時刻,在執行到線程開始地址之前。(這句翻譯的拗口,原文 The problem is that the processing of this information happens by the OS on the creation of every thread prior to execution being passed to the thread start address. )這通常不牽涉到我們,除了至少一個線程在我們解壓數據之前被執行:我們的線程!我們必須設置一個偽 TLS 處理區段捕獲 OS 在我們開始之前做的事情,然后在最后一步把這個信息傳遞給原程序。

            為此,我在外部加殼器外部全局結構添加了2個項目:
            GlobalExternVars
            {
            //(other stuff we previously described)
            IMAGE_TLS_DIRECTORY tls_original;
            IMAGE_TLS_DIRECTORY tls_proxy;
            }
            ;

            加殼器將會在運行期復制原始數據到 tls_orginal 為我們所用。tls_proxy 幾乎是一個精確的副本,除了2個項目將會被修改:
            tls_proxy.AddressOfIndex
            tls_proxy.AddressOfCallBacks

            在這個塊中我們將要初始化 AddressOfIndex 指向一個正常的全局雙字變量,并且我們將初始化 AddressOfCallBacks 指向一個函數指針數組。它是一個線程創建時將會被調用的函數指針列表。用戶使用它定義 TLS 對象的初始化。唉,我沒見過一個編譯器使用它。此外,在 9x 下,這些函數不會被調用。盡管如此,我們還是要支持它以防萬一哪天它會被使用。我們令 AddressOfCallbacks 指向一個2個成員的數組,一個試我們將要執行的函數指針,另一個是 NULL 作為列表結束符。

            設置一個全局雙字存儲 TLS slot(槽?)
            DWORD TLS_slot_index;

            TLS 回調函數必須是這種原型:
            extern "C" void NTAPI TLS_callback ( PVOID DllHandle, DWORD Reason, PVOID Reserved );

            當然還要添加兩個邏輯標志表示是否可以安全地調用原來的回調函數,和是否延期調用。這樣初始化它們:
            bool safe_to_callback_tls = false;
            bool delayed_tls_callback = false;

            再提供一些變量保存延遲調用的數據:
            PVOID TLS_dll_handle = NULL;
            DWORD TLS_reason 
            = 0;
            PVOID TLS_reserved 
            = NULL;

            編寫回調函數:
            extern "C" void NTAPI TLS_callback ( PVOID DllHandle, DWORD Reason, PVOID Reserved )
            {
                    
            if ( safe_to_callback_tls )
                    
            {
                            PIMAGE_TLS_CALLBACK
            * ppfn = g_pkrdat.m_tlsdirOrig.AddressOfCallBacks;
                            
            if ( ppfn )
                            
            {
                                    
            while ( *ppfn )
                                    
            {
                                    (
            *ppfn) ( DllHandle, Reason, Reserved );
                                    
            ++ppfn;
                                    }

                            }


                    }

                    
            else
                    
            {
                            delayed_tls_callback 
            = true;
                            TLS_dll_handle 
            = DllHandle;
                            TLS_reason 
            = Reason;
                            TLS_reserved 
            = Reserved;
                    }

            }


            這樣會為 OS 提供一個存儲 slot 信息的地方,我們稍候恢復它,并且如果調用了我們的回調函數我們將捕獲參數,在解壓縮之后調用原來的回調函數。否則會出錯因為 0S 會在我們有機會解壓縮之前做這件事情。解壓縮之后,我們把參數傳遞給原來的回調函數。

            最后一步是這樣的:
            void FinalizeTLSStuff()
            {
                    
            if ( origdirinfo[IMAGE_DIRECTORY_ENTRY_TLS].VirtualAddress != 0 )
                    
            {
                            
            *gev.tls_original.AddressOfIndex = TLS_slot_index;
                            
            void* TLS_data;

                            __asm
                            
            {
                            mov ecx, DWORD PTR TLS_slot_index;
                            mov edx, DWORD PTR fs:[02ch]
                            mov ecx, DWORD PTR [edx
            +ecx*4]
                            mov pvTLSData, ecx
                            }


                            
            int size = gev.tls_original.EndAddressOfRawData - gev.tls_original.StartAddressOfRawData;

                            memcpy ( pvTLSData, (
            void*) gev.tls_original.StartAddressOfRawData, size );
                            memset ( (
            void*) gev.tls_original.EndAddressOfRawData, 0,
                            gev.tls_original.SizeOfZeroFill );
                    }


                    safe_to_callback_tls 
            = true;
                    
            if ( delayed_tls_callback )
                    
            {
                            TLSCallbackThunk ( TLS_dll_handle TLS_reason TLS_reserved );
                    }

            }

            posted on 2008-04-29 14:46 楊粼波 閱讀(494) 評論(0)  編輯 收藏 引用

            色妞色综合久久夜夜| 亚洲国产精品久久66| 精品久久久无码21p发布| 亚洲国产另类久久久精品小说| 一本一本久久A久久综合精品 | 无码人妻少妇久久中文字幕| 国色天香久久久久久久小说| 久久99国产综合精品女同| 国内精品久久久久久久coent| 亚洲精品国产自在久久| 久久电影网一区| 国产偷久久久精品专区| 欧美久久精品一级c片片| 久久亚洲AV成人无码| 99久久亚洲综合精品成人| 伊人色综合久久天天人手人婷| 久久国产精品免费一区| 久久91精品国产91久久户| 久久精品国产亚洲AV蜜臀色欲| 精品久久久久久国产免费了| 久久久一本精品99久久精品88| 手机看片久久高清国产日韩| 狠狠人妻久久久久久综合蜜桃| 一本一本久久A久久综合精品| 久久嫩草影院免费看夜色| 久久最新精品国产| 狠狠色丁香久久婷婷综合五月 | 99久久国产免费福利| 久久久噜噜噜www成人网| 国内精品人妻无码久久久影院导航| 久久乐国产精品亚洲综合| 久久精品国产WWW456C0M| 99久久国产亚洲高清观看2024| 99久久无色码中文字幕| 99国产精品久久| 久久综合九色综合精品| 国产精品亚洲综合专区片高清久久久| 国产亚洲美女精品久久久久狼| 国产亚洲综合久久系列| 国产欧美久久久精品| 91久久精品电影|