2020国产成人精品视频,性做久久久久久久久,亚洲国产成人久久综合一区,亚洲影院天堂中文av色

分享

dll 高級技術(shù)中--函數(shù)轉(zhuǎn)發(fā)器、KNOWDLL、DLL重定向知識收集

 herowuking 2015-05-24

4、函數(shù)轉(zhuǎn)發(fā)器

      函數(shù)轉(zhuǎn)發(fā)器(function forwarder)是DLL輸出段中的一個條目,用來將一個函數(shù)調(diào)用轉(zhuǎn)發(fā)到另一個DLL中的另一個函數(shù)。例如:如果用Visual C++的Dumpbin工具來查看Kernel32.dll那么我們會看到類似下面的輸出。

c:/Windows/System32>dumpbin -exports Kernel32.dll

 

 710  2C5          RtlFillMemory (forwarded to NTDLL.RtlFillMemory)

 711  2C6          RtlMoveMemory (forwarded to NTDLL.RtlMoveMemory)

 712  2C7          RtlUnwind (forwarded to NTDLL.RtlUnwind)

 713  2C8          RtlZeroMemory (forwarded to NTDLL.RtlZeroMemory)

這個輸出顯示了4個被轉(zhuǎn)發(fā)的函數(shù),如果應(yīng)用程序調(diào)用了RtlFillMemory,那么我們的可執(zhí)行文件會被動的鏈接到Kernel32.dll。當(dāng)可執(zhí)行文件運(yùn)行的時(shí)候,加載程序會載入Kernel32.dll并發(fā)現(xiàn)被轉(zhuǎn)發(fā)的函數(shù)實(shí)際上是在NTDLL.dll中,然后他會將NTDLL.dll模塊也一并載入。當(dāng)可執(zhí)行文件調(diào)用RtlFillMemory的時(shí)候,它實(shí)際上調(diào)用的是NTDLL.dll中的RtlFillMemory函數(shù)。

      如果我們調(diào)用RtlFillMemory ,那么GerProcAddress會先在Kernel32.dll的導(dǎo)出段中查找,并發(fā)現(xiàn)RtlFillMemory是一個轉(zhuǎn)發(fā)器函數(shù),于是它會遞歸調(diào)用GetProcAddress,在NTDLL的導(dǎo)出段中查找RtlFillMemory 函數(shù)。

      我們也可以在自己的DLL模塊中使用函數(shù)轉(zhuǎn)發(fā)器,最簡單的方法是使用pragma指示符,如下所示:

#pragma comment(linker,"/export:someFunc=DllWork.someOtherFunc")

這個pragma告訴鏈接器,正在編譯的DLL應(yīng)該導(dǎo)出一個名為someFunc的函數(shù),但實(shí)際上實(shí)現(xiàn)someFunc的是另一個名為someOtherFunc的函數(shù),該函數(shù)被包含在另一個DllWork.dll的模塊中。我們必須為每個想要轉(zhuǎn)發(fā)的函數(shù)單獨(dú)創(chuàng)建一行pragma。

5、已知的DLL

      系統(tǒng)對操作系統(tǒng)提供的某些DLL進(jìn)行了特殊處理,這些DLL被稱為已知的DLL(known DLL)。除了操作系統(tǒng)在載入它們的時(shí)候總是在同一個目錄中查找之外,它們與其它的DLL并沒有什么不同。在注冊表中有這么一個注冊表項(xiàng):

HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/Session Manager/KnownDLLs

      我們可以看到,這個注冊表項(xiàng)包含了一組值名,這些值名是一些DLL的名稱。每個值名的數(shù)據(jù)正好等于值名加上.dll擴(kuò)展名。(但這并不是必須的,稍候就會看到)。當(dāng)LoadLibrary或LoadLibraryEx被調(diào)用的時(shí)候,函數(shù)首先會檢查我們傳入的DLL的名字是否包含了.dll擴(kuò)展名。如果沒有包含,那么函數(shù)會用正常的搜索順序來搜索這個DLL。

如果我們指定了.dll擴(kuò)展名,那么這兩個函數(shù)會先將擴(kuò)展名去掉,然后再在KnownDLLs注冊表中搜索,看其中是否有與之相符的值名。如果沒有值名與之相符,那么函數(shù)會使用正常的搜索規(guī)則。但是,如果找到了與之相符的值名,那么系統(tǒng)會查看與值名相對于的數(shù)據(jù),并試圖用該數(shù)據(jù)來載入DLL。系統(tǒng)還會從注冊表項(xiàng)的DllDirectory值所表示的目錄中開始搜索DLL。在Windows XP中DllDirectory的默認(rèn)值為%SystemRoot%/system32

      為了舉例說明這一過程,假設(shè)我們在KnownDLLs注冊表項(xiàng)中添加了下列值:

