macOSのすべてのアプリケーションは、実行時にダイナミックライブラリ(dylib)やフレームワークをロードします。これらのロード済みモジュールを調べることで、リンクの問題のデバッグ、サードパーティ依存関係の監査、インジェクトされたライブラリの検出、アプリの内部アーキテクチャの理解に役立ちます。本記事では、組み込みのコマンドラインツールから専用GUIアプリまで、プロセスがロードしたモジュールを確認する5つの方法を紹介します。
結論から言うと
ターミナルでvmmap <pid> | grep '\.dylib'を実行すれば、実行中のプロセスにロードされたすべてのダイナミックライブラリを一覧表示できます。静的リンクの依存関係を確認するにはotool -L /path/to/binaryを使います。ロード済みモジュールをファイルパス、バージョン、UUIDとともに視覚的かつ検索可能なインターフェースで確認したい場合は、**ProcXray**が便利です。
macOSにおけるロード済みモジュールとは?
ロード済みモジュールとは、macOSのダイナミックリンカ(dyld)が実行時にプロセスのアドレス空間にマッピングするダイナミックライブラリ(.dylib)、フレームワーク(.framework)、またはバンドル(.bundle)のことです。大きく2つのカテゴリに分かれます:
- ロード時の依存関係 — コンパイル時にバイナリがリンクするライブラリ。プロセス起動時にダイナミックリンカが自動的にロードします。
- 実行時ロードライブラリ — 実行中に
dlopen()を通じてオンデマンドでロードされるライブラリ。プラグイン、拡張機能、オプション機能によく使われるパターンです。
macOSのシステムプロセスは通常100〜300のモジュールをロードし、XcodeやChromeのような複雑なアプリでは1,000以上をロードすることもあります。どのモジュールがロードされているかを把握することは、クラッシュの診断、バージョン競合の特定、セキュリティ監査にとって極めて重要です。
方法1:vmmap — 実行中プロセスのロード済みモジュールを一覧表示
vmmapコマンドは、実行中のプロセスの仮想メモリ領域を表示します。ロードされた各dylibは独自のメモリ領域を占有するため、出力をフィルタリングすることで、現在メモリ上にあるすべてのモジュールを確認できます。
# PIDを指定して、実行中プロセスのロード済みdylibを一覧表示
vmmap <pid> | grep '\.dylib'
PIDを先に調べるには:
# SafariのPIDを検索
pgrep -x Safari
出力例:
__TEXT 7FF80B2A0000-7FF80B2C1000 r-x/r-x /usr/lib/system/libsystem_kernel.dylib
__TEXT 7FF80B2C1000-7FF80B2FD000 r-x/r-x /usr/lib/system/libsystem_c.dylib
__TEXT 7FF80B300000-7FF80B365000 r-x/r-x /usr/lib/libobjc.A.dylib
各行には、メモリアドレス範囲、パーミッション、ロードされたライブラリのフルパスが表示されます。
フレームワークも含めて表示するには:
# ロード済みdylibとフレームワークをすべて表示
vmmap <pid> | grep -E '\.(dylib|framework)/'
ロードされたモジュール数をカウントするには:
vmmap <pid> | grep '\.dylib' | awk '{print $NF}' | sort -u | wc -l
vmmapを使うべきタイミング
vmmapは、実行中のプロセスが実際にメモリにロードしているすべてのものを確認したいときに使います。otoolでは表示できない実行時ロードモジュールも含まれます。プロセスが実行中である必要があり、システムプロセスの場合は管理者権限が必要になることがあります。
方法2:otool -L — 静的リンク依存関係の確認
otoolコマンドはMach-Oバイナリを検査します。-Lフラグを使うと、バイナリがコンパイル時にリンクしているすべてのダイナミックライブラリを一覧表示します。
# アプリケーションバイナリのリンク済みライブラリを一覧表示
otool -L /Applications/Safari.app/Contents/MacOS/Safari
出力例:
/Applications/Safari.app/Contents/MacOS/Safari:
/System/Library/Frameworks/WebKit.framework/Versions/A/WebKit
/System/Library/Frameworks/AppKit.framework/Versions/C/AppKit
/usr/lib/libSystem.B.dylib
/usr/lib/libc++.1.dylib
これは、バイナリがロードすることを想定しているライブラリ、つまりコンパイル時の依存関係を示します。dlopen()で実行時にロードされるライブラリは表示されません。
特定のdylibが依存しているライブラリを調べるには:
otool -L /usr/lib/libobjc.A.dylib
otoolを使うべきタイミング
otool -Lは、バイナリを実行する前に何をロードするはずかを確認したいときに使います。ビルド設定の検証、正しいSDKフレームワークがリンクされているかの確認、欠落した依存関係の検出に役立ちます。
方法3:lsof — オープンファイル経由でロード済みライブラリを検索
lsofコマンドは、プロセスがオープンしているすべてのファイルを一覧表示します。ロードされたライブラリはメモリマップドファイルであるため、lsofの出力に表示されます。
# プロセスのロード済み.dylibファイルをすべて表示
lsof -p <pid> | grep '\.dylib'
フレームワークも含めるには:
lsof -p <pid> | grep -E '\.(dylib|framework)'
lsofを使うべきタイミング
lsofは、手早く確認したいとき、すでに使い慣れている場合に使います。ただし、vmmapのほうがより詳細な情報(メモリアドレス、パーミッション)を提供するため、モジュール検査にはそちらが推奨されます。
方法4:dyld_info — ダイナミックリンカの検査
macOS 12(Monterey)以降、Appleはダイナミックリンカ情報を検査するためのdyld_infoコマンドを提供しています。
# バイナリの依存dylibをすべて表示
dyld_info -dependents /Applications/Safari.app/Contents/MacOS/Safari
実行中のプロセスのdyld共有キャッシュの使用状況を検査するには:
# プラットフォームと依存関係を表示
dyld_info -platform -dependents /usr/lib/libobjc.A.dylib
dyld_infoを使うべきタイミング
dyld_infoは、プラットフォーム要件や依存関係チェーンなど、ダイナミックリンカの動作に関する詳細情報が必要なときに使います。依存関係分析ではotoolよりクリーンな出力が得られます。
方法5:ProcXray — ビジュアルモジュールインスペクタ
ProcXrayには専用のModulesタブがあり、実行中のあらゆるプロセスのロード済みモジュールを表示できます。コマンドを覚える必要も、出力をパースする必要もありません。
ProcXrayでモジュールを検査する方法
- ProcXrayを起動します。
- プロセスリストからプロセスを選択します(検索バーやツリービューで探せます)。
- 詳細パネルのModulesタブをクリックします。
- ロード済みdylibとフレームワークの完全なリストを、ファイルパスや詳細情報とともに閲覧します。
Modulesタブの検索フィールドでライブラリ名をフィルタリングできます。例えば「libsystem」と入力すればロード済みシステムライブラリをすべて検索でき、「swift」と入力すればSwiftランタイムモジュールを見つけられます。

