動態連結程式庫搜尋順序

相同動態連結程式庫的多個版本通常會 (DLL) 存在於作業系統 (作業系統) 內的不同檔案系統位置。 您可以藉由指定完整路徑來控制載入任何指定 DLL 的特定位置。 但是,如果您不使用該方法,則系統會在載入時搜尋 DLL,如本主題所述。 DLL 載入器是作業系統 (作業系統) 的一部分,可載入 DLL 和/或解析 DLL 的參考。

提示

如需 已封裝未封裝 應用程式的定義,請參閱 封裝應用程式的優點和缺點

影響搜尋的因素

以下是本主題中討論的一些特殊搜尋因素,您可以將它們視為 DLL 搜尋順序的一部分。 本主題稍後的章節會以特定應用程式類型的適當搜尋順序列出這些因素,以及其他搜尋位置。 本節只是為了介紹概念,並為其命名,我們將在本主題稍後用來參考這些概念。

  • DLL 重新導向。 如需詳細資訊,請參閱 動態連結程式庫重新導向
  • API 集合。 如需詳細資訊,請參閱 Windows API 集合
  • 並存 (SxS) 資訊清單重新導向—傳統型應用程式只會 (非 UWP 應用程式) 。 您可以使用應用程式資訊清單 (也稱為並存應用程式資訊清單或融合資訊清單) 來重新導向。 如需詳細資訊,請參閱 資訊清單
  • Loaded-module list。 系統可以檢查是否有具有相同模組名稱的 DLL 已載入記憶體 (不論從哪個資料夾載入) 。
  • 已知的 DLL。 如果 DLL 位於應用程式執行所在 Windows 版本的已知 DLL 清單中,則系統會使用其已知 DLL 複本 (和已知 DLL 的相依 DLL,如果有任何) 。 如需目前系統上已知 DLL 的清單,請參閱登錄機碼 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs

如果 DLL 具有相依性,則系統會搜尋相依 DLL,就像只使用模組名稱載入一樣。 即使第一個 DLL 是藉由指定完整路徑來載入,也是如此。

已封裝應用程式的搜尋順序

當已封裝的應用程式特別載入已封裝的模組 (時,程式庫模組— .dll 透過呼叫 LoadPackagedLibrary 函式) 檔案,DLL 必須位於進程的套件相依性圖形中。 如需詳細資訊,請參閱 LoadPackagedLibrary。 當已封裝的應用程式以其他方式載入模組,且未指定完整路徑時,系統會在載入時搜尋 DLL 及其相依性,如本節所述。

當系統搜尋模組或其相依性時,它一律會使用已封裝應用程式的搜尋順序;即使相依性未封裝應用程式程式碼也一樣。

已封裝應用程式的標準搜尋順序

系統會依下列順序搜尋:

  1. DLL 重新導向。
  2. API 集合。
  3. 傳統型應用程式 (非 UWP 應用程式) 。 SxS 資訊清單重新導向。
  4. Loaded-module list。
  5. 已知的 DLL。
  6. 進程的套件相依性圖形。 這是應用程式的套件加上應用程式套件資訊清單區段中指定 <PackageDependency><Dependencies> 的任何相依性。 相依性會依出現在資訊清單中的順序進行搜尋。
  7. 呼叫進程從 (可執行檔的資料夾) 載入。
  8. 系統資料夾 (%SystemRoot%\system32) 。

如果 DLL 具有相依性,則系統會搜尋相依 DLL,就像只使用模組名稱載入一樣, (即使第一個 DLL 是透過指定完整路徑) 來載入。

已封裝應用程式的替代搜尋順序

如果模組使用LOAD_WITH_ALTERED_SEARCH_PATH呼叫LoadLibraryEx函式來變更標準搜尋順序,則搜尋順序與標準搜尋順序相同,不同之處在于,在步驟 7 中,系統會在 (載入頂端模組的資料夾) 而不是可執行檔的資料夾載入指定的模組資料夾。

未封裝應用程式的搜尋順序

當未封裝的應用程式載入模組且未指定完整路徑時,系統會在載入時搜尋 DLL,如本節所述。

重要

如果攻擊者取得其中一個搜尋的目錄控制權,則它可以在該資料夾中放置 DLL 的惡意複本。 如需協助防止這類攻擊的方式,請參閱 動態連結程式庫安全性

未封裝應用程式的標準搜尋順序

系統所使用的標準 DLL 搜尋順序取決於是否啟用 安全的 DLL 搜尋模式

