次の方法で共有


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

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

先端

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

検索に影響する要因

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

  • DLL リダイレクト。 詳細については、「ダイナミック リンク ライブラリのリダイレクト 」を参照してください。
  • API セット。 詳細については、Windows API セット を参照してください。
  • サイド バイ サイド (SxS) マニフェスト リダイレクト-デスクトップ アプリのみ (UWP アプリではありません)。 アプリケーション マニフェスト (サイド バイ サイド アプリケーション マニフェストまたは Fusion マニフェストとも呼ばれます) を使用してリダイレクトできます。 詳細については、「マニフェスト を参照してください。
  • Loaded-module list します。 システムは、同じモジュール名の DLL が既にメモリに読み込まれているかどうかを確認できます (読み込まれたフォルダーに関係なく)。
  • 既知の DLL します。 DLL が、アプリケーションが実行されている Windows のバージョンの既知の 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 list。
  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 セット。
  3. SxS マニフェスト のリダイレクト。
  4. Loaded-module list。
  5. 既知の DLL。
  6. Windows 11 バージョン 21H2 (10.0;ビルド 22000) 以降の。 プロセスのパッケージ依存関係グラフ。 これは、アプリケーションのパッケージに加えて、アプリケーションのパッケージ マニフェストの <Dependencies> セクションで <PackageDependency> として指定されたすべての依存関係です。 依存関係は、マニフェストに表示される順序で検索されます。
  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_PATHLoadLibraryEx で指定された代替検索方法は、LoadLibraryEx が読み込まれている実行可能モジュールのフォルダーで (最初の手順の後に) 開始

それが違う唯一の方法です。

安全な DLL 検索モードが有効になっている場合、代替検索順序は次のようになります。

手順 1 から 6 は、標準の検索順序と同じです。

  1. lpFileName で指定フォルダー。
  2. システム フォルダー。 GetSystemDirectory 関数を使用して、このフォルダーのパスを取得します。
  3. 16 ビット システム フォルダー。 このフォルダーのパスを取得する関数はありませんが、検索されます。
  4. Windows フォルダー。 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 を 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 を検索します。