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

            S.l.e!ep.¢%

            像打了激速一樣,以四倍的速度運(yùn)轉(zhuǎn),開(kāi)心的工作
            簡(jiǎn)單、開(kāi)放、平等的公司文化;尊重個(gè)性、自由與個(gè)人價(jià)值;
            posts - 1098, comments - 335, trackbacks - 0, articles - 1
              C++博客 :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

            第二十章 DLL高級(jí)技巧

            Posted on 2009-05-10 22:51 S.l.e!ep.¢% 閱讀(1106) 評(píng)論(0)  編輯 收藏 引用 所屬分類(lèi): DLL

            第二十章 DLL高級(jí)技巧

            1.概覽

            ?1.1動(dòng)態(tài)加載DLL文件 LoadLibraryEx

            ??????????????? HMODULE LoadLibraryEx(

            PCTSTR pszDLLPathName,

            HANDLE hFile,

            DWORD dwFlags);

            ????????????? 返回DLL加載到進(jìn)程空間原首地址。

            ????????????? dwFlags 可以有以下幾個(gè)值

            ????????????? (1) DONT_RESOLVE_DLL_REFERENCES

            ????????????????????????????? 建議永遠(yuǎn)不要使有這個(gè)值,它的存在僅僅是為了向后兼容、

            ????????????????????????????? 更多內(nèi)容請(qǐng)?jiān)L問(wèn):http://blogs.msdn.com/oldnewthing/archive/2005/02/14/372266.aspx

            ????????????? (2) LOAD_LIBRARY_AS_DATAFILE

            ????????????????????????????? 把要加載的DLL文件以數(shù)據(jù)文件的形式加載到進(jìn)程中。

            ????????????????????????????? GetModuleHandleGetProcAddress返回NULL

            ????????????? (3) LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE

            ????????????????????????????? 與前者相同,不同的時(shí)獨(dú)占打開(kāi),禁止其它進(jìn)程訪問(wèn)和修改該DLL中的內(nèi)容。

            ????????????? (4) LOAD_LIBRARY_AS_IMAGE_RESOURCE

            ????????????????????????????? 不修改DLL中的RVA,以image的形式加載到進(jìn)程中。常與LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE一起使用。

            ????????????? (5) LOAD_WITH_ALTERED_SEARCH_PATH

            ????????????????????????????? 修改DLL的加載路徑

            ? 1.2 DLL 的加載與卸載

            ????????????? (1)加載

            ????????????????????????????? 不要在同一進(jìn)程中,同時(shí)使用LoadLIbraryLoadLibraryEx加載同一DLL文件。

            ????????????????????????????? DLL的引用計(jì)數(shù)是以進(jìn)程為單位的。LoadLibrary會(huì)把DLL文件加載到內(nèi)存,然后映射到進(jìn)程空間中。

            ????????????????????????????? 多次加載同一DLL只會(huì)增加引用計(jì)數(shù)而不會(huì)多次映射。當(dāng)所有進(jìn)程對(duì)DLL的引用計(jì)數(shù)都為0時(shí),系統(tǒng)會(huì)在內(nèi)存中釋放該DLL

            ????????????? (2)卸載

            ????????????????????????????? FreeLibrary,FreeLibraryAndExitThread對(duì)當(dāng)前進(jìn)程的DLL的引用計(jì)數(shù)減1

            ????????????? (3) GetProcAddress

            ????????????????????????????? 取得函數(shù)地址。它只接受ANSI字符串。

            2.DLL的入口函數(shù)

            ??????????????? 2.1 DllMain

            ????????????? BOOL WINAPI DllMain(

            ????????????? HINSTANCE hInstDll, ""加載后在進(jìn)程中的虛擬地址

            ????????????? DWORD fdwReason, ""系統(tǒng)因何而調(diào)用該函數(shù)

            ????????????? PVOID fImpLoad ""查看是隱工還是動(dòng)態(tài)加載該DLL

            ?

            ????????????? DLLsDllMain方法來(lái)初始化他們自已。DllMain中的代碼應(yīng)盡量簡(jiǎn)單,只做一些簡(jiǎn)單的初始化工作。

            ????????????? 不要在DllMain中調(diào)用LoadLibrary,FreeLibraryShell, ODBC, COM, RPC, socket 函數(shù),從而避免不可預(yù)期的錯(cuò)誤。

            ?

            ??????????????? 2.2 fdwReason的值

            ????????????? ?(1)DLL_PROCESS_ATTACH

            ????????????? ?系統(tǒng)在為每個(gè)進(jìn)程第一次加載該DLL時(shí)會(huì),執(zhí)行DLL_PROCESS_ATTACH后面的語(yǔ)句來(lái)初始化DLL,DllMain的返回值僅由它決定。

            ?系統(tǒng)會(huì)忽略DLL_THREAD_ATTACH等執(zhí)行后DllMain的返回值。

            ????????????? ?如果DllMain返回FALSE,系統(tǒng)會(huì)自動(dòng)調(diào)用DLL_PROCESS_DETACH的代碼并解除DLL文件中進(jìn)程中的內(nèi)存映射。

            ????????????? ?

            ????????????? ?(2)DLL_PROCESS_DETACH

            ????????????????????????????? 如果DLL是因進(jìn)程終止而卸載其在進(jìn)程中的映射,那么負(fù)責(zé)調(diào)用ExitProcess的線程會(huì)調(diào)用DllMainDLL_PROCESS_DETACH所對(duì)應(yīng)的代碼。

            ????????????????????????????? 如果DLL是因FreeLibraryFreeLibraryAndExitThread,而卸載其在進(jìn)程中的映射,

            那么FreeLibraryFreeLibraryAndExitThread會(huì)負(fù)責(zé)調(diào)用DllMainDLL_PROCESS_DETACH所對(duì)應(yīng)的代碼。

            ????????????????????????????? 如果DLL是因TerminateProcess而卸載其在進(jìn)程中的映射,系統(tǒng)不會(huì)調(diào)用DllMainDLL_PROCESS_DETACH所對(duì)應(yīng)的代碼。

            ????????????? (3) DLL_THREAD_ATTACH

            ????????????????????????????? 若進(jìn)程是先加載的DLL,后創(chuàng)建的線程

            ????????????????????????????????????????????? 那么在進(jìn)程中創(chuàng)建新線程時(shí)(主線程除外),系統(tǒng)會(huì)執(zhí)行該進(jìn)程已載的所有DLLDllMainDLL_THREAD_ATTACH對(duì)應(yīng)的代碼。

            ????????????????????????????? 若進(jìn)程是先創(chuàng)建的線程,后加載的DLL

            ????????????????????????????????????????????? 那么系統(tǒng)不會(huì)調(diào)用DLLDllMain中的代碼。

            ????????????? (4) DLL_THREAD_DETACH

            ????????????? ??????????????? 進(jìn)程中的線程退出時(shí),會(huì)先執(zhí)行所有已加載DLLDllMainDLL_THREAD_DETACH所對(duì)應(yīng)的代碼。若該代碼中有死循環(huán),線程不會(huì)退出。

            ?????????????

            ?2.3 同步化DllMain的調(diào)用

            ????????????? 同一時(shí)間只能有一個(gè)線程調(diào)用DllMain中的代碼,所以下面的代碼會(huì)導(dǎo)致死循環(huán)

            BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD fdwReason, PVOID fImpLoad) {

            ?

            ?? HANDLE hThread;

            ?? DWORD dwThreadId;

            ?

            ?? switch (fdwReason) {

            ?? case DLL_PROCESS_ATTACH:

            ????? // The DLL is being mapped into the process' address space.

            ?

            ????? // Create a thread to do some stuff.

            ????? hThread = CreateThread(NULL, 0, SomeFunction, NULL,

            ???????? 0, &dwThreadId);// CreateThread會(huì)DLL_THREAD_ATTACH中的代碼,但是由于當(dāng)前線程并未執(zhí)行完畢,

            //所以DLL_THREAD_ATTACH中的代碼不會(huì)被執(zhí)行,且CreateThread永無(wú)不會(huì)返回。

            ?

            ????? // Suspend our thread until the new thread terminates.

            ????? WaitForSingleObject(hThread, INFINITE);

            ?

            ????? // We no longer need access to the new thread.

            ????? CloseHandle(hThread);

            ????? break;

            ?

            ?? case DLL_THREAD_ATTACH:

            ????? // A thread is being created.

            ????? break;

            ?

            ?? case DLL_THREAD_DETACH:

            ????? // A thread is exiting cleanly.

            ????? break;

            ?

            ?? case DLL_PROCESS_DETACH:

            ????? // The DLL is being unmapped from the process' address space.

            ????? break;

            ?? }

            ?? return(TRUE);

            }

            ?

            3.延時(shí)加載DLL

            (1)延時(shí)加載DLL的限制

            ????????????? 延時(shí)加載是指當(dāng)程序在運(yùn)行時(shí)用到DLL中的函數(shù)時(shí)自動(dòng)會(huì)自動(dòng)加載DLL函數(shù),它與動(dòng)態(tài)加載不同。

            ????????????? http://msdn2.microsoft.com/en-us/library/yx1x886y(VS.80).aspx

            ?

            4.已知的DLL (Known DLLs)

            ????????????? 位置:HKEY_LOCAL_MACHINE"SYSTEM"CurrentControlSet"Control"Session Manager"KnownDLLs

            ????????????? LoadLibrary在查找DLL會(huì)先去該位置查找有無(wú)相應(yīng)的鍵值與DLL要對(duì)應(yīng),若有則根據(jù)鏈值去%SystemRoot%"System32加載鍵值對(duì)應(yīng)的DLL

            ????????????? 若無(wú)則根據(jù)默認(rèn)規(guī)去尋找DLL

            ?

            5.Bind and Rebase Module

            ????????????? 它可以程序啟動(dòng)的速度。ReBaseImage

            亚洲国产精品成人久久蜜臀 | 中文字幕无码久久人妻| 亚洲中文字幕无码久久2020| 国产午夜福利精品久久2021| 欧美一级久久久久久久大| 久久久女人与动物群交毛片| 久久精品亚洲福利| 69国产成人综合久久精品| 中文精品99久久国产 | 亚洲精品无码久久久| 91精品国产色综合久久| 欧美日韩精品久久久久| 国产精品亚洲美女久久久| 亚洲AV成人无码久久精品老人| 久久五月精品中文字幕| 韩国免费A级毛片久久| 久久久久久久久久久久久久| 久久国产精品国语对白| 久久本道伊人久久| 久久久久久毛片免费播放| 久久婷婷是五月综合色狠狠| 久久国产高清一区二区三区| 精品一区二区久久| 久久久精品人妻一区二区三区蜜桃| 久久夜色精品国产噜噜亚洲a| 久久精品一区二区三区中文字幕| 久久777国产线看观看精品| 久久久久久夜精品精品免费啦| 久久久久久精品无码人妻| 久久青青草原亚洲av无码| 国产亚洲精久久久久久无码AV| 久久91亚洲人成电影网站| 久久综合综合久久综合| 亚洲国产精品无码久久久秋霞2| 无码人妻久久一区二区三区蜜桃 | 久久精品国产亚洲AV蜜臀色欲| 日韩欧美亚洲国产精品字幕久久久| 91亚洲国产成人久久精品| 久久青青草原精品影院| 香港aa三级久久三级| 岛国搬运www久久|