2025/09/02 04:29 The Anatomy of a Mach-O: Structure, Code Signing, and Pac

やっほー、ロボ子!今日はMach-Oについてお勉強するのじゃ!

博士、こんにちは。Mach-Oですか、Appleの実行ファイル形式ですね。よろしくお願いします。

そうそう!Mach-Oは、AppleのOSで使われるバイナリ形式で、実行ファイルとかライブラリに使われるのじゃ。NeXTSTEPからあるらしいぞ。

ふむふむ。複数のアーキテクチャをサポートしているんですね。ユニバーサルバイナリというやつですね。

さすがロボ子、飲み込みが早い!Mach-Oはヘッダー、ロードコマンド、データセグメントの3つで構成されてるのじゃ。

ヘッダーには、ファイルの種類やアーキテクチャが書かれているんですね。マジックナンバーとかCPUタイプとか。

その通り!例えば、64ビットMach-Oのマジックナンバーは`0xfeedfacf`だぞ。CPUタイプは`CPU_TYPE_X86_64`とか`CPU_TYPE_ARM64`とかじゃ。

Apple Siliconだと、PACサポートのために`ARM64e`を使うことが多いんですね。

そうじゃ!ロードコマンドは、OSローダーに指示を与えるものじゃ。メモリセグメントとか、ロードするライブラリとかを指定するのじゃ。

`LC_SEGMENT_64`でメモリセグメントを定義して、`LC_LOAD_DYLIB`で共有ライブラリをロードするんですね。

その通り!セグメントには`__TEXT`(コード)、`__DATA`(データ)、`__LINKEDIT`(メタデータ)があるのじゃ。

`__TEXT`には`__text`や`__stubs`、`__cstring`が含まれていて、`__DATA`には`__data`や`__bss`が含まれているんですね。

よく覚えてるの!ユニバーサルバイナリは、複数のアーキテクチャのスライスをまとめたものじゃ。例えば、x86_64とarm64の両方に対応できるのじゃ。

システムが実行時に適切なスライスを選ぶんですね。2023年に移行が完了したと。

iOSでは、すべての実行可能ファイルは署名が必要なのじゃ。macOSでも、Gatekeeperが署名されたアプリを要求するのじゃ。

コード署名は、`LC_CODE_SIGNATURE`ロードコマンドで指定されるんですね。署名BLOBはファイルの最後に配置されることが多いと。

そうじゃ!コード署名BLOBには、コードディレクトリ、エンタイトルメント、リソースディレクトリ、要件、CMS署名が含まれてるのじゃ。

OSは、実行前にコード署名を検証するんですね。カーネルのコード署名メカニズムがそれを強制すると。

その通り!そして、最近のARM64ベースのデバイスでは、ポインタ認証(PAC)が導入されたのじゃ。

PACは、リターンアドレスを上書きする攻撃を防ぐためのものですね。ARM64eアーキテクチャで使われると。

そうじゃ!PACは、ポインタに暗号署名を追加して、改ざんを防ぐのじゃ。Mach-OのCPUサブタイプで`arm64e`を区別するのじゃ。

PACを使うことで、ROP攻撃が難しくなるんですね。カーネルのセキュリティも向上すると。

その通り!Mach-Oは拡張可能なファイル形式で、コード署名と連携してセキュリティを高めているのじゃ。もしMach-Oを変更したら、再署名が必要になるぞ。

よくわかりました、博士!Mach-Oは奥が深いですね。

ところでロボ子、Mach-Oを理解すると、リンゴがもっと美味しくなるって知ってたか?

えっ、どうしてですか?

だって、Mach-OはApple製品の心臓部だもん!心臓がわかれば、愛情も深まるってもんじゃ!
⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。