CLIツールに対するProcXrayの優位点
- ワンクリックで検査。 プロセスを選んでModulesをクリックするだけ。PIDを調べたりコマンドを入力したりする必要がありません。
- 検索とフィルタリング。 リアルタイムの検索結果で、名前によるモジュールの即座のフィルタリングが可能です。
- フルコンテキスト。 環境変数、オープンファイル、ネットワーク接続、コード署名など、隣接タブでモジュールと並行して確認できます。
- すべてのプロセスに対応。 異なるシナリオごとに異なるコマンドを組み立てることなく、あらゆる実行中プロセスを検査できます。
各方法の比較
| 機能 | vmmap | otool -L | lsof | dyld_info | ProcXray |
|---|---|---|---|---|---|
| 実行時ロードモジュールの表示 | 可 | 不可 | 可 | 不可 | 可 |
| 静的依存関係の表示 | 不可 | 可 | 不可 | 可 | 不可 |
| プロセス実行中が必要 | はい | いいえ | はい | いいえ | はい |
| メモリアドレスの詳細 | あり | なし | なし | なし | なし |
| 検索 / フィルタリング | 手動(grep) | 手動(grep) | 手動(grep) | なし | 組み込み |
| 使いやすさ | 普通 | 簡単 | 普通 | 簡単 | 最も簡単 |
| macOSバージョン | 全て | 全て | 全て | 12以降 | 14以降 |
実践的なユースケース
クラッシュの原因となるライブラリの欠落やバージョン不一致のデバッグ
# 想定しているバージョンのライブラリがロードされているか確認
vmmap <pid> | grep 'libssl'
出力が想定と異なるlibssl(例えばシステムのものではなくHomebrewのもの)を指していれば、バージョン競合の原因を特定できたことになります。
インジェクトされたライブラリの監査
セキュリティ研究者や開発者は、想定外のライブラリがプロセスにロードされていないかを確認できます:
# /Systemや/usr/lib以外のライブラリを検索
vmmap <pid> | grep '\.dylib' | grep -v '/System/' | grep -v '/usr/lib/'
結果が表示された場合、サードパーティによるインジェクション、プラグイン、またはカスタムフレームワークの可能性があり、調査する価値があります。
特定のフレームワークを使用しているか確認
# このアプリはSwiftUIを使用しているか?
vmmap <pid> | grep 'SwiftUI'
# Metalにリンクしているか?
otool -L /path/to/binary | grep 'Metal'
FAQ
macOSでのdylibとフレームワークの違いは何ですか?
.dylibは単独のダイナミックライブラリファイルです。.frameworkは、dylibに加えてヘッダ、リソース、メタデータを含むバンドルディレクトリです。フレームワークはAppleのシステムライブラリやサードパーティSDKの標準パッケージ形式です。実行時にはどちらもdyldによって同じ方法でロードされます。
ターミナルを使わずに実行中のアプリが使用しているdylibを確認できますか?
はい。ProcXrayを使えば、任意の実行中プロセスを選択し、組み込みの検索機能を持つグラフィカルインターフェースでロード済みモジュールを確認できます。ターミナルコマンドは一切不要です。
プロセスが何百ものライブラリをロードするのはなぜですか?
macOSはダイナミックリンクに大きく依存しています。Swiftで書かれたシンプルな「Hello World」アプリでさえ、Swiftランタイム、Foundationフレームワーク、コアシステムライブラリがそれぞれ独自の依存関係を引き込むため、100以上のモジュールをロードします。これは正常な仕様です。共有ライブラリにより、システム全体のメモリ使用量が削減されます。
otool -Lでプロセスがロードするすべてのものを表示できますか?
いいえ。otool -Lはコンパイル時のリンク依存関係のみを表示します。dlopen()で実行時にロードされるライブラリ(プラグイン、オプション機能、遅延ロードコンポーネントなど)は表示されません。完全な全体像を把握するには、実行中のプロセスに対してvmmapを使用してください。
他のプロセスのモジュールを検査するのにsudoは必要ですか?
自分のプロセスであれば不要です。システムプロセスや他のユーザーが所有するプロセスの場合、vmmapやlsofでsudoが必要になることがあります。ProcXrayは初回起動時に必要なmacOSのアクセス許可を求めるプロンプトを表示します。
出典・参考文献
- Apple: vmmap man page
- Apple: otool man page
- Apple: dyld — Dynamic Link Editor
- Apple: lsof man page
ProcXrayをダウンロード → — 無料、macOS Sonoma以降対応。