免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
《Windows核心編程系列》二十談?wù)凞LL高級技術(shù)

      本篇文章將介紹DLL顯式鏈接的過程和模塊基地址重定位及模塊綁定的技術(shù)。

      第一種將DLL映射到進(jìn)程地址空間的方式是直接在源代碼中引用DLL中所包含的函數(shù)或是變量,DLL在程序運(yùn)行后由加載程序隱式的載入,此種方式被稱為隱式鏈接。

      第二種方式是在程序運(yùn)行時(shí),通過調(diào)用API顯式的載入所需要的DLL,并顯式的鏈接所想要鏈接的符號。換句話說,程序在運(yùn)行時(shí),其中的一個(gè)線程能夠顯式的將該DLL調(diào)用到進(jìn)程地址空間中,并得到DLL中某函數(shù)的在進(jìn)程地址空間的虛擬地址,然后調(diào)用該函數(shù)。此種方式被稱為顯式鏈接。

      注意:顯式載入某DLL時(shí),不需要該dllLib文件,且exe文件中并不包含該dll的導(dǎo)入表。

顯示載入DLL模塊的步驟:

    線程可以調(diào)用LoadLibrary將一個(gè)DLL映射到進(jìn)程地址空間。

 

  1. HMODULE LoadLibrary(PCTSTR pszDLLPathName);  


     該函數(shù)會(huì)試圖對程序想載入的DLL進(jìn)行定位,并試圖將該DLL映射到調(diào)用進(jìn)程的地址空間中。返回是DLL在調(diào)用進(jìn)程的虛擬地址。即模塊的句柄。如果無法將DLL載入到進(jìn)程地址空間中返回值為NULL.

     與它類似的另一個(gè)函數(shù)

  1. HMODULE LoadLibraryEx(PCTSTR pszDLLPathName,HANDLE hFile,DWORD dwFlags);  


      也可以實(shí)現(xiàn)將DLL載入到進(jìn)程地址空間的目的。具體請參考MSDN

     加載后如果程序不再需要該DLL,可以調(diào)用FreeLibraryDLL從進(jìn)程地址空間中卸載:

  1. BOOL FreeLibrary( HMODULE  hInstDll );  


    也可以調(diào)用FreeLibraryEx卸載某DLL

    以下函數(shù)不僅具有從進(jìn)程地址空間卸載某DLL的功能,還能退出調(diào)用線程:

  1. VOID FreeLibraryAndExitThread(HMODULE hInstDll,DWORD dwExitCode)  
  2.   
  3. {  
  4.   
  5.  FreeLibrary(HMODULE hInstDll);  
  6.   
  7.  ExitThread(dwExitCode);  
  8.   
  9. }  


       剛見到時(shí)或許你會(huì)覺得它很多余??紤]下面的情形:

       我們調(diào)用一個(gè)DLL,該DLL中的代碼會(huì)創(chuàng)建一個(gè)線程,當(dāng)此線程完成工作后,可以調(diào)用FreeLibraryExitThreadDLL從進(jìn)程地址空間中卸載,并終止自己。由于線程是由DLL創(chuàng)建的,線程執(zhí)行的代碼也在DLL中,當(dāng)線程調(diào)用FreeLibrary將它所在的DLL卸載的時(shí)候,它后續(xù)要執(zhí)行的代碼已不再進(jìn)程地址空間中了,試圖執(zhí)行不存在的代碼可能會(huì)導(dǎo)致訪問違規(guī),導(dǎo)致進(jìn)程被終止。

       如果線程調(diào)用FreeLibraryAndExitThread,此函數(shù)在Kernel32.dll中,F(xiàn)reeLibraryAndExitThread函數(shù)調(diào)用FreeLibrary將線程函數(shù)所在的DLL卸載后,其所屬DLL Kernel32.dll仍在進(jìn)程地址空間內(nèi),F(xiàn)reeLibraryAndExitThread函數(shù)繼續(xù)執(zhí)行調(diào)用ExitThread,后續(xù)代碼仍然存在,不會(huì)導(dǎo)致訪問違規(guī)。

       每個(gè)DLL在進(jìn)程中都有一個(gè)使用計(jì)數(shù)。LoadLibrary(Ex)會(huì)增加其計(jì)數(shù),FreeLibrary(Ex)FreeLibraryAndExitThread會(huì)遞減其計(jì)數(shù)。例如:當(dāng)程序第一次調(diào)用LoadLibrary來載入一個(gè)DLL時(shí),系統(tǒng)會(huì)將此DLL映射到進(jìn)程地址空間中,并將此DLL的使用計(jì)數(shù)加一。如果線程后來再次調(diào)用LoadLibrary(Ex)時(shí),系統(tǒng)不會(huì)將此DLL再次映射到進(jìn)程地址空間,僅僅遞增此DLL的使用計(jì)數(shù)。為了從進(jìn)程地址空間中撤銷對該DLL的映射,線程必須調(diào)用FreeLibrary(Ex)兩次。第一次是將此DLL的使用計(jì)數(shù)減為1,第二次減為0。當(dāng)系統(tǒng)發(fā)現(xiàn)某DLL的使用計(jì)數(shù)已經(jīng)為0時(shí),會(huì)從進(jìn)程地址空間卸載此DLL。此時(shí)如果線程試圖顯式調(diào)用DLL中的函數(shù)將會(huì)導(dǎo)致訪問違規(guī)。

     系統(tǒng)會(huì)在每個(gè)進(jìn)程中為DLL維護(hù)一個(gè)使用計(jì)數(shù),在本進(jìn)程調(diào)用LoadLibrary僅僅是增加DLL在本進(jìn)程的使用計(jì)數(shù)。如果進(jìn)程A中的一個(gè)線程執(zhí)行了LoadLibrary("Mydll.dll");進(jìn)程B的某一線程也調(diào)用LoadLibrary("Mydll.dll");那么該DLL會(huì)被映射到A,B兩個(gè)進(jìn)程空間中去,且在AB進(jìn)程的使用計(jì)數(shù)都為1

