1. 程式人生 > >動態載入DLL所需要的三個函數詳解(LoadLibrary,GetProcAddress,FreeLibrary)

動態載入DLL所需要的三個函數詳解(LoadLibrary,GetProcAddress,FreeLibrary)

包含 設計 應用程序 執行文件 lib 通過 不同的 將不 width

動態載入 DLL

動態載入方式是指在編譯之前並不知道將會調用哪些 DLL 函數, 完全是在運行過程中根據需要決定應調用哪些函數。

方法是:用 LoadLibrary 函數加載動態鏈接庫到內存,用 GetProcAddress函數動態獲得 DLL 函數的入口地址。當一個 DLL 文件用 LoadLibrary 顯式加載後,在任何時刻均可以通過調用 FreeLibrary 函數顯式地從內存中把它給卸載。

動態調用使用的 Windows API 函數主要有 3 個, 分別是 LoadLibrary、 GetProcAddress 和FreeLibrary。

我們分別詳細介紹這三個函數的功能,因為無論學習編程還是逆向這是三個函數都是非常常用滴。


(1)LoadLibrary 函數

註:Delphi 中還提供了 SafeLoadLibrary 函數,它封裝了 Loadlibrary 函數,可以裝載由 Filename 參數指定的 WindowsDLL或 Linux 共享對象。它簡化了DLL的裝載並且使裝載更加安全。

[格式]:

  1. function LoadLibrary(LibFileName : PChar): Thandle;
復制代碼


[功能]:加載由參數 LibFileName 指定的 DLL 文件。

[說明]:參數 LibFileName 指定了要裝載的 DLL 文件名,如果 LibFileName 沒有包含一個路徑,系統將按照:當前目錄、Windows 目錄、Windows 系統目錄、包含當前任務可執行文件的目錄、列在 PATH 環境變量中的目錄等順序查找文件。

如果函數操作成功,將返回裝載 DLL 庫模塊的實例句柄,否則,將返回一個錯誤代碼,錯誤代碼的定義如下表所示。


錯誤代碼 含義
0 系統內存不夠,可執行文件被破壞或調用非法
2 文件沒有被發現
3 路徑沒有被發現
5 企圖動態鏈接一個任務錯誤或者有一個共享或網絡保護錯誤
6 庫需要為每個任務建立分離的數據段
8 沒有足夠的內存啟動應用程序
10 Windows 版本不正確
11 可執行文件非法或不是Windows 應用程序,或在. EXE映像中有錯誤
12 應用程序為一個不同的操作系統設計(如 OS/2)
13 應用程序為 MS DOS 4. 0 設計
14 可執行文件的類型不知道
15 試圖裝載一個實模式應用程序(為早期Windows 版本設計)
16 試圖裝載包含可寫的多個數據段的可執行文件的第二個實例
19 試圖裝載一個壓縮的可執行文件(文件必須被解壓後才能被裝載)
20 DLL 文件非法
21 應用程序需要 32 位擴展


假如在應用程序中用 LoadLibrary 函數裝入某一個 DLL 前, 其他應用程序已把該 DLL 裝入內存中了,則系統將不再裝入該 DLL 的另一個實例,而是使該 DLL 的“引用計數”加 1 。


(2)GetProcAddress 函數

[格式]:

  1. function GetProcAddress(Module:Thandle; ProcName:PChar): TfarProc;
復制代碼


[功能]:返回參數 Module 指定的模塊中,由參數 ProcName 指定的過程或函數的入口地址。

[說明]:參數 Module 包含被調用函數的 DLL 句柄,這個值由 LoadLibrary 返回, ProcName
是指向含有函數名的以 nil 結尾的字符串指針,或者可以是函數的次序值,但大多數情況下,用函數名是一種更穩妥的選擇。如果該函數執行成功,則返回 DLL 中由參數 ProcName 指定的過程或函數的入口地址,否則返回 nil 。


(3)FreeLibrary 函數

[格式]:

  1. procedure FreeLibrary(Module: Thandle);
復制代碼


[說明]:將由參數 Module 指定的 DLL 文件從內存中卸載 1 次。

[說明]:Module 為 DLL 庫的句柄。這個值由 LoadLibrary 返回。由於 DLL 在內存中只裝載一次,因此調用 FreeLibrary 首先使 DLL 的引用計數減 1,如果計數減為 0 則卸載該 DLL。

[註意]:每調用一次 LoadLibrary 函數就應調用一次 FreeLibrary 函數,以保證不會有多余的庫模塊在應用程序結束後仍留在內存中,否則導致內存泄漏。

動態載入DLL所需要的三個函數詳解(LoadLibrary,GetProcAddress,FreeLibrary)