読者です 読者をやめる 読者になる 読者になる

DLL 検索順序 (3)

さていよいよ本題です.SxS アセンブリの有効な Windows XP で,仮に exe ファイルと同じディレクトリに GDIPlus.dll を置いたとしましょう.もちろん Windows XP なので %WINDIR%\WinSxS 以下にも GDIPlus.dll は存在します.さてこのとき,以下のそれぞれの方法で DLL を読み込むと,読み込まれるのはプライベートな GDIPlus.dll と SxS 版の DLL どちらでしょうか?

  1. gdiplus.lib とリンクし Load-Time Dynamic Linking を行う
  2. LoadLibrary("GDIPlus.dll") で Run-Time Dynamic Linking を行う
  3. LoadLibrary("(絶対パス)\GDIPlus.dll") で Run-Time Dynamic Linking を行う
  4. gdiplus.lib とリンクし LoadLibrary("(絶対パス)\GDIPlus.dll") も行う

結果は次の通りです.

  1. SxS 版が読み込まれる.
  2. SxS 版が読み込まれる.
  3. プライベート版が読み込まれる.
  4. SxS 版とプライベート版が両方読み込まれる.

大抵の開発者は gdiplus.lib とリンクしているでしょうから,少なくとも Windows XP に限ればかなりの度合いで安全そうに見えます.たとえ DLL 検索順序的には危険な位置にわざわざ脆弱性のある GDIPlus.dll が deploy されていたとしても,まんまと SxS DLL が出し抜いてくれるでしょう.もっとも,敢えて絶対パス指定で読み込まれるとどうしようもありません.
とはいっても,ここに書いたことを鵜呑みにされてもさすがに責任はとれません.もし Windows XP をお使いの方でサードパーティー製のアプリケーションが GDIPlus.dll を deploy しているのを見つけたら,そのアプリケーションが実際にどのバージョンの DLL がロードされているか念のため Process Explorer で確かめてみてください.
http://www.sysinternals.com/ntw2k/freeware/procexp.shtml
(追記)サポート技術情報が更新されていて,開発者が気をつけるべき点が分かりやすくまとめられています.下記資料も参考にして下さい.

side-by-side アセンブリを使用するソフトウェア開発者向けの推奨事項

  • アプリケーションを出荷する際に、アプリケーションのビルドまたはテストの際に使用した side-by-side アセンブリのバージョンが記載されているアプリケーション マニフェストを含めるようにします。
  • アプリケーション フォルダに展開するように選択する場合でも、必ず side-by-side アセンブリのマニフェスト ファイルを side-by-side DLL と共に展開します。
  • Microsoft Windows 2000 またはそれ以前のバージョンの Windows を実行しているコンピュータにアプリケーションをインストールする場合、それらのオペレーティング システムでは、side-by-side アセンブリをアプリケーション フォルダに展開しないようにします。side-by side アセンブリは、システム フォルダから使用するようにしてください。
  • .local 機能 (Windows での DLL/COM リダイレクト) を使用しないようにします。
  • side-by-side アセンブリに対して LoadLibrary 関数を実行する際、完全なパスを明示的に指定しないようにします。その代わり、静的リンクを使用するか、LoadLibrary 関数で DLL のファイル名を直接指定します。たとえば、ファイル名として "Gdiplus.dll" を指定します。