value name:SomeLib

value data:SomeOtherLib.dll

調(diào)用LoadLibrary("SomeLib");的時(shí)候,系統(tǒng)會用正常的搜索規(guī)則來對這個DLL進(jìn)行定位.

但是,如果調(diào)用LoadLibrary("SomeLib.dll");的時(shí)候,系統(tǒng)會在knownDllsz注冊表中發(fā)現(xiàn)有一個與之相符的名稱。因此系統(tǒng)試圖載入的DLL是SomeOtherLib.dll而不是SomeLib.dll。它首先會在%SystemRoot%/system32目錄中查找SomeOtherLib.dll。如果在這個目錄中找到了該文件,那么系統(tǒng)就會將它載入,如果系統(tǒng)未能在這個目錄中找到該文件,那么LoadLibrary會失敗并返回NULL,這時(shí)調(diào)用GetLastError將返回ERROR_FILE_NOT_FOUND。

6、DLL重定向

      最初開發(fā)Windows的時(shí)候,內(nèi)存和磁盤空間都非常寶貴,因此為了節(jié)約這些寶貴的資源,Windows的設(shè)計(jì)目標(biāo)是盡可能的共享資源。出于這樣的考慮,Microsoft建議將多個應(yīng)用程序所共享的模塊放在Windows的系統(tǒng)目錄中,這使得系統(tǒng)能方便的定位和共享文件。C/C++運(yùn)行庫以及MFC就是很好的例子。

      隨著時(shí)間的推移,這成為了一個嚴(yán)重的問題,這是因?yàn)榘惭b程序可能會用老版本的文件覆蓋這個目錄中的文件,或用不完全兼容的新版本的文件覆蓋這個目錄中的文件,從而妨礙用戶的其它應(yīng)用程序的正常運(yùn)行。今天,硬盤不僅容量大而且價(jià)格便宜,內(nèi)存也夠用而且相對來說價(jià)格比以前要便宜很多。因此,Microsoft現(xiàn)在強(qiáng)烈建議開發(fā)人員將應(yīng)用程序的文件放到自己的目錄中,并且絕對不要碰Windows系統(tǒng)目錄中的任何東西。這樣既可以防止我們的應(yīng)用程序妨礙其它應(yīng)用程序,也可以避免其它應(yīng)用程序妨礙我們的應(yīng)用程序。

      為了幫助開發(fā)人員,Microsoft從Windows 2000開始新增了一項(xiàng)DLL重定向特性。這項(xiàng)特性強(qiáng)制操作系統(tǒng)的加載程序 首先從應(yīng)用程序的目錄中載入模塊。只有加載程序無法找到要找的文件時(shí),才會在其它目錄中搜索。

      為了強(qiáng)制加載程序總是先檢查應(yīng)用程序的目錄,我們所要做的就是將一個文件放到應(yīng)用程序的目錄中。這個文件的內(nèi)容無關(guān)緊要,但它的文件名必須是AppName.local。舉個例子,如果我們有一個名為SuperApp.exe的可執(zhí)行文件,那么重定向文件的名稱必須是SuperApp.exe.local。

      LoadLibrary(Ex)在內(nèi)部做了修改,來檢查這個文件存在與否。如果應(yīng)用程序的目錄中存在這個文件,那么系統(tǒng)會載入這個目錄中的模塊。如果應(yīng)用程序的目錄中不存在這個文件,那么LoadLibrary的工作方式與以往相同。注意:除了創(chuàng)建一個.local文件,我們還可以創(chuàng)建一個名為.locald的文件夾。在這種情況下,我們可以將自己的DLL保存在這個文件夾中,讓W(xué)indows能夠輕易找到他們。

      注意:為了安全性的緣故,Windows vista中這項(xiàng)特性在默認(rèn)情況下是關(guān)閉的----因?yàn)樗赡軙瓜到y(tǒng)從應(yīng)用程序的文件夾中載入偽造的系統(tǒng)DLL,而不是從Windows的系統(tǒng)文件夾中載入真正的系統(tǒng)DLL。為了打開這項(xiàng)特性,我們必須在HKLM/SoftWare/Microsoft/WindowsNT/CurrentVersion/Image File Execution Options注冊表項(xiàng)中增加一個條目DWORD DevOverrideEnable,并將它的值設(shè)為1。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多