ダイナミック リンク ライブラリの検索順序

同じダイナミック リンク ライブラリ (DLL) の複数のバージョンが、オペレーティング システム (OS) 内の異なるファイル システムの場所に存在するのが一般的です。 完全パスを指定することで、特定の DLL の読み込み元となる特定の場所を制御 できます 。 ただし、そのメソッドを使用しない場合は、このトピックで説明するように、読み込み時に DLL が検索されます。 DLL ローダーは、DLL を読み込んだり、DLL への参照を解決したりするオペレーティング システム (OS) の一部です。

ヒント

パッケージ化されたアプリとパッケージ化されていないアプリの定義については、「アプリのパッケージ化の長所と短所」を参照してください。

検索に影響を与える要因

このトピックで説明する特別な検索要素をいくつか次に示します。これらは DLL 検索順序の一部であると見なすことができます。 このトピックの以降のセクションでは、特定のアプリの種類に対する適切な検索順序で、これらの要素を他の検索場所と共に一覧表示します。 このセクションでは、概念を紹介し、トピックの後半で参照するために使用する名前を付けるだけです。

  • DLL リダイレクト。 詳細については、「 ダイナミック リンク ライブラリのリダイレクト」を参照してください。
  • API セット。 詳細については、「 Windows API セット」を参照してください。
  • Side-by-side (SxS) マニフェスト リダイレクト - デスクトップ アプリのみ (UWP アプリではありません)。 アプリケーション マニフェスト (サイド バイ サイド アプリケーション マニフェストまたは Fusion マニフェストとも呼ばれます) を使用してリダイレクトできます。 詳細については、「 マニフェスト」を参照してください。
  • Loaded-module リスト。 システムは、同じモジュール名の DLL が既にメモリに読み込まれているかどうかを確認できます (どのフォルダーから読み込まれたかに関係なく)。
  • 既知の DLL。 アプリケーションが実行されている Windows のバージョンの既知の DLL の一覧に DLL がある場合、システムは既知の DLL (および既知の DLL の依存 DLL がある場合) のコピーを使用します。 現在のシステム上の既知の DLL の一覧については、レジストリ キー HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLsを参照してください。

DLL に依存関係がある場合、システムはモジュール名のみを使用して読み込まれたかのように依存 DLL を検索します。 これは、完全なパスを指定して最初の DLL が読み込まれた場合でも当てはまります。

パッケージ アプリの検索順序

パッケージ 化されたアプリが LoadPackagedLibrary 関数を呼び出してパッケージ化されたモジュール (具体的にはライブラリ モジュール - .dll ファイル) を読み込む場合、DLL はプロセスのパッケージ依存関係グラフに含まれている必要があります。 詳細については、「 LoadPackagedLibrary」を参照してください。 パッケージ アプリが他の方法でモジュールを読み込み、完全なパスを指定しない場合、システムは、このセクションで説明するように、読み込み時に DLL とその依存関係を検索します。

システムは、モジュールまたはその依存関係を検索するときに、パッケージ化されたアプリの検索順序を常に使用します。依存関係がパッケージ化されたアプリ コードでない場合でも。

パッケージ アプリの標準検索順序

システムは次の順序で検索します。

  1. DLL リダイレクト。
  2. API セット。
  3. デスクトップ アプリのみ (UWP アプリではありません)。 SxS マニフェスト リダイレクト。
  4. Loaded-module リスト。
  5. 既知の DLL。
  6. プロセスのパッケージ依存関係グラフ。 これは、アプリケーションのパッケージと、アプリケーションのパッケージ マニフェストのセクションで<Dependencies>指定されている<PackageDependency>依存関係です。 依存関係は、マニフェストに表示される順序で検索されます。
  7. 呼び出し元のプロセスが読み込まれたフォルダー (実行可能ファイルのフォルダー)。
  8. システム フォルダー (%SystemRoot%\system32)。

DLL に依存関係がある場合、システムは依存 DLL を、モジュール名だけで読み込まれたかのように検索します (完全パスを指定して最初の DLL が読み込まれた場合でも)。

パッケージ アプリの代替検索順序

モジュールが LOAD_WITH_ALTERED_SEARCH_PATH を使用して LoadLibraryEx 関数を呼び出して標準の検索順序を変更した場合、検索順序は標準の検索順序と同じですが、手順 7 では、指定したモジュールが読み込まれたフォルダー (最上位の読み込みモジュールのフォルダー) が実行可能ファイルのフォルダーではなく検索されます。

パッケージ化されていないアプリの検索順序

パッケージ化されていないアプリがモジュールを読み込み、完全なパスを指定しない場合、システムは、このセクションで説明するように、読み込み時に DLL を検索します。

重要

攻撃者が検索されたディレクトリの 1 つを制御すると、そのフォルダーに 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 初期化ルーチンの処理を開始すると、システムは標準の検索戦略に戻ります。

LoadLibraryEx 関数は、呼び出しでLOAD_WITH_ALTERED_SEARCH_PATHを指定し、lpFileName パラメーターで絶対パスを指定する場合に、代替検索順序をサポートします。

  • 標準の検索戦略は、呼び出し元のアプリケーションのフォルダーで (最初の手順の後に) 開始されます。
  • LOAD_WITH_ALTERED_SEARCH_PATHを使用してLoadLibraryEx によって指定された代替検索戦略は、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 一覧表示されているディレクトリ。 これには、 App Paths レジストリ キーで指定されたアプリケーションごとのパスは含まれません。 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 を NULL として使用して SetDllDirectory を呼び出します。

LOAD_LIBRARY_SEARCH フラグを使用した検索順序

LoadLibraryEx 関数で 1 つ以上のLOAD_LIBRARY_SEARCH フラグを使用して、検索順序を指定できます。 SetDefaultDllDirectories 関数で LOAD_LIBRARY_SEARCH フラグを使用して、プロセスの DLL 検索順序を確立することもできます。 プロセス DLL の検索順序に追加のディレクトリを指定するには、 AddDllDirectory 関数または SetDllDirectory 関数を使用します。

検索されるディレクトリは、 SetDefaultDllDirectories または LoadLibraryEx で指定されたフラグによって異なります。 複数のフラグを使用する場合、対応するディレクトリは次の順序で検索されます。

  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。 [システム] フォルダーが検索されます。

LOAD_LIBRARY_SEARCH フラグなしで LoadLibraryEx を呼び出すか、プロセスの DLL 検索順序を確立すると、システムは標準の検索順序または代替検索順序を使用して DLL を検索します。