• <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.¢%

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

            第二十章 DLL高級技巧

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

            第二十章 DLL高級技巧

            1.概覽

            ?1.1動態加載DLL文件 LoadLibraryEx

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

            PCTSTR pszDLLPathName,

            HANDLE hFile,

            DWORD dwFlags);

            ????????????? 返回DLL加載到進程空間原首地址。

            ????????????? dwFlags 可以有以下幾個值

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

            ????????????????????????????? 建議永遠不要使有這個值,它的存在僅僅是為了向后兼容、

            ????????????????????????????? 更多內容請訪問:http://blogs.msdn.com/oldnewthing/archive/2005/02/14/372266.aspx

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

            ????????????????????????????? 把要加載的DLL文件以數據文件的形式加載到進程中。

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

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

            ????????????????????????????? 與前者相同,不同的時獨占打開,禁止其它進程訪問和修改該DLL中的內容。

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

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

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

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

            ? 1.2 DLL 的加載與卸載

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

            ????????????????????????????? 不要在同一進程中,同時使用LoadLIbraryLoadLibraryEx加載同一DLL文件。

            ????????????????????????????? DLL的引用計數是以進程為單位的。LoadLibrary會把DLL文件加載到內存,然后映射到進程空間中。

            ????????????????????????????? 多次加載同一DLL只會增加引用計數而不會多次映射。當所有進程對DLL的引用計數都為0時,系統會在內存中釋放該DLL

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

            ????????????????????????????? FreeLibrary,FreeLibraryAndExitThread對當前進程的DLL的引用計數減1

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

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

            2.DLL的入口函數

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

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

            ????????????? HINSTANCE hInstDll, ""加載后在進程中的虛擬地址

            ????????????? DWORD fdwReason, ""系統因何而調用該函數

            ????????????? PVOID fImpLoad ""查看是隱工還是動態加載該DLL

            ?

            ????????????? DLLsDllMain方法來初始化他們自已。DllMain中的代碼應盡量簡單,只做一些簡單的初始化工作。

            ????????????? 不要在DllMain中調用LoadLibrary,FreeLibraryShell, ODBC, COM, RPC, socket 函數,從而避免不可預期的錯誤。

            ?

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

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

            ????????????? ?系統在為每個進程第一次加載該DLL時會,執行DLL_PROCESS_ATTACH后面的語句來初始化DLL,DllMain的返回值僅由它決定。

            ?系統會忽略DLL_THREAD_ATTACH等執行后DllMain的返回值。

            ????????????? ?如果DllMain返回FALSE,系統會自動調用DLL_PROCESS_DETACH的代碼并解除DLL文件中進程中的內存映射。

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

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

            ????????????????????????????? 如果DLL是因進程終止而卸載其在進程中的映射,那么負責調用ExitProcess的線程會調用DllMainDLL_PROCESS_DETACH所對應的代碼。

            ????????????????????????????? 如果DLL是因FreeLibraryFreeLibraryAndExitThread,而卸載其在進程中的映射,

            那么FreeLibraryFreeLibraryAndExitThread會負責調用DllMainDLL_PROCESS_DETACH所對應的代碼。

            ????????????????????????????? 如果DLL是因TerminateProcess而卸載其在進程中的映射,系統不會調用DllMainDLL_PROCESS_DETACH所對應的代碼。

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

            ????????????????????????????? 若進程是先加載的DLL,后創建的線程

            ????????????????????????????????????????????? 那么在進程中創建新線程時(主線程除外),系統會執行該進程已載的所有DLLDllMainDLL_THREAD_ATTACH對應的代碼。

            ????????????????????????????? 若進程是先創建的線程,后加載的DLL

            ????????????????????????????????????????????? 那么系統不會調用DLLDllMain中的代碼。

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

            ????????????? ??????????????? 進程中的線程退出時,會先執行所有已加載DLLDllMainDLL_THREAD_DETACH所對應的代碼。若該代碼中有死循環,線程不會退出。

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

            ?2.3 同步化DllMain的調用

            ????????????? 同一時間只能有一個線程調用DllMain中的代碼,所以下面的代碼會導致死循環

            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);// CreateThreadDLL_THREAD_ATTACH中的代碼,但是由于當前線程并未執行完畢,

            //所以DLL_THREAD_ATTACH中的代碼不會被執行,且CreateThread永無不會返回。

            ?

            ????? // 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.延時加載DLL

            (1)延時加載DLL的限制

            ????????????? 延時加載是指當程序在運行時用到DLL中的函數時自動會自動加載DLL函數,它與動態加載不同。

            ????????????? 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會先去該位置查找有無相應的鍵值與DLL要對應,若有則根據鏈值去%SystemRoot%"System32加載鍵值對應的DLL

            ????????????? 若無則根據默認規去尋找DLL

            ?

            5.Bind and Rebase Module

            ????????????? 它可以程序啟動的速度。ReBaseImage

            精品久久久久久无码专区| 久久综合狠狠综合久久97色| 久久久久亚洲AV无码去区首| 亚洲国产精品成人AV无码久久综合影院 | 伊人久久大香线蕉综合网站| 久久香综合精品久久伊人| 成人久久综合网| 亚洲乱码日产精品a级毛片久久 | 亚洲欧洲精品成人久久奇米网| 怡红院日本一道日本久久| 久久影视国产亚洲| 久久青草国产手机看片福利盒子| 久久久久国产| 97超级碰碰碰碰久久久久| 乱亲女H秽乱长久久久| 香港aa三级久久三级老师2021国产三级精品三级在 | 九九精品99久久久香蕉| 国产成人久久精品二区三区| 国产亚洲精品久久久久秋霞| 精品久久久久久国产牛牛app| 久久国产欧美日韩精品| 伊人久久大香线蕉无码麻豆| 激情五月综合综合久久69| 久久av无码专区亚洲av桃花岛| 人人狠狠综合久久亚洲高清| 国产精品对白刺激久久久| 久久婷婷五月综合色奶水99啪| 久久久久久久综合日本| 久久综合综合久久97色| 99久久精品日本一区二区免费| 亚洲精品午夜国产VA久久成人| 一本色道久久88综合日韩精品| 久久精品国产亚洲5555| 国产高潮久久免费观看| 国产精品久久久久一区二区三区 | 亚洲欧美另类日本久久国产真实乱对白| 久久精品国产精品青草app| 久久精品国产亚洲AV高清热 | 欧美伊人久久大香线蕉综合69 | 天天综合久久一二三区| 美女久久久久久|