調(diào)用FreeLibrary"Mydll.dll");也僅僅是遞減DLL在本進(jìn)程內(nèi)的使用計(jì)數(shù)。

 

  1. HMODULE  GetModuleHandle(PCTSTR pszModuleName);  


      該函數(shù)可以用來檢測某DLL是否被映射到了進(jìn)程地址空間。如果返回值為NULL,則此DLL未被載入。

     當(dāng)給pszModuleNameNULL時(shí),函數(shù)會(huì)返回應(yīng)用程序可執(zhí)行文件的句柄。

 顯式鏈接導(dǎo)出符號

       顯式載入某個(gè)DLL后,線程可以通過調(diào)用以下函數(shù)來得到它要引用的符號的地址。

     

  1. FARPROC GetProcAddr(HMODULE hInstDll, PCSTR pszSymbolName);  


         hInstDll標(biāo)識導(dǎo)出符號所在的DLL的句柄。它是LoadLibrary(Ex),或是GetModuleHandle所返回的句柄。

     pszSymbolName用于標(biāo)識導(dǎo)出符號。

         pszSymbolName可以有兩種形式:

         第一種:用符號名來指定我們想要得到哪個(gè)符號的地址。

        如:FARPROC pfn=GetProcAddress(hInstDll,"MyProc");

        它是以0結(jié)尾的字符串。要注意此字符串是ANSI類型的。因?yàn)榫幾g器、鏈接器始終都是將符號的名稱以ANSI字符串的形式保存在DLL的導(dǎo)出段。

         第二種:用序號來指定我們想要那個(gè)符號的地址。

         如:FARPROC pfn=GetProcAddress(hInstDll,MAKERESOURCE(2));

         這種方法假定我們知道某個(gè)導(dǎo)出符號在某DLL中的序號為2。應(yīng)該明確的是Microsoft強(qiáng)烈反對使用序號。

使用序號的形式要比使用字符串速度慢,因?yàn)橄到y(tǒng)需要對一字符串標(biāo)識的符號名進(jìn)行字符串比較。使用第二種方法即使該序號并沒有與任何導(dǎo)出函數(shù)相對應(yīng),GetProcAddress也會(huì)返回非NULL值。其實(shí)這個(gè)地址是無效的,訪問此地址可能會(huì)導(dǎo)致訪問違規(guī)。

      注意:使用GetProcAddress返回的函數(shù)指針來調(diào)用函數(shù)之前,需要將它轉(zhuǎn)換成與函數(shù)簽名相匹配的類型。

     例如:

     

  1. typedef void (CALLBACK *PFN_DUM_MOUDLE)(MODULE hModule);  


      它是與void DynamicDumpModule(HMODULE hModule)函數(shù)相對應(yīng)的函數(shù)相同。

      動(dòng)態(tài)調(diào)用某DLL導(dǎo)出函數(shù)的例子:

  1. <span style="font-size:18px;"> PFN_DUMPMODULE pfnDumpModule=(PFN_DUMPMODULE)GetProcAddress(hDll,"DumpModule");  
  2.   
  3. If(pfnDumpModule!=NULL)  
  4.  {  
  5.     pfnDumpModule(hDll);  
  6.  }  
  7.   
  8. pan>  


