2.

DLL ファイル(.dll)とは | Windows 動的リンクライブラリの仕組み・LoadLibrary・DLL Hijacking 対策

編集
この記事の要点
  • .dll は Windows の動的リンクライブラリで、複数の .exe から共有できる関数・リソースを格納する
  • 内部構造は .exe と同じ PE 形式。違いは「単独実行できない」「エクスポートテーブルを持つ」点
  • 実行時には LoadLibrary / GetProcAddress または静的インポートテーブル経由でロードされる
  • Side-by-side(WinSxS)、マニフェスト、レジストリ COM 登録など、配置ルールが複雑になりがち
  • DLL Hijacking 攻撃を避けるため、ロード順序とフルパス指定に注意する

概要

.dll(Dynamic Link Library)は、Windows 上で複数のプログラムが共有して使う関数群やリソースをまとめたバイナリファイルです。たとえば kernel32.dll(Windows API の基盤)、user32.dll(ウィンドウ・メッセージ)、gdi32.dll(描画)といった OS の中核も DLL として提供されており、すべての Windows アプリは何らかの DLL に依存しています。

DLL の最大のメリットは コードの共有とメモリ効率です。10 個のアプリが同じ機能を必要としても、それぞれが同じコードを抱える代わりに 1 つの DLL を読み込めば、ディスク容量もメモリ使用量も大幅に節約できます。さらに DLL を差し替えるだけでバグ修正や機能追加ができ、アプリ本体(.exe)を再ビルドしなくて済みます。

一方で、依存する DLL が見つからない、バージョンが合わない、悪意ある DLL に差し替えられる、といった 「DLL 地獄」とも呼ばれる問題も発生しやすく、Windows の歴史は DLL 管理の試行錯誤の歴史でもあります。

内部構造

DLL のファイル構造は基本的に .exe と同じ PE 形式です。先頭の 4D 5A(MZ)ヘッダ、PE シグネチャ、COFF ヘッダ、オプショナルヘッダ、セクションテーブルという順序は同一で、違いは以下の点に集約されます。

  • Characteristics フラグ: COFF ヘッダの IMAGE_FILE_DLL ビットが立っている。これにより OS は「単独起動不可、ライブラリとしてロード」と判断する
  • エクスポートテーブル(.edata): 他プログラムから呼び出せる関数名・序数(ordinal)・アドレスの対応表。__declspec(dllexport) や DEF ファイルで指定する
  • エントリポイント: DllMainDLL_PROCESS_ATTACH / DLL_PROCESS_DETACH 等の通知を受ける
  • リソースセクション(.rsrc): アイコン、ダイアログ、文字列テーブル等。リソース専用 DLL も存在する

呼び出し側は次のいずれかでロードします。

  • 暗黙的リンク(静的インポート): ビルド時に .lib(インポートライブラリ)をリンクし、.exe の IAT(Import Address Table)に DLL 名と関数名が記録される。起動時に OS が自動ロード
  • 明示的リンク(動的ロード): HMODULE h = LoadLibrary(L"foo.dll");FARPROC p = GetProcAddress(h, "Bar");FreeLibrary(h);

主な用途

  • OS の API 提供: kernel32 / user32 / advapi32 / ntdll など Windows 自身のサブシステム
  • ランタイムライブラリ: msvcr*.dll(C ランタイム)、vcruntime140.dll、.NET の mscoree.dll
  • サードパーティライブラリ: Qt、OpenSSL、ffmpeg、zlib などの再配布パッケージ
  • プラグイン機構: Photoshop プラグイン、VST、Excel アドイン、ゲームの MOD などは DLL 形式で提供されることが多い
  • COM サーバ: regsvr32 foo.dll でレジストリに登録、CLSID 経由で生成

関連形式との比較

形式プラットフォーム用途備考
.dllWindows動的ライブラリPE 形式、エクスポートテーブル必須
.soLinux共有オブジェクトELF 形式、dlopen でロード
.dylibmacOS動的ライブラリMach-O 形式、dlopen
.lib(インポート)Windows静的リンクのスタブDLL 名と関数名のみ。実体は持たない
.lib(静的)Windows静的ライブラリオブジェクトコード本体。.exe に取り込まれる
.ocxWindowsActiveX コントロール実体は DLL

コマンド・ツール

  • dumpbin /exports foo.dll: エクスポート関数一覧を表示
  • dumpbin /imports app.exe: その .exe が必要とする DLL と関数を表示
  • Dependency Walker(depends.exe): 依存ツリーを GUI で可視化。古典的ツールだが Windows 10 以降は API セット DLL の扱いで誤検知あり
  • Dependencies(lucasg/Dependencies): Dependency Walker の現代版後継
  • Process Explorer / Process Hacker: 実行中プロセスがロードしている DLL 一覧
  • regsvr32 / regsvr32 /u: COM DLL の登録・解除
  • sxstrace.exe: Side-by-side アセンブリのロードエラー解析

注意点

  • DLL Hijacking(DLL Search Order Hijacking): LoadLibrary に絶対パスを与えないと、OS は決められた検索順(アプリディレクトリ → System32 → カレント → PATH)でロードする。攻撃者が同名 DLL を仕込むと乗っ取られる。対策は SetDefaultDllDirectoriesLoadLibraryEx のフラグ、KnownDLLs 機構
  • 32bit / 64bit の混在不可: 64bit .exe は 64bit DLL しかロードできない。プロセス内で混ぜることはできない
  • バージョン不整合: 同名異バージョンの DLL が複数存在すると問題が起きる。Side-by-side(WinSxS)/ マニフェスト / アプリローカル配置で解決
  • 循環依存と DllMain: DllMain 内で別 DLL を LoadLibrary するとデッドロック・クラッシュの原因。最小限の初期化のみ書く
  • 削除・上書きの困難さ: ロード中の DLL はロックされて削除できない。再起動や MoveFileEx + MOVEFILE_DELAY_UNTIL_REBOOT で対応

関連リンク

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. EXE(.exe)
  2. DLL(.dll)
  3. MSI(.msi)
  4. DMG(.dmg)
  5. DEB(.deb)
  6. RPM(.rpm)
  7. APK(.apk)
  8. IPA(.ipa)
  9. AppImage(.appimage)
  10. app(.app)

最近更新/作成されたページ