ブログに戻る

macOSでプロセスのロード済みモジュールとライブラリを確認する方法

macOSで実行中のプロセスにロードされたダイナミックライブラリ(dylib)やフレームワークを、vmmap、otool、lsof、dyld_info、ProcXrayを使って調べる方法を解説します。

macOSのすべてのアプリケーションは、実行時にダイナミックライブラリ(dylib)やフレームワークをロードします。これらのロード済みモジュールを調べることで、リンクの問題のデバッグ、サードパーティ依存関係の監査、インジェクトされたライブラリの検出、アプリの内部アーキテクチャの理解に役立ちます。本記事では、組み込みのコマンドラインツールから専用GUIアプリまで、プロセスがロードしたモジュールを確認する5つの方法を紹介します。

結論から言うと

ターミナルでvmmap <pid> | grep '\.dylib'を実行すれば、実行中のプロセスにロードされたすべてのダイナミックライブラリを一覧表示できます。静的リンクの依存関係を確認するにはotool -L /path/to/binaryを使います。ロード済みモジュールをファイルパス、バージョン、UUIDとともに視覚的かつ検索可能なインターフェースで確認したい場合は、**ProcXray**が便利です。

macOSにおけるロード済みモジュールとは?

ロード済みモジュールとは、macOSのダイナミックリンカ(dyld)が実行時にプロセスのアドレス空間にマッピングするダイナミックライブラリ(.dylib)、フレームワーク(.framework)、またはバンドル(.bundle)のことです。大きく2つのカテゴリに分かれます:

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でモジュールを検査する方法

  1. ProcXrayを起動します。
  2. プロセスリストからプロセスを選択します(検索バーやツリービューで探せます)。
  3. 詳細パネルのModulesタブをクリックします。
  4. ロード済みdylibとフレームワークの完全なリストを、ファイルパスや詳細情報とともに閲覧します。

Modulesタブの検索フィールドでライブラリ名をフィルタリングできます。例えば「libsystem」と入力すればロード済みシステムライブラリをすべて検索でき、「swift」と入力すればSwiftランタイムモジュールを見つけられます。

ProcXrayのModulesタブで、検索フィルタリングを使ってプロセスのロード済みライブラリを表示している画面

CLIツールに対するProcXrayの優位点

各方法の比較

機能vmmapotool -Llsofdyld_infoProcXray
実行時ロードモジュールの表示不可不可
静的依存関係の表示不可不可不可
プロセス実行中が必要はいいいえはいいいえはい
メモリアドレスの詳細ありなしなしなしなし
検索 / フィルタリング手動(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は必要ですか?

自分のプロセスであれば不要です。システムプロセスや他のユーザーが所有するプロセスの場合、vmmaplsofsudoが必要になることがあります。ProcXrayは初回起動時に必要なmacOSのアクセス許可を求めるプロンプトを表示します。

出典・参考文献

ProcXrayをダウンロード → — 無料、macOS Sonoma以降対応。