DLL的入口點(diǎn)函數(shù)

         一個(gè)DLL可以有一個(gè)入口點(diǎn)函數(shù),系統(tǒng)會(huì)在不同的時(shí)候調(diào)用這個(gè)函數(shù)。這些調(diào)用是通知性質(zhì)的,通常被DLL用來執(zhí)行與進(jìn)程或線程有關(guān)的初始化和清理工作。

       如果不需要執(zhí)行這些操作,可以不必再源代碼中不實(shí)現(xiàn)此函數(shù)。

       如果需要DLL接受這些通知,就應(yīng)該按照如下的格式來實(shí)現(xiàn)該函數(shù)。

    

  1. <span style="font-size:18px;">Bool WINAPI DllMain(HINSTANCE hInsDll,DWORD fdwReason,PVOID fImpLoad)  
  2.   
  3. {  
  4.   
  5.      Swith(fdwReason)  
  6.   
  7.     {  
  8.   
  9.         Case DLL_PROCESS_ATTACH:  
  10.   
  11.     
  12.   
  13.              //DLL被映射到進(jìn)程地址空間是,執(zhí)行此處代碼。  
  14.   
  15.                 Break;  
  16.   
  17.          Case DLL_THREAD_ATTACH:  
  18.   
  19.              //線程被創(chuàng)建的時(shí)候執(zhí)行。  
  20.   
  21.                  Break;  
  22.   
  23.          Case DLL_THREAD_DETACH:  
  24.   
  25.                //線程終止運(yùn)行時(shí)執(zhí)行。  
  26.   
  27.                    Break;  
  28.   
  29.          Case DLL_PROCESS_DETACH:  
  30.   
  31.                 //DLL被卸載的時(shí)候執(zhí)行。  
  32.   
  33.                     Break;  
  34.   
  35.        }  
  36. }  
  37.   
  38. </span>  


          hInstDll是該DLL實(shí)例的句柄。它是DLL文件被映射到進(jìn)程地址空間的虛擬地址。通常將這個(gè)參數(shù)保存在全局變量中。這樣在DLL的其他導(dǎo)出函數(shù)中就可以使用。

        如果DLL是被隱式載入的,fImpLoad為非零值,顯式的話fImportLoad0。

        fdwReason表示系統(tǒng)調(diào)用入口點(diǎn)函數(shù)的原因。它是switch語句的參數(shù)??梢允巧鲜鏊膫€(gè)值。分別表示四種情況。后續(xù)將會(huì)詳細(xì)介紹每一種情況。

          注意:DLL使用DllMain對自己進(jìn)行初始化。DllMain執(zhí)行的時(shí)候,其他DLL的可能還未被初始化。這意味著我們應(yīng)該避免在DllMain中調(diào)用從其他DLL中導(dǎo)出的函數(shù)。

DLL_PROCESS_ATTACH通知

         當(dāng)系統(tǒng)第一次將一個(gè)DLL映射到進(jìn)程地址空間是,會(huì)調(diào)用DllMain函數(shù),并給fdwReason傳入DLL_PROCESS_ATTACH。注意:只有在該DLL是第一次被調(diào)用到進(jìn)程地址空間中時(shí),才會(huì)調(diào)用DllMain。如果以后再次調(diào)用LoadLibrary(Ex)時(shí),OS僅僅是遞增該DLL在此進(jìn)程的使用計(jì)數(shù),并不會(huì)再次調(diào)用DllMain。

         當(dāng)DLL在處理DLL_PROCESS_ATTACH時(shí),應(yīng)該根據(jù)需要執(zhí)行與進(jìn)程相關(guān)的初始化。如DLL中包含一些函數(shù),需要使用自己的堆,可以在進(jìn)程加載時(shí)執(zhí)行一些堆的初始化工作。