預設會啟用的安全 DLL 搜尋模式 (,) 在搜尋順序中稍後移動使用者的目前資料夾。 若要停用安全的 DLL 搜尋模式,請建立登錄 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\SafeDllSearchMode 值,並將其設定為 0。 當指定的資料夾位於搜尋路徑) 時,呼叫 SetDllDirectory 函式會有效地停用安全 DLL 搜尋模式 (,並變更本主題中所述的搜尋順序。

如果已啟用安全的 DLL 搜尋模式,則搜尋順序如下:

  1. DLL 重新導向。
  2. API sets.
  3. SxS manifest redirection.
  4. Loaded-module list.
  5. Known DLLs.
  6. Windows 11版本 21H2 (10.0;組建 22000) 及更新版本。 The package dependency graph of the process. This is the application's package plus any dependencies specified as <PackageDependency> in the <Dependencies> section of the application's package manifest. Dependencies are searched in the order they appear in the manifest.
  7. 應用程式從中載入的資料夾。
  8. 系統資料夾。 使用 GetSystemDirectory 函 式來擷取此資料夾的路徑。
  9. 16 位系統資料夾。 沒有可取得此資料夾路徑的函式,但會加以搜尋。
  10. Windows 資料夾。 使用 GetWindowsDirectory 函 式來取得此資料夾的路徑。
  11. 目前的資料夾。
  12. 環境變數中所列的 PATH 目錄。 這不包括 應用程式路徑 登錄機碼所指定的個別應用程式路徑。 計算 DLL 搜尋路徑時,不會使用 應用程式路徑 索引鍵。

如果 停用安全 DLL 搜尋模式,則搜尋順序會相同,不同之處在于 目前的資料夾 會從位置 11 移至順序中的位置 8, (步驟 7 之後立即 移動。應用程式載入) 的資料夾

未封裝應用程式的替代搜尋順序

若要變更系統所使用的標準搜尋順序,您可以使用LOAD_WITH_ALTERED_SEARCH_PATH呼叫LoadLibraryEx 函式。 您也可以呼叫 SetDllDirectory 函式來變更標準搜尋順序。

注意

在目前進程的開始之前,在父進程中呼叫 SetDllDirectory 函式,也會影響進程的標準搜尋順序。

如果您指定替代搜尋策略,則會繼續其行為,直到找到所有相關聯的可執行模組為止。 系統開始處理 DLL 初始化常式之後,系統會還原為標準搜尋策略。

如果呼叫指定LOAD_WITH_ALTERED_SEARCH_PATH,且lpFileName參數指定絕對路徑,LoadLibraryEx函式支援替代搜尋順序。

  • 標準搜尋策略會在呼叫應用程式的 資料夾中) 初始步驟之後開始 (。
  • LoadLibraryEx所指定的替代搜尋策略,LOAD_WITH_ALTERED_SEARCH_PATH會在LoadLibraryEx載入之可執行模組資料夾中的初始步驟) 開始 (。

這是它們唯一不同的方式。

如果已啟用安全的 DLL 搜尋模式,則替代搜尋順序如下所示:

步驟 1-6 與標準搜尋順序相同。

  1. lpFileName所指定的資料夾。
  2. The system folder. Use the GetSystemDirectory function to retrieve the path of this folder.
  3. The 16-bit system folder. There's no function that obtains the path of this folder, but it is searched.
  4. The Windows folder. 使用 GetWindowsDirectory 函式 來取得此資料夾的路徑。
  5. 目前的資料夾。
  6. 環境變數中所列的 PATH 目錄。 這不包括 應用程式路徑 登錄機碼所指定的個別應用程式路徑。 計算 DLL 搜尋路徑時,不會使用 應用程式路徑 索引鍵。

如果 停用安全 DLL 搜尋模式,則替代搜尋順序相同,不同之處在于 目前的資料夾 會從順序 11 移至順序中的位置 8, (步驟 7 之後立即 移動。lpFileName 所指定的資料夾) 。

如果lpPathName參數指定路徑,SetDllDirectory函式支援替代搜尋順序。 替代搜尋順序如下所示:

步驟 1-6 與標準搜尋順序相同。

  1. 應用程式從中載入的資料夾。
  2. SetDllDirectorylpPathName參數所指定的資料夾。
  3. 系統資料夾。
  4. 16 位系統資料夾。
  5. Windows 資料夾。
  6. 環境變數中列出的 PATH 目錄。

如果 lpPathName 參數是空字串,則呼叫會從搜尋順序中移除目前的資料夾。

當指定的資料夾位於搜尋路徑時,SetDllDirectory實際上會停用安全的 DLL 搜尋模式。 若要根據SafeDllSearchMode登錄值還原安全 DLL 搜尋模式,並將目前的資料夾還原至搜尋順序,請使用lpPathName呼叫SetDllDirectory作為 Null。

使用LOAD_LIBRARY_SEARCH旗標的搜尋順序

您可以搭配LoadLibraryEx函式使用一或多個LOAD_LIBRARY_SEARCH旗標來指定搜尋順序。 您也可以搭配SetDefaultDllDirectories函式使用LOAD_LIBRARY_SEARCH旗標來建立程式的 DLL 搜尋順序。 您可以使用 AddDllDirectorySetDllDirectory 函式來指定進程 DLL 搜尋順序的其他目錄。

搜尋的目錄取決於 使用 SetDefaultDllDirectoriesLoadLibraryEx指定的旗標。 如果您使用多個旗標,則會依下列順序搜尋對應的目錄:

  1. LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR。 搜尋包含 DLL 的資料夾。 此資料夾只會搜尋要載入之 DLL 的相依性。
  2. LOAD_LIBRARY_SEARCH_APPLICATION_DIR。 搜尋應用程式資料夾。
  3. LOAD_LIBRARY_SEARCH_USER_DIRS。 系統會搜尋 使用 AddDllDirectory 函式或 SetDllDirectory 函數明確新增的路徑。 如果您新增多個路徑,則未指定搜尋路徑的順序。
  4. LOAD_LIBRARY_SEARCH_SYSTEM32。 系統會搜尋 [系統] 資料夾。

如果您呼叫 LoadLibraryEx 且沒有 LOAD_LIBRARY_SEARCH 旗標,或為程式建立 DLL 搜尋順序,則系統會使用標準搜尋順序或替代搜尋順序來搜尋 DLL。