ダイナミック リンク ライブラリの検索順序
同じダイナミック リンク ライブラリ (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 とその依存関係を検索します。
システムは、モジュールまたはその依存関係を検索するときに、パッケージ化されたアプリの検索順序を常に使用します。依存関係がパッケージ化されたアプリ コードでない場合でも。
パッケージ アプリの標準検索順序
システムは次の順序で検索します。
- DLL リダイレクト。
- API セット。
- デスクトップ アプリのみ (UWP アプリではありません)。 SxS マニフェスト リダイレクト。
- Loaded-module リスト。
- 既知の DLL。
- プロセスのパッケージ依存関係グラフ。 これは、アプリケーションのパッケージと、アプリケーションのパッケージ マニフェストのセクションで
<Dependencies>
指定されている<PackageDependency>
依存関係です。 依存関係は、マニフェストに表示される順序で検索されます。 - 呼び出し元のプロセスが読み込まれたフォルダー (実行可能ファイルのフォルダー)。
- システム フォルダー (
%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 検索モードが有効になっている場合、検索順序は次のようになります。
- DLL リダイレクト。
- API sets.
- SxS manifest redirection.
- Loaded-module list.
- Known DLLs.
-
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. - アプリケーションの読み込み元のフォルダー。
- システム フォルダー。 GetSystemDirectory 関数を使用して、このフォルダーのパスを取得します。
- 16 ビット システム フォルダー。 このフォルダーのパスを取得する関数はありませんが、検索されます。
- Windows フォルダー。 GetWindowsDirectory 関数を使用して、このフォルダーのパスを取得します。
- 現在のフォルダー。
- 環境変数に
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 は、標準の検索順序と同じです。
- lpFileName で指定されたフォルダー。
- The system folder. Use the GetSystemDirectory function to retrieve the path of this folder.
- The 16-bit system folder. There's no function that obtains the path of this folder, but it is searched.
- The Windows folder. GetWindowsDirectory 関数を使用して、このフォルダーのパスを取得します。
- 現在のフォルダー。
- 環境変数に
PATH
一覧表示されているディレクトリ。 これには、 App Paths レジストリ キーで指定されたアプリケーションごとのパスは含まれません。 DLL 検索パスを計算する場合、 アプリ パス キーは使用されません。
安全な DLL 検索モードが 無効になっている場合、 現在のフォルダー がシーケンス内の位置 11 から位置 8 に移動する点を除き、代替検索順序は同じです (手順 7 の直後)。lpFileName で指定されたフォルダー)。
lpPathName パラメーターでパスが指定されている場合、SetDllDirectory 関数は代替検索順序をサポートします。 代替検索順序は次のとおりです。
手順 1 から 6 は、標準の検索順序と同じです。
- アプリケーションの読み込み元のフォルダー。
- SetDllDirectory の lpPathName パラメーターで指定されたフォルダー。
- システム フォルダー。
- 16 ビット システム フォルダー。
- Windows フォルダー。
- 環境変数に一覧表示されている
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 で指定されたフラグによって異なります。 複数のフラグを使用する場合、対応するディレクトリは次の順序で検索されます。
- LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR。 DLL を含むフォルダーが検索されます。 このフォルダーは、読み込まれる DLL の依存関係のみを検索します。
- LOAD_LIBRARY_SEARCH_APPLICATION_DIR。 アプリケーション フォルダーが検索されます。
- LOAD_LIBRARY_SEARCH_USER_DIRS。 AddDllDirectory 関数または SetDllDirectory 関数で明示的に追加されたパスが検索されます。 複数のパスを追加する場合、パスの検索順序は指定されません。
- LOAD_LIBRARY_SEARCH_SYSTEM32。 [システム] フォルダーが検索されます。
LOAD_LIBRARY_SEARCH フラグなしで LoadLibraryEx を呼び出すか、プロセスの DLL 検索順序を確立すると、システムは標準の検索順序または代替検索順序を使用して DLL を検索します。