處理DLL_PROCESS_ATTACH時(shí),DllMain的返回值表示DLL的初始化是否成功。如初始化成功,應(yīng)返回TRUE,否則應(yīng)返回false

       下面來看看DllMain調(diào)用的時(shí)機(jī):

        創(chuàng)建新進(jìn)程時(shí),系統(tǒng)為該進(jìn)程分配地址空間,并將exe可執(zhí)行文件和所需要的DLL映射到進(jìn)程地址空間。然后創(chuàng)建主線程,并用主線程來調(diào)用每個(gè)DLLDllMain函數(shù),同時(shí)傳入DLL_PROCESS_ATTACH。當(dāng)所有已映射的DLL完成對該通知的處理后,系統(tǒng)會(huì)讓主進(jìn)程執(zhí)行可執(zhí)行模塊的C/C++運(yùn)行庫的啟動(dòng)代碼。然后執(zhí)行可執(zhí)行模塊的入口點(diǎn)函數(shù)(_tmain_tWinMain)。如果任意一個(gè)DLLDllMain返回false,就說明初始化失敗,系統(tǒng)會(huì)將所有文件映像從地址空間中清除,向用戶顯示錯(cuò)誤信息。

顯式載入DLL的過程:

         進(jìn)程調(diào)用LoadLibrary(Ex),該函數(shù)對DLL進(jìn)行定位,并將該DLL映射到進(jìn)程地址空間。然后會(huì)讓調(diào)用LoadLibrary(Ex)的線程調(diào)用DllMain函數(shù),并傳入DLL_PROCESS_ATTACH。當(dāng)DLLDllMain函數(shù)完成了對通知的處理后,系統(tǒng)會(huì)讓LoadLibrary返回。這樣線程就可以繼續(xù)執(zhí)行。

         注意:DllMain是在進(jìn)程調(diào)用LoadLibraryEx)的時(shí)候調(diào)用的。它返回到LoadLibrary(Ex)函數(shù)內(nèi)。

DLL_PROCESS_ATTACH通知

       當(dāng)一個(gè)DLL從進(jìn)程的地址空間中撤銷的時(shí)候,會(huì)調(diào)用該DLL的DllMain函數(shù),并在fdwReason傳入DLL_PROCESS_DETACH。該case語句內(nèi)一般是用來執(zhí)行與進(jìn)程相關(guān)的清理工作。如調(diào)用HeapDestroy清理堆。

         注意:當(dāng)DLL剛被映射到進(jìn)程地址空間,執(zhí)行DllMain并傳入DLL_PROCESS_ATTACH時(shí)的返回值為false時(shí),所有DLL將會(huì)被撤銷映射,此時(shí)并不會(huì)調(diào)用DllMain并傳入DLL_PROCESS_DETACH。

       下面談?wù)務(wù){(diào)用DllMain并傳入DLL_PROCESS_DETACH的時(shí)機(jī):

        1:當(dāng)進(jìn)程又由于某線程調(diào)用ExitProcess而終止時(shí),映射到該進(jìn)程的所有DLL都會(huì)被撤銷。調(diào)用 ExitProcess的線程將負(fù)責(zé)執(zhí)行DllMain。一般情況下,此線程就是主線程。

        2:如果DLL被撤銷的原因是因?yàn)檫M(jìn)程中的線程調(diào)用了FreeLibrary或是FreeLibraryAndExitThread,那么執(zhí)行上述函數(shù)的線程將負(fù)責(zé)對DllMain的調(diào)用。調(diào)用完成后線程返回,繼續(xù)執(zhí)行其他代碼。

        注意:如果進(jìn)程終止是因?yàn)槟硞€(gè)線程調(diào)用TerminateProcess,此時(shí)DllMain并不會(huì)被調(diào)用。這意味著在進(jìn)程終止前,已經(jīng)映射到進(jìn)程的任何DLL將沒有任何機(jī)會(huì)執(zhí)行清理工作,這可能導(dǎo)致數(shù)據(jù)丟失或是已被該進(jìn)程占用的信號量不能得到釋放。因此不到萬不得已,應(yīng)該避免使用TerminageProcess。

DLL_THREAD_DEATTACH通知

        當(dāng)進(jìn)程創(chuàng)建一線程的時(shí)候,系統(tǒng)會(huì)檢查已映射到此進(jìn)程的所有DLL,并用DLL_THREAD_ATTACH調(diào)用每個(gè)DLL的DllMain。一般在此時(shí)執(zhí)行與線程有關(guān)的初始化。DllMain的代碼是由新創(chuàng)建的線程執(zhí)行。當(dāng)該線程完成了所有DllMain之后,才會(huì)執(zhí)行它的線程函數(shù)。

        注意:僅僅是讓新建的線程執(zhí)行已經(jīng)被映射到進(jìn)程地址空間的DLL的DllMain函數(shù)。而不會(huì)讓已經(jīng)存在的線程調(diào)用DllMain。當(dāng)系統(tǒng)的主線程被創(chuàng)建的時(shí)候,并不會(huì)調(diào)用DllMain并傳入DLL_PROCESS_ATTACH。它已經(jīng)在進(jìn)程被創(chuàng)建的時(shí)候調(diào)用DllMain并傳入DLL_PROCESS_ATTACH。

DLL_THREAD_DETACH通知

         當(dāng)線程調(diào)用ExitThread將要終止的時(shí)候,系統(tǒng)會(huì)讓該線程用DLL_THREAD_DETACH調(diào)用所有已映射到進(jìn)程地址空間的所有DLL的DllMain函數(shù)。這一般被用來執(zhí)行與線程相關(guān)的清理工作。

         注意:如果線程終止是因?yàn)槠渌€程調(diào)用TerminateThread而終止的話,系統(tǒng)不會(huì)用DLL_THREAD_DETACH讓線程調(diào)用各DLL的DllMain。因此與TerminateProcess一樣,除非萬不得以,應(yīng)避免使用TerminateThread函數(shù)。

       下面來總結(jié)下調(diào)用DllMain的過程:

        進(jìn)程中的一個(gè)線程調(diào)用LoadLibrary來映射一個(gè)DLL,系統(tǒng)使該線程用DLL_PROCESS_ATTCH調(diào)用該DLL的DllMain函數(shù)(該線程不會(huì)得到DLL_THREAD_ATTACH)通知。當(dāng)此線程退出時(shí),系統(tǒng)讓此線程再次調(diào)用所有DLL的DllMain函數(shù),但此次傳入的是DLL_THREAD_DETACH。雖然在該DLL映射的時(shí)候,不會(huì)向該DLL發(fā)送DLL_THREAD_ATTACH通知。但是當(dāng)該線程退出時(shí),會(huì)向DLL發(fā)送DLL_THREAD_DETACH通知。

之所以不發(fā)送DLL_PROCESS_DETACH通知,是因?yàn)镈LL仍在進(jìn)程中。只有當(dāng)DLL被卸載時(shí),才會(huì)發(fā)送此通知。

        前面我們提到過DllMain函數(shù)并不是必須的。在鏈接DLL的時(shí)候,如果鏈接器無法在obj文件中發(fā)現(xiàn)DllMain函數(shù),它會(huì)鏈接C/C++運(yùn)行庫的DllMain函數(shù)。如果我們不提供DllMain函數(shù),C/C++運(yùn)行庫會(huì)認(rèn)為我們不關(guān)系DLL的各種通知。它會(huì)調(diào)用DisableThreadLibraryCalls函數(shù)。

  1. <span style="font-size:18px;">     BOOL DisableThreadLibraryCalls(HMODULE hInstDll);  
  2.   
  3. </span>  


          該函數(shù)告訴系統(tǒng)  我們不想讓系統(tǒng)向某個(gè)指定的DLL發(fā)送DLL_THREAD_ATTACH和DLL_THREAD_DETACH通知。

         C/C++運(yùn)行庫中實(shí)現(xiàn)的DllMain函數(shù)如下所示:

  1. <span style="font-size:18px;">    BOOL WINAPI DllMain(HINSTANCE hInstDll,DWORD fdwReason,PVOID fImpLoad)  
  2.   
  3.     {  
  4.   
  5.         if(fdwReason==DLL_PROCESS_ATTACH)  
  6.   
  7.            DisableThreadLibraryCalls(hInstDll);  
  8.   
  9.         return true;  
  10.   
  11.     }  
  12.   
  13. </span>  

延遲載入DLL。

         所謂延遲載入DLL,就是在進(jìn)程運(yùn)行后加載程序加載各種DLL時(shí),并不載入已經(jīng)被設(shè)為延遲加載的DLL。直到該DLL中的某個(gè)導(dǎo)出函數(shù)被調(diào)用的時(shí)候,此DLL才會(huì)被加載到進(jìn)程的地址空間中。該DLL是隱式鏈接的 。

        這項(xiàng)特性非常有用,主要應(yīng)用與以下各種情況下:

        1:某進(jìn)程使用了很多DLL,由于初始化時(shí)加載程序必須將所有DLL都映射到進(jìn)程地址空間中,這會(huì)導(dǎo)致加載速度比較慢。如果使用延遲加載,某些DLL直到其導(dǎo)出符號被引用到的時(shí)候,該DLL才會(huì)被隱式加載到進(jìn)程地址空間,這縮短了初始化時(shí)間。

        2:當(dāng)應(yīng)用程序在代碼上使用了一個(gè)新的函數(shù),運(yùn)行在不提供此函數(shù)的老版本的系統(tǒng)上時(shí),如果該函數(shù)所在的DLL不使用延遲加載機(jī)制,加載程序會(huì)報(bào)告一個(gè)錯(cuò)誤:無法找到該函數(shù)。接著便會(huì)終止該應(yīng)用程序的執(zhí)行。如果我們使用延遲加載技術(shù),當(dāng)程序檢測到此時(shí)是運(yùn)行在老的系統(tǒng)中,程序就不會(huì)調(diào)用此函數(shù),轉(zhuǎn)而使用可以在老的系統(tǒng)上使用的其它函數(shù)。程序仍然可以繼續(xù)運(yùn)行。由于不會(huì)在程序中引用在老系統(tǒng)中不支持的函數(shù),該函數(shù)所在的DLL就不會(huì)被加載。

        當(dāng)然任何方法都有適用范圍,延遲加載不適用于以下幾種情況:

       1:導(dǎo)出全局變量的DLL是無法延遲加載的。

       2:Kernel32.dll是無法延遲加載的,LoadLibrary和GetProcAddress都在該模塊中。必須加載該模塊才可以調(diào)用它們。

        3:不應(yīng)該在DllMain中代用延遲加載函數(shù),這樣會(huì)導(dǎo)致程序崩潰。

         要讓延遲加載能夠正常工作,首先要指定兩個(gè)鏈接器開關(guān)。

        /Lib:DelayImp.dl

        /DelayLoad:要延遲加載的DLL名字。

        它們不可以在代碼中通過#pragma comment(linker,"")來設(shè)定。而要通過Configuration Properities屬性頁來設(shè)定。

        /Lib:DelayImp.dll是通過Linker/Advanced/DelayLoadDLL開關(guān)來指定。它告訴鏈接器將函數(shù)_delay_LoadHelper2嵌入到我們的可執(zhí)行文件中。

         /DelayLoad開關(guān)可以通過Linker /input/DelayLoadDLLs開關(guān)來指定。要延遲載入的函數(shù)所在的DLL在該項(xiàng)的右側(cè)指定??梢灾付ǘ鄠€(gè)延遲載入DLL。

      該開關(guān)告訴鏈接器::

      1:將用戶要延遲載入的DLL從可執(zhí)行文件的導(dǎo)入段中去除,這樣當(dāng)進(jìn)程初始化時(shí)該DLL就不會(huì)被隱式的載入。

      2:在可執(zhí)行文件中嵌入一個(gè)延遲載入段,來表示要從用戶要延遲載入的DLL導(dǎo)入哪些函數(shù)。

      3:當(dāng)程序調(diào)用延遲載入DLL中的函數(shù)時(shí),對該函數(shù)的調(diào)用會(huì)轉(zhuǎn)到_delayLoadHelper2函數(shù),來完成對延遲載入函數(shù)的解析。也就是說對延遲載入段中的函數(shù)的調(diào)用,實(shí)際上會(huì)調(diào)用_delayLoadHelper2函數(shù)。此函數(shù)會(huì)引用延遲載入段,然后調(diào)用LoadLibrary和GetProcAddress得到延遲載入函數(shù)的地址。一旦得到延遲載入函數(shù)的地址_delayLoadHelper2就會(huì)修復(fù)對該函數(shù)的調(diào)用(Windows核心編程的原話,至于如何修復(fù)不清楚。2011年12月8日注)。今后的調(diào)用將直接調(diào)用該延遲載入函數(shù)。注意:同一個(gè)DLL的其它函數(shù)仍然必須在第一次被調(diào)用的時(shí)候修復(fù)。對同一DLL中某一延遲函數(shù)的調(diào)用并不會(huì)對其他延遲函數(shù)的調(diào)用進(jìn)行修復(fù)

關(guān)于延遲載入函數(shù)暫時(shí)介紹這么多。感興趣的話可以參考其他文獻(xiàn)。

 

      《參考自windows核心編程》第五版第四部分。以上僅僅是個(gè)人總結(jié),如有紕漏請不吝賜教!

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
Inside DllMain
Windows核心編程(第五版)筆記 第二十章 DLL高級技巧 (DLL Advanced...
DLL高級技術(shù)2
關(guān)于dll的一些事
DllMain詳解
dll概述
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服