マッハO

マッハO
Mac OS X 実行可能バイナリアイコン
ファイル名拡張子
なし.o、、、.dylib[ .kext1]
統一型識別子(UTI)com.apple.mach-o-binary
開発者カーネギーメロン大学Apple Inc.
フォーマットの種類バイナリ実行可能オブジェクト共有ライブラリコアダンプ
コンテナ用ARMSPARCPA-RISCPowerPCx86 実行可能コード、メモリイメージダンプ

Mach-OMachオブジェクト)は、実行ファイルオブジェクトコード共有ライブラリ、動的にロードされるコード、コアダンプ用のファイル形式です。a.out形式の代替として開発されました

Mach-O は、Mach カーネルをベースとする一部のシステムで使用されています。NeXTSTEP macOSiOS はネイティブ実行ファイル、ライブラリ、オブジェクト コードにこの形式を使用するシステムの例です。

ファイルレイアウト

各Mach-Oファイルは、1つのMach-Oヘッダー、それに続く一連のロードコマンド、そして1つ以上のセグメントで構成されます。各セグメントには0~255個のセクションが含まれます。Mach-Oは、シンボルへの参照を処理するためにREL再配置形式を使用します。シンボルの検索では、Mach-Oは2レベルの名前空間を使用します。この名前空間は、各シンボルを「オブジェクト名/シンボル名」のペアにエンコードし、最初にオブジェクト名、次にシンボル名で線形検索します。[2]

基本構造(ファイル内の他の場所にあるデータページを参照する可変長の「ロードコマンド」のリスト[3] )は、 Accentの実行ファイル形式でも使用されました[引用が必要] Accentファイル形式は、 Spice Lispのアイデアに基づいています[引用が必要]

すべてのデータ構造内のすべてのマルチバイト値は、コードが生成されたホストのバイト順序で書き込まれます。 [4]

Mach-Oファイルヘッダー[5]
オフセットバイト説明
04魔法の数字
44CPUタイプ
84CPUサブタイプ
124ファイルタイプ
164ロードコマンドの数
204ロードコマンドのサイズ
244
284予約済み(64ビットのみ)

ビッグエンディアンバイナリ(つまり、アーキテクチャがビッグエンディアンを使用している)の場合、32ビットコードのマジックナンバーは 、0xfeedface64ビットアーキテクチャのマジックナンバーはです。リトルエンディアンバイナリの場合、 32ビットの場合は 、 64ビットの場合は0xfeedfacfになります。後者の2つは、前者のエンディアンを反転させたものです。0xcefaedfe0xcffaedfe

予約値は64ビットMach-Oファイルにのみ存在します。これは将来の使用または64ビットヘッダーの拡張のために予約されています。

CPUタイプは、コードの命令セットアーキテクチャを示します。ファイルが64ビット版の命令セットアーキテクチャ用の場合、CPUタイプの値に0x01000000ビットがセットされます。ファイルが32ビット命令セットアーキテクチャ用であるにもかかわらず、64ビットハードウェア上で実行されている場合、CPUタイプの値に0x02000000ビットがセットされます。

CPUタイプの値は次のとおりです。[6]

CPUタイプ
価値CPUタイプ
0x00000001ヴァックス
0x00000002ロンプ
0x00000004NS32032
0x00000005NS32332
0x00000006MC680x0
0x00000007x86
0x00000008ミップス
0x00000009NS32352
0x0000000BHP-PA
0x0000000Cアーム
0x0000000DMC88000
0x0000000ESPARC
0x0000000Fi860 (ビッグエンディアン)
0x00000010i860(リトルエンディアン)またはDEC Alpha [7]
0x00000011RS/6000
0x00000012パワーPC / MC98000
0x00000018RISC-V

各CPUタイプには、コードが対象とするCPUタイプの特定のモデルを示すCPUサブタイプ値のセットがあります。CPUタイプの新しいモデルは、古いCPUモデルではサポートされていない命令やその他の機能をサポートしている場合があり、新しいモデル用にコンパイルまたは作成されたコードには、古いモデルでは無効な命令が含まれる可能性があります。その結果、古いモデルで実行すると、コードがトラップしたり、正しく動作しなかったりする可能性があります。古いモデル向けのコードは、新しいモデルでも問題なく動作します。

CPUタイプがARMの場合、サブタイプは次のようになります。[6]

CPUサブタイプARM
価値CPUバージョン
0x00000000すべてのARMプロセッサ
0x00000001ARM-A500 ARCH 以降向けに最適化されています。
0x00000002ARM-A500 以降向けに最適化されています。
0x00000003ARM-A440 以降向けに最適化されています。
0x00000004ARM-M4 以降向けに最適化されています。
0x00000005ARM-V4T 以降向けに最適化されています。
0x00000006ARM-V6 以降向けに最適化されています。
0x00000007ARM-V5TEJ 以降向けに最適化されています。
0x00000008ARM-XSCALE 以降向けに最適化されています。
0x00000009ARM-V7 以降向けに最適化されています。
0x0000000AARM-V7F (Cortex A9) 以降向けに最適化されています。
0x0000000BARM-V7S (Swift) 以降向けに最適化されています。
0x0000000CARM-V7K (Kirkwood40) 以降向けに最適化されています。
0x0000000DARM-V8 以降向けに最適化されています。
0x0000000EARM-V6M 以降向けに最適化されています。
0x0000000FARM-V7M 以降向けに最適化されています。
0x00000010ARM-V7EM 以降向けに最適化されています。

CPUタイプがx86の場合、サブタイプは次のようになります。[6]

CPUサブタイプ x86
価値CPUバージョン
0x00000003すべて x86 プロセッサ。
0x00000004486 以降に最適化されています。
0x00000084486SX 以降向けに最適化されています。
0x00000056Pentium M5 以降向けに最適化されています。
0x00000067Celeron 以降向けに最適化されています。
0x00000077Celeron Mobile向けに最適化されています。
0x00000008Pentium 3 以降に最適化されています。
0x00000018Pentium 3-M 以降向けに最適化されています。
0x00000028Pentium 3-XEON 以降向けに最適化されています。
0x0000000APentium-4 以降に最適化されています。
0x0000000BItanium 以降向けに最適化されています。
0x0000001BItanium-2 以降向けに最適化されています。
0x0000000CXEON 以降向けに最適化されています。
0x0000001CXEON-MP 以降向けに最適化されています。

サブタイプ値の後にはファイル タイプ値が続きます。

ファイルタイプ
価値説明
0x00000001再配置可能なオブジェクト ファイル。
0x00000002ページングされた実行可能ファイルを要求します。
0x00000003VM共有ライブラリファイルを修正しました。
0x00000004コアファイル。
0x00000005プリロードされた実行可能ファイル。
0x00000006動的にバインドされた共有ライブラリ ファイル。
0x00000007ダイナミック リンク エディター。
0x00000008動的にバインドされたバンドル ファイル。
0x00000009静的リンクのみの共有ライブラリ スタブ。セクションの内容はありません。
0x0000000Aデバッグ セクションのみを含むコンパニオン ファイル。
0x0000000Bx86_64 kext。
0x0000000C単一のリンクエディターを共有する同じユーザー空間で実行される他の Mach-O で構成されたファイル。

ファイル タイプ値の後には、ロード コマンドの数と、Mach-O ヘッダーの後のロード コマンドの合計バイト数が続き、その後に次の設定が可能な 32 ビット フラグが続きます。

フラグ設定
左シフトのフラグバイナリフラグ説明
1<<00000_0000_0000_0000_0000_0000_0001オブジェクト ファイルには未定義の参照はありません。
1<<10000_0000_0000_0000_0000_0000_0010オブジェクト ファイルは、ベース ファイルに対する増分リンクの出力であり、再度リンク編集することはできません。
1<<20000_0000_0000_0000_0000_0000_0100オブジェクト ファイルは動的リンカーの入力であり、再度静的にリンク編集することはできません。
1<<30000_0000_0000_0000_0000_0000_1000オブジェクト ファイルの未定義の参照は、ロード時に動的リンカーによってバインドされます。
1<<40000_0000_0000_0000_0000_0000_0001_0000ファイルには動的な未定義参照が事前にバインドされています。
1<<50000_0000_0000_0000_0000_0000_0010_0000ファイルは読み取り専用セグメントと読み取り/書き込みセグメントに分割されています。
1<<60000_0000_0000_0000_0000_0000_0100_0000共有ライブラリの init ルーチンは、書き込み可能なセグメントへのメモリ障害をキャッチすることで遅延実行されます (廃止)。
1<<70000_0000_0000_0000_0000_0000_1000_0000イメージは 2 レベルの名前空間バインディングを使用しています。
1<<80000_0000_0000_0000_0000_0001_0000_0000実行可能ファイルは、すべてのイメージにフラットな名前空間バインディングを使用するように強制します。
1<<90000_0000_0000_0000_0000_0010_0000_0000このアンブレラは、サブイメージ内のシンボルの複数の定義がないことを保証するため、2 レベルの名前空間ヒントを常に使用できます。
1<<100000_0000_0000_0000_0000_0100_0000_0000dyld にこの実行可能ファイルについて事前バインド エージェントに通知させません。
1<<110000_0000_0000_0000_0000_1000_0000_0000バイナリは事前バインドされていませんが、事前バインドをやり直すことができます。MH_PREBOUND が設定されていない場合にのみ使用されます。
1<<120000_0000_0000_0000_0001_0000_0000_0000このバイナリが依存ライブラリのすべての 2 レベルの名前空間モジュールにバインドすることを示します。
1<<130000_0000_0000_0000_0010_0000_0000_0000デッドコード除去用のシンボルを使用してセクションをサブセクションに分割しても安全です。
1<<140000_0000_0000_0000_0100_0000_0000_0000バイナリは、un-prebind 操作によって正規化されました。
1<<150000_0000_0000_0000_1000_0000_0000_0000最終的なリンクされたイメージには、外部の弱いシンボルが含まれています。
1<<160000_0000_0000_0001_0000_0000_0000_0000最終的にリンクされた画像では弱いシンボルが使用されています。
1<<170000_0000_0000_0010_0000_0000_0000_0000このビットが設定されている場合、タスク内のすべてのスタックにスタック実行権限が付与されます。
1<<180000_0000_0000_0100_0000_0000_0000_0000このビットが設定されている場合、バイナリは uid が 0 のプロセスで使用しても安全であると宣言します。
1<<190000_0000_0000_1000_0000_0000_0000_0000このビットが設定されている場合、バイナリは、UGID が true の場合にプロセスで使用しても安全であると宣言します。
1<<200000_0000_0001_0000_0000_0000_0000_0000このビットが dylib に設定されている場合、静的リンカーは依存する dylib を調べて再エクスポートされているかどうかを確認する必要がありません。
1<<210000_0000_0010_0000_0000_0000_0000_0000このビットが設定されている場合、OS はランダムなアドレスにメイン実行可能ファイルをロードします。
1<<220000_0000_0100_0000_0000_0000_0000_0000dylib でのみ使用します。このビットが設定されている dylib にリンクする場合、dylib からシンボルが参照されていない場合、静的リンカーは dylib へのロードコマンドを自動的に作成しません。
1<<230000_0000_1000_0000_0000_0000_0000_0000S_THREAD_LOCAL_VARIABLES タイプのセクションが含まれます。
1<<240000_0001_0000_0000_0000_0000_0000_0000このビットが設定されている場合、OS は、実行可能ヒープを必要としないプラットフォーム (i386 など) でも、メインの実行可能ファイルを非実行可能ヒープで実行します。
1<<250000_0010_0000_0000_0000_0000_0000_0000コードはアプリケーションで使用するためにリンクされました。
1<<260000_0100_0000_0000_0000_0000_0000_0000nlist シンボル テーブルにリストされている外部シンボルには、dyld 情報にリストされているすべてのシンボルが含まれているわけではありません。
1<<270000_1000_0000_0000_0000_0000_0000_0000macOS、macCatalyst、iOSSimulator、tvOSSimulator、watchOSSimulator プラットフォームで LC_MIN_VERSION_MACOS および LC_BUILD_VERSION ロード コマンドを許可します。
1<<311000_0000_0000_0000_0000_0000_0000_0000dylibs 専用です。このビットが設定されている場合、dylib はファイルシステムに分散されるのではなく、dyld 共有キャッシュの一部となります。
----0xxx_0000_0000_0000_0000_0000_0000_0000「x」マークの付いた数字は使用されず、将来の使用のために予約されています。

フラグ内で複数のバイナリ数字を 1 つに設定して、バイナリに適用される情報または設定を識別することができます。

ここで、Mach-O ヘッダーの末尾に到達すると、ロード コマンドが読み取られます。

マルチアーキテクチャバイナリ

複数のMach-Oファイルをマルチアーキテクチャバイナリに組み合わせることができます。これにより、単一のバイナリファイルに、例えばARM64x86-64などの異なるプロセッサアーキテクチャ[8]を含む、異なる世代や種類のAppleデバイスなど、複数の命令セットアーキテクチャをサポートするコードを含めることができます[9]

ユニバーサルヘッダー内のすべてのフィールドはビッグエンディアンです。[4]

ユニバーサルヘッダーは次の形式です: [10]

Mach-Oユニバーサルヘッダー
オフセットバイト説明
04魔法の数字
44バイナリの数

マルチアーキテクチャバイナリのマジックナンバーは0xcafebabeビッグエンディアンのバイト順なので、ヘッダーの最初の 4 バイトは常に0xca 0xfe 0xba 0xbeその順になります。

バイナリの数は、ヘッダーに続くエントリの数です。

ヘッダーの後に、次の形式のエントリのシーケンスが続きます。[11]

Mach-Oユニバーサルファイルエントリ
オフセットバイト説明
04CPUタイプ
44CPUサブタイプ
84ファイルオフセット
124サイズ
164セクションの配置(2の累乗)

エントリのシーケンスの後に、Mach-O 画像のシーケンスが続きます。各エントリは 1 つの Mach-O 画像を参照します。

エントリの CPU タイプとサブタイプは、エントリが参照する Mach-O イメージの CPU タイプとサブタイプと同じである必要があります。

ファイル オフセットとサイズは、エントリが参照する Mach-O イメージの先頭のファイル内のオフセットと、Mach-O イメージのサイズです。

セクションアラインメントは、エントリが参照するMach-Oイメージに必要なファイル内のバイトアラインメントの対数(底は2)です。例えば、値が14の場合、イメージは2 14バイト境界、つまり16384バイト境界にアラインメントされている必要があります。これは、マルチアーキテクチャバイナリを変更するツールがイメージの適切なアラインメントを維持するために必要です。

ロードコマンド

ロード コマンドは Mach-O ヘッダーの直後に読み取られます。

Mach-Oヘッダーは、Mach-Oヘッダーの後に存在するロードコマンドの数と、ロードコマンドの終了位置までのバイト数を指定します。ロードコマンドのサイズは冗長性チェックとして使用されます。

最後のロード コマンドが読み取られ、ロード コマンドのバイト数が一致しない場合、または最後のロード コマンドに到達する前にロード コマンドのバイト数を超えた場合、ファイルが破損する可能性があります。

各ロードコマンドは次の形式のエントリのシーケンスです。[12]

ロードコマンド
オフセットバイト説明
04コマンドタイプ
44コマンドサイズ

ロードコマンドタイプは、ロードコマンド内のパラメータを識別します。ロードコマンドが0x80000000ビットセットで始まる場合、バイナリをロードまたは実行するためにロードコマンドが必要です。これにより、古いMach-Oローダーは、アプリケーションのロードに必須ではない、ローダーが理解できないコマンドをスキップできます。

セグメントロードコマンド

ロードコマンドタイプを使用するMach-Oバイナリは、0x00000001セグメントロードコマンドの32ビットバージョンを使用します。[13]は、0x00000019セグメントロードコマンドの64ビットバージョンを指定するために使用されます。[14]

セグメントロードコマンドは、Mach-Oヘッダーが32ビットか64ビットかによって異なります。これは、64ビットプロセッサアーキテクチャでは64ビットアドレスが使用され、32ビットアーキテクチャでは32ビットアドレスが使用されるためです。

アプリケーション間の間隔を保つため、すべての仮想RAMアドレスはベースアドレスに追加されます。セグメントロードコマンドの各セクションには、アプリケーションのベースアドレスに基づいて調整する必要があるセクション内のオフセットを指定する再配置リストオフセットがあります。アプリケーションを定義済みのRAMアドレス位置(例えばベースアドレス0)に配置できる場合、再配置は不要です。

ロードコマンド(セグメントロード32/64)
オフセット(32ビット)バイト(32ビット)オフセット(64ビット)バイト(64ビット)説明
04040x00000001(コマンドタイプ32ビット)

0x00000019(コマンドタイプ64ビット)

4444コマンドサイズ
816816セグメント名
244248住所
284328アドレスサイズ
324408ファイルオフセット
364488サイズ(ファイルオフセットからのバイト数)
404564最大限の仮想メモリ保護
444604初期仮想メモリ保護
484644セクション数
524684フラグ32

セグメント名は16バイトを超えるテキスト文字数にすることはできません。未使用の文字数は0x00値に含まれます。

セグメントコマンドには、仮想アドレス空間におけるセクションの書き込みアドレスとアプリケーションのベースアドレスが含まれます。また、そのアドレス位置に書き込むバイト数(アドレスサイズ)も指定します。

アドレス情報の後には、Mach-O バイナリ内のセグメント データが配置されているファイル オフセットと、ファイルから読み取るバイト数が続きます。

アドレス サイズがファイルから読み取るバイト数より大きい場合、 RAM 空間の残りのバイトが設定されます0x00

と呼ばれるセグメントがあり__PAGEZERO、ファイルオフセットがゼロで、ファイル内でのサイズがゼロです。このセグメントには、定義された仮想メモリアドレスとサイズがあります。アクセス許可もゼロに設定されているため、まったく使用できません(このセグメントにアクセスするとページフォールトが発生します)。このセグメントの目的は、無効な NULL ポインタ(値がゼロ)を捕捉することです。32 ビット環境では、このセグメントのデフォルトサイズは 4 KiB ですが、64 ビット環境では 4 GiB です(これにより、32 ビット整数によるラウンドトリップ割り当て中に切り捨てられた可能性のある無効な 32 ビット NULL ポインタが捕捉されます)。このセグメントのサイズは、-pagezero_sizeコンパイラ/リンカーフラグで設定できます。

セグメントが仮想アドレス空間に最初に配置されると、初期仮想メモリ保護値によって指定されたCPUアクセス権限が付与されます。仮想アドレス空間の領域に対する権限は、アプリケーションまたはライブラリコードから などのルーチンを呼び出すことで変更できますmprotect()。最大仮想メモリ保護によって、セグメントへのアクセスに付与できる権限が制限されます。

権限
バイナリでの許可ビット説明
00000000000000000000000000000001このセクションでは、CPU がこのセクションからデータを読み取ることを許可します (読み取り設定)。
00000000000000000000000000000010このセクションでは、CPU がこのセクションにデータを書き込むことを許可します (書き込み設定)。
00000000000000000000000000000100このセクションでは、CPU がこのセクション内のコードを実行できるようにします (実行設定)。
xxxxxxxxxxxxxxxxxxxxxxxxxxxxx000「x」マークの付いた数字は使用されず、将来の使用のために予約されています。

次に、CPU アドレス保護設定の後に、セグメント フラグ設定の後に読み取られるこのセグメント内のセクションの数があります。

セグメントフラグの設定は次のとおりです。

セグメントフラグの設定。
バイナリのFlag32説明
00000000000000000000000000000001このセグメントのファイルの内容は VM スペースの上位部分であり、下位部分はゼロで埋められています (コア ファイル内のスタック用)。
00000000000000000000000000000010このセグメントは、リンク エディターでの重複チェックのために、固定 VM ライブラリによって割り当てられた VM です。
00000000000000000000000000000100このセグメントには、再配置されたものも再配置されたものも存在しません。つまり、再配置せずに安全に置き換えることができます。
00000000000000000000000000001000このセグメントは保護されています。セグメントがファイルオフセット0から始まる場合、セグメントの最初のページは保護されません。セグメントのその他のページはすべて保護されます。
00000000000000000000000000010000このセグメントは、必要に応じて再配置が適用された後、読み取り専用になります。
xxxxxxxxxxxxxxxxxxxxxxxxxxx00000「x」マークの付いた数字は使用されず、将来の使用のために予約されています。

セグメント内のセクションの数は、次のように読み取られるエントリのセットです。

セグメントセクション32/64
オフセット(32ビット)バイト(32ビット)オフセット(64ビット)バイト(64ビット)説明
016016セクション名
16161616セグメント名
324328セクションアドレス
364408セクションサイズ
404484セクションファイルオフセット
444524アライメント
484564再配置ファイルのオフセット
524604移転件数
564644フラグ/タイプ
604684予約済み1
644724予約済み2
該当なし該当なし764予約済み3(64ビットのみ)

セクションのセグメント名は、セグメントのロードコマンド名と一致する必要があります。セクションのエントリは、セグメント内のデータに位置付けられます。各セクションは、アプリケーションベースアドレスにゼロ以外の値が加算された場合、セクション内のアドレスを調整するための再配置エントリに位置付けられます。

セクション サイズは、アドレス位置でのセクションのサイズと、オフセット位置でのファイル内のサイズの両方に適用されます。

セクションのフラグ/タイプの値は次のように読み取られます。

セクションフラグの設定
バイナリフラグ説明
10000000000000000000000000000000xxxxxxxxこのセクションには実際の機械命令のみが含まれています
01000000000000000000000000000000xxxxxxxxセクションには、ranlib の目次に含まれない結合シンボルが含まれています。
00100000000000000000000000000000xxxxxxxxMH_DYLDLINK フラグを持つファイル内のこのセクションの静的シンボルを削除しても問題ありません
00010000000000000000000000000000xxxxxxxxデッドストリッピングなし
00001000000000000000000000000000xxxxxxxxブロックはライブブロックを参照している場合、ライブです
00000100000000000000000000000000xxxxxxxxdyld によって書かれた i386 コードスタブで使用される
00000010000000000000000000000000xxxxxxxxデバッグセクション
00000000000000000000010000000000xxxxxxxxこのセクションにはいくつかの機械命令が含まれています
00000000000000000000001000000000xxxxxxxxセクションには外部再配置エントリがあります
00000000000000000000000100000000xxxxxxxxセクションにはローカル移転エントリがあります

セクションに適用される設定には、それぞれ1に設定された2進数の桁があります。最後の8桁の2進数はセクションタイプ値です。

セクションタイプの値
バイナリフラグ説明
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx00000110非遅延シンボルポインタのみのセクション
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx00000111遅延シンボルポインタのみのセクション
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx00001000シンボルスタブのみのセクション
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx00001100オンデマンドのゼロフィルセクション(4ギガバイトを超える場合があります)
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx00010000遅延ロードされた dylib への遅延シンボル ポインタのみを含むセクション

Mach-Oローダーは、シンボルポインタセクションとシンボルスタブセクションを記録します。これらは、間接シンボルテーブルによって順番に使用され、メソッド呼び出しにロードされます。

各シンボルスタブのサイズはreserved2値に格納されます。各ポインタは、32ビットMach-Oでは32ビットのアドレス位置、64ビットMach-Oでは64ビットのアドレス位置です。セクションの終端に達すると、間接シンボルテーブルを読み取りながら次のセクションに進みます。

セグメント番号とセクション番号

セグメントとセクションは、圧縮および非圧縮のリンク編集情報セクション内のセグメント番号とセクション番号によって配置されます。

セグメント値 3 は、Mach-O ファイル内の 4 番目のセグメント ロード コマンドのデータへのオフセットが 0 から始まることを意味します (0、1、2、3 = 4 番目のセグメント)。

セクションもセクション1から順に番号が付けられます。セクション値0は、シンボルテーブルにおいて、どのセクションにも定義されていないシンボル(未定義シンボル)を表します。例えば、メソッドや、別のバイナリシンボルテーブルセクション内に存在するデータなどです。

7 つのセクションがあるセグメントの場合、最後のセクションは 8 になります。次のセグメント ロード コマンドに 3 つのセクションがある場合、それらはセクション 9、10、および 11 としてラベル付けされます。セクション番号 10 は、2 番目のセグメント、つまりセクション 2 を意味します。

セクションが読み込まれる順序とアドレス/ファイル オフセット位置を保存しないと、シンボル テーブルとリンク情報を適切に読み取ることができません。

RAM アドレスや再配置を使用せずにファイル オフセットを使用すると、シンボル リーダーを構築したり、リンク編集セクションを読み取ったり、メソッド呼び出しをマップしたり、逆アセンブラーを設計したりすることが簡単にできます。

Mach-O ローダーを構築する場合、アプリケーションが互いに上書きされないように、アプリケーション間の間隔を保つために、セクションを定義済みの RAM アドレスとベース アドレスにダンプする必要があります。

セグメント名とセクション名は好きな名前に変更することができ、セグメント コマンドの順序を変更しない限り、セクション番号またはセグメント番号で適切なセクションを見つけるのに問題はありません。

リンク ライブラリは他の Mach-O バイナリと同じですが、プログラムが開始されるメイン エントリ ポイントを指定するコマンドがない点が異なります。

リンク ライブラリ ファイルをロードするためのロード コマンドは 3 つあります。

ロード コマンド タイプ0x0000000Cは、動的にリンクされた共有ライブラリへの完全なファイル パス用です。

ロード コマンド タイプ0x0000000Dは、アプリケーションの現在のパスから動的にリンクされた共有場所用です。

ロードコマンドタイプ0x00000018は、動的にリンクされた共有ライブラリ用であり、ライブラリが欠落していても構いません。シンボル名は他のリンクライブラリに存在し、ライブラリが欠落している場合に使用されます。つまり、すべてのシンボルが弱インポートされます。

リンク ライブラリ コマンドは次のように読み取られます。

ロードコマンド(リンクライブラリ)
オフセットバイト説明
040x0000000C(コマンドタイプ)

0x0000000D(コマンドタイプ)

0x00000018(コマンドタイプ)

44コマンドサイズ
84文字列オフセット(常にオフセット24)
124タイムスタンプ
164現在のバージョン
204互換バージョン
24コマンドサイズ - 24ファイルパス文字列

ファイルパス名は文字列オフセット(常に24)から始まります。テキスト文字あたりのバイト数は、コマンドサイズの残りのバイト数です。ライブラリファイルパスの末尾は、 という文字で識別されます0x00。残りの0x00値は、パディングとして使用されます(存在する場合)。

ライブラリは、圧縮および非圧縮のリンク編集情報セクション内の序数によって配置されます。

リンクライブラリは序数1から順に番号が付けられます。序数0はシンボルテーブルにおいて、そのシンボルが他のMach-Oバイナリに外部シンボルとして存在しないことを示すために使用されます。

リンク ライブラリ コマンドの順序を変更しない限り、リンク編集情報では、序数によって読み取る適切なライブラリを問題なく見つけることができます。

パフォーマンス上の理由から、リンク ライブラリ コマンドの使用0x00000018は避ける必要があります。ライブラリが見つからない場合、ロードされているすべてのリンク ライブラリを検索する必要があるためです。

__LINKEDIT シンボルテーブル

Mach-O アプリケーション ファイルとリンク ライブラリの両方に、シンボル テーブル コマンドがあります。

コマンドは次のように読みます。

ロードコマンド(シンボルテーブル)
オフセットバイト説明
040x00000002(コマンドタイプ)
44コマンドサイズ(常に24)
84シンボル(Mach-Oヘッダーに対するファイルオフセット)
124シンボルの数
164文字列テーブル(Mach-Oヘッダーに対するファイルオフセット)
204文字列テーブルのサイズ

シンボルファイルオフセットは、Mach-Oヘッダーの先頭からファイル内のシンボルエントリの開始位置までの相対オフセットです。シンボルエントリの数は、シンボルテーブルの終了位置を示します。

シンボルには名前オフセットがあり、これは文字列テーブルのサイズを超えてはなりません。各シンボル名のオフセットは、文字列テーブルファイルのオフセットに加算されます。このオフセットは、Mach-Oヘッダーの先頭からの相対位置です。各シンボル名は0x00バイト値で終わります。

シンボル アドレスは、32 ビット Mach-O ファイルの場合は 32 ビット アドレスを使用し、64 ビット Mach-O ファイルの場合は 64 ビット アドレスを使用します。

各シンボルエントリは次のように読み取られます。

シンボル32/64
オフセット(32ビット)バイト(32ビット)オフセット(64ビット)バイト(64ビット)説明
0404名前オフセット
4141シンボルの種類
5151セクション番号0~255
6262データ情報(ライブラリ序数)
8488シンボルアドレス

シンボル名オフセットが文字列テーブルオフセットに加算されます。最後のテキスト文字バイトは として読み取られます0x00

シンボルタイプの値は、バイナリ形式で複数の調整可能なセクションを持ちます。シンボルタイプは次のように読み取られます。

シンボルタイプのセクション
2進数説明
???xxxxxローカルデバッグシンボル
xxxx???xシンボルアドレスタイプ
xxx?xxx?シンボルの可視性設定フラグ

マークされた数字?は指定された目的に使用され、マークされた数字xは他の目的に使用されます。

最初の3桁のバイナリは、コンパイルされたマシンコード命令を基準とした関数名と、アドレス位置による行番号を示すシンボルです。この情報により、コードがクラッシュした場所の行番号を生成できます。ローカルデバッグシンボルはアプリケーションの設計時にのみ役立ちますが、アプリケーションの実行には必要ありません。

シンボルアドレスタイプ
バイナリ値説明
xxxx000xシンボルが未定義
xxxx001x絶対記号
xxxx101xシンボル間接
xxxx110xシンボルの事前バインドが未定義
xxxx111xセクション番号で定義されたシンボル

次のフラグ設定:

シンボルの可視性設定フラグ
バイナリ値説明
xxx1xxx0プライベートシンボル
xxx0xxx1外部シンボル

外部シンボルとは、リンクライブラリ内で定義済みのアドレスを持ち、Mach-Oアプリケーション内の未定義シンボルにコピーできるシンボルです。アドレス位置はリンクライブラリのベースアドレスに追加されます。

プライベートシンボルは、未定義シンボルの名前と一致していてもスキップされます。プライベートシンボルと外部シンボルが同じファイル内にある場合にのみ、未定義シンボルに設定できます。

シンボルタイプの後には、シンボルが存在するセクション番号が続きます。セクション番号はバイト値(0~255)です。セグメントロードコマンドを使用して255を超えるセクションを追加できますが、その場合、セクション番号はシンボルエントリで使用されるバイト値の範囲外になります。

セクション番号が0の場合、シンボルはアプリケーションのどのセクションにも存在せず、シンボルのアドレス位置は0で、Undefinedに設定されていることを意味します。一致する外部シンボル名は、シンボルアドレスを持つリンクライブラリ内に見つかる必要があります。

データ情報フィールドには、対応するシンボル名を持つ外部シンボルが見つかるリンクライブラリの序数が含まれます。データ情報ビットフィールドは以下のように分類されます。

シンボルデータ情報セクション
2進数説明
????????xxxxxxxx図書館序数 0~255
xxxxxxxx????xxxxダイナミックローダーフラグオプション
xxxxxxxxxxxx????住所タイプオプション

シンボルが外部シンボルであるか、現在のファイル内に存在する場合、ライブラリ序数は0に設定されます。未定義シンボルの場合のみ、データ情報セクションを使用してライブラリ序数とリンカーオプションを指定します。

ダイナミック ローダー フラグのオプションは次のとおりです。

ダイナミックローダーフラグオプション
2進数説明
xxxxxxxx0001xxxxdynamic-loader によって参照される定義済みシンボルに対して設定する必要があります。
xxxxxxxx0010xxxx実行時に動的リンカーによって使用されます。
xxxxxxxx0100xxxxダイナミック リンカーがこのシンボルの定義を見つけられない場合、このシンボルのアドレスを 0 に設定します。
xxxxxxxx1000xxxx静的リンカーまたは動的リンカーがこのシンボルの別の定義を見つけた場合、その定義は無視されます。

適用される 4 つのオプションのいずれかを設定できます。

アドレス タイプ オプションの値は次のとおりです。

ダイナミックローダーのアドレスオプション
2進数説明
xxxxxxxxxxxx0000非遅延ロードポインタメソッド呼び出し
xxxxxxxxxxxx0001遅延ロードされたポインタメソッド呼び出し
xxxxxxxxxxxx0010このライブラリ/プログラムで定義されたメソッド呼び出し
xxxxxxxxxxxx0011このライブラリ/プログラムで定義されたプライベートメソッド呼び出し
xxxxxxxxxxxx0100プライベート非遅延ロードポインタメソッド呼び出し
xxxxxxxxxxxx0101プライベート遅延ロードポインタメソッド呼び出し

値によって設定できるアドレス型値は1つだけです。ポインタとは、プログラムのマシンコードによって読み取られ、別のバイナリファイルからメソッドを呼び出すための値です。プライベートとは、他のプログラムがバイナリ自体以外の関数/メソッドを読み取ったり呼び出したりできないようにすることを意味します。レイジーとは、ポインタがdyld_stub_binderに移動し、シンボルを検索してメソッドを呼び出し、dyld_stub_binderの位置をシンボルの位置に置き換えることを意味します。バイナリ内のマシンコードからの以降の呼び出しは、シンボルのアドレスに移動し、dyld_stub_binderは呼び出されません。

シンボルテーブルの構成

シンボルテーブルエントリはすべてタイプ順に保存されます。最初に読み込まれるシンボルは、ローカルデバッグシンボル(存在する場合)、次にプライベートシンボル、外部シンボル、そして最後に、別のMach-Oバイナリ内の外部シンボルアドレスを含む別のバイナリシンボルテーブルにリンクする未定義シンボルです。

Mach-Oバイナリにシンボルテーブルセクションがある場合、シンボルテーブル情報ロードコマンドは0x0000000B常に存在します。このコマンドは、リンカーにローカルシンボル、プライベートシンボル、外部シンボル、未定義シンボルの数を伝えます。また、シンボルの開始番号も指定します。シンボルテーブル情報は、動的リンカーがシンボルエントリを読み取る前に使用されます。これは、未定義シンボルにロードするシンボルの読み取り開始位置と、すべてのシンボルエントリを読み取ることなく一致する外部シンボルを検索する読み取り開始位置を動的リンカーに指示するためです。

シンボルセクションにおけるシンボルの順序は、各シンボルが0から順に番号付けされるため、変更しないでください。シンボルテーブル情報コマンドは、未定義シンボルをスタブセクションとポインタセクションにロードする際の順序としてシンボル番号を使用します。順序を変更すると、マシンコード実行時に誤ったメソッドが呼び出されることになります。

__LINKEDIT シンボルテーブル情報

0x00000002シンボル テーブル情報コマンドは、リンク中に未定義のシンボルと外部シンボルを高速に検索するために、動的リンカーがシンボル テーブル コマンドの下にあるシンボル テーブル エントリをどこで読み取るかを知るために使用されます。

コマンドは次のように読みます。

ロードコマンド(シンボルテーブル情報)
オフセットバイト説明
040x0000000B(コマンドタイプ)
44コマンドサイズ(常に80)
84ローカルシンボルインデックス
124ローカルシンボルの数
164外部シンボルインデックス
204外部シンボルの数
244未定義シンボルインデックス
284未定義シンボルの数
324コンテンツテーブルのオフセット
364コンテンツテーブルエントリの数
404モジュールテーブルオフセット
444モジュールテーブルエントリの数
484参照シンボルテーブルへのオフセット
524参照されるシンボルテーブルエントリの数
564間接シンボルテーブルオフセット
604間接シンボルテーブルエントリ
644外部再配置オフセット
684外部移転エントリの数
724ローカル再配置オフセット
764ローカル移転エントリの数

シンボル インデックスは、Mach-O 32 ビットの場合は 12 倍、Mach-O 64 ビットの場合は 16 倍に、シンボル テーブル エントリのオフセットを加算して、シンボル番号インデックスによってシンボル エントリを読み取るためのオフセットを見つけます。

ローカルシンボルのインデックスは、シンボルエントリの先頭にあるためゼロです。ローカルシンボルはデバッグ情報として使用されます。

ローカル シンボルの数は、シンボル インデックスの後に存在するシンボルの数です。

シンボル テーブル エントリを高速に読み取るために、同じ 2 つのプロパティが外部シンボルと未定義シンボルに対して繰り返されます。

プライベート シンボルがある場合、ローカル シンボルと外部シンボルの間には小さなインデックス/サイズのギャップがあります。

ゼロのファイル オフセットは未使用です。

間接テーブル

Mach-Oローダーは、セグメントロードコマンドの実行中にシンボルポインタセクションとシンボルスタブセクションを記録します。これらは間接シンボルテーブルによって順番に使用され、メソッド呼び出しにロードされます。セクションの終端に達すると、次のセクションに進みます。

間接シンボル テーブル オフセットは、シンボル番号インデックスとして使用される 32 ビット (4 バイト) 値のセットを見つけます。

シンボル インデックス番号の順序は、ポインター セクションとスタブ セクションに各シンボル アドレスを次々に書き込む順序です。

シンボルスタブセクションには、間接シンボルアドレスへのJUMP命令を含むマシンコード命令が含まれており、これらの命令は別のMach-Oバイナリからメソッド/関数を呼び出すために使用されます。各JUMP命令のサイズはプロセッサの種類に基づいており、セグメントロードコマンドのセクション32/64のreserved2値に格納されます。

ポインタセクションは、32ビットMach-Oバイナリの場合は32ビット(4バイト)のアドレス値、64ビットMach-Oバイナリの場合は64ビット(8バイト)のアドレス値です。ポインタはマシンコードによって読み取られ、読み取られた値はメソッド/関数を呼び出す位置として使用され、マシンコード命令は格納されません。

シンボル インデックス番号0x40000000ビット セットは絶対メソッドであり、ポインターがメソッドの正確なアドレスに配置されることを意味します。

シンボルのインデックス番号0x80000000ビットがセットされているのはローカルメソッドであり、これはポインター自体がメソッドに配置されており、メソッド名がないことを意味します (ローカルメソッド)。

逆アセンブラーを設計している場合は、シンボル名だけを各スタブとポインターのオフセット アドレスに簡単にマップして、他の Mach-O ファイル内の未定義のシンボル アドレスの場所を探すことなく、実行されているメソッドまたは関数の呼び出しを表示できます。

__LINKEDIT 圧縮テーブル

圧縮リンク編集テーブルコマンドが存在する場合、シンボルテーブル内の未定義/外部シンボルは不要になります。間接シンボルテーブルとスタブおよびポインタセクションの位置も不要になります。

新しい OS バージョンと古い OS バージョンにロードされる下位互換性のある Mach-O ファイルを構築する場合、間接シンボル テーブルは依然として存在します。

ロードコマンド(圧縮リンク編集テーブル)
オフセットバイト説明
040x00000022(コマンドタイプ)
44コマンドサイズ(常に48バイト)
84ファイルのオフセットをリベースする
124リベースサイズ
164バインドファイルオフセット
204バインドサイズ
244弱いバインドファイルオフセット
284弱いバインドサイズ
324遅延バインドファイルオフセット
364遅延バインドサイズ
404エクスポートファイルのオフセット
444エクスポートサイズ

ゼロのファイル オフセットは未使用のセクションです。

バインディング情報

バインド、弱いバインド、および遅延バインド セクションは、同じ操作コード形式を使用して読み取られます。

元々、シンボル テーブルは、シンボル テーブルのデータ情報フィールドのアドレス タイプを、遅延、弱、または非遅延として定義します。

弱い結合とは、ライブラリ序数で検索するライブラリが設定されており、設定されたシンボル名が存在しないが、以前にロードされた別の Mach-O ファイルに存在する場合、シンボルの場所は他の Mach-O ファイルから使用されることを意味します。

遅延とは、書き込まれたアドレスがdyld_stub_binderに配置されることを意味します。dyld_stub_binderはシンボルを検索し、メソッドを呼び出し、dyld_stub_binderの位置をシンボルの位置に置き換えます。バイナリ内のマシンコードからの以降の呼び出しは、シンボルのアドレスに配置され、dyld_stub_binderは呼び出されません。

昔ながらのシンプルなbindセクションでは、複雑な読み込みやアドレス指定は一切行いません。シンボルは、指定されたライブラリ序数内に存在する必要があります。

0x1Xリンクライブラリの序数を設定するバイト値。16進数Xは0から15までのライブラリ序数です。

リンク ライブラリの序数を、操作コードの後に​​読み取られる値に設定する0x20バイト値。0x2F

バイトシーケンス0x20 0x84 0x01セットの序数は 132 です。

オペレーションコードの後の数値はLEB128数値としてエンコードされます。最後の7桁の2進数が1に設定されている限り、それらの数値は加算されてより大きな数値を形成します。これにより、可変長の数値をエンコードできます。

0x4Xシンボル名を設定するバイト値。Xでマークされた16進数はフラグ設定を設定します。

フラグ設定が8の場合、メソッドは弱インポートされていることを意味します。フラグ設定が1の場合、メソッドは弱インポートされていないことを意味します。

バイトシーケンスは0x48 0x45 0x78 0x61 0x6D 0x70 0x6C 0x65 0x00シンボル名を設定します。例:最後のテキスト文字バイトは です0x00。これは弱インポートであるため、同じ名前の別のエクスポート可能なシンボルが見つかった場合、置き換えられる可能性があります。

バイト値は0x7X現在位置を設定します。Xでマークされた16進数は、選択されたセグメント0~15を表します。オペレーションコードの後に​​は、セグメントオフセットにLEB128数値として追加されたオフセットが続きます。

バイト シーケンスは0x72 0x8C 0x01、位置を 3 番目のセグメント ロード コマンド アドレスに設定し、アドレスに 140 を追加します。

0x90現在のセット位置をセットシンボル名とライブラリ序数にバインドする操作コード0x9F。32ビットMach-Oバイナリの場合は現在のセット位置を4バイト分インクリメントし、64ビットMach-Oバイナリの場合はセットアドレスを8バイト分インクリメントします。

バイトシーケンス0x11 0x72 0x8C 0x01 0x48 0x45 0x78 0x61 0x6D 0x70 0x6C 0x65 0x00 0x90 0x48 0x45 0x78 0x61 0x6D 0x70 0x6C 0x65 0x32 0x00 0x90

リンクライブラリの序数を1に設定します。位置をセグメント番号2に設定し、現在の位置に140を加算します。選択されたライブラリ序数でExampleというシンボルを検索します。演算コードは0x90シンボルアドレスを書き込み、現在の設定アドレスをインクリメントします。その後の演算コードは、次のシンボル名を設定してExample2というシンボルを検索します。演算コードは0x90シンボルアドレスを書き込み、現在の設定アドレスをインクリメントします。

新しい形式では、シンボル テーブル内の繰り返しフィールドが削除され、間接シンボル テーブルは廃止されます。

アプリケーションのメインエントリポイント

type で始まるロード コマンドは0x00000028、アプリケーションが開始するアドレス位置を指定するために使用されます。

ロードコマンド(メインエントリポイント)
オフセットバイト説明
040x00000028(コマンドタイプ)
44コマンドサイズ(常に24バイト)
88住所の場所
168スタックメモリサイズ

プログラムのセグメント/セクションを実行のために再配置する必要がない場合、メインエントリポイントは正確なアドレス位置になります。これは、アプリケーションセグメントのアドレスがアプリケーションベースアドレス0に加算され、かつセクションの再配置が不要であった場合のみ適用されます。

Mach-Oローダーの主なエントリポイントは、プログラムのベースアドレスとアドレス位置の組み合わせです。これは、CPUがマシンコード命令の実行を開始するアドレスです。

0x00000005これは、プログラムの開始前にすべてのレジスタが持つべき状態を保存するため、CPU タイプによって異なっていた古いロード コマンドに代わるものです。

アプリケーションUUID番号

type で始まるロード コマンドは、アプリケーションのユニバーサル一意識別子0x0000001B(UUID)を指定するために使用されます。

ロードコマンド(UUID番号)
オフセットバイト説明
040x0000001B(コマンドタイプ)
44コマンドサイズ(常に24バイト)
816128ビットUUID

UUID には、アプリケーションがコンパイルされたときに生成される 128 ビットの一意のランダム番号[引用が必要]が含まれており、インターネット上またはアプリ ストアでアプリケーション ファイルを識別するために使用できます。

最小OSバージョン

type で始まるロード コマンドは0x00000032、最小 OS バージョン情報を指定するために使用されます。

ロードコマンド(最小OSバージョン)
オフセットバイト説明
040x00000032(コマンドタイプ)
44コマンドサイズ
84プラットフォームタイプ
124最小OSバージョン
164SDKバージョン
204使用したツールの数

バイナリの実行対象となるプラットフォームの種類は次のとおりです。

プラットフォームの種類。
価値プラットフォーム
0x00000001macOS
0x00000002iOS
0x00000003テレビOS
0x00000004ウォッチOS
0x00000005ブリッジOS
0x00000006Mac Catalyst
0x00000007iOSシミュレーター
0x00000008tvOSシミュレーター
0x00000009watchOSシミュレーター
0x0000000Aドライバーキット
0x0000000BビジョンOS
0x0000000CvisionOSシミュレーター

32ビットバージョン値は、16ビット値と2つの8ビット値として読み取られます。32ビットバージョンの値は、0x000D02000x000Dが13である 、次の8ビットが0x02値が2である 、最後の8ビットが0x00値が0である となり、バージョン番号は13.2.0vとなります。SDKバージョン値も同様に読み取られます。

バイナリを作成するツールの数は、次のように読み取られるエントリのセットです。

ツールの種類
オフセットバイト説明
04ツールの種類
44ツールバージョン

ツールタイプの値は次のとおりです。

ツールタイプの値。
価値使用したツールの種類
0x00000001カラン
0x00000002迅速
0x00000003LD

バージョン番号は、OS バージョンや SDK バージョンと同じように読み取られます。

Mac OS X 10.6プラットフォームの導入により、Mach-O ファイルは大幅に変更され、10.6 以降でコンパイルされたバイナリは (デフォルトでは) Mac OS X 10.6 以降でのみ実行可能になりました。この違いは、以前の Mac OS X バージョンのダイナミック リンカーが理解できないロード コマンドに起因しています。Mach-O 形式のもう 1 つの重要な変更は、リンク編集テーブル (__LINKEDIT セクションにあります) の機能の変更です。10.6 では、これらの新しいリンク編集テーブルは、未使用および不要な情報ビットを削除することで圧縮されますが、Mac OS X 10.5 以前では、この新しいリンク編集テーブル形式を読み取ることができません。下位互換性のある実行ファイルを作成するには、リンカー フラグ "-mmacosx-version-min=" を使用できます。

その他の実装

Mach-Oパーサーとエディター

セキュリティ研究者などがMac以外の場所からMach-Oファイルを扱うことは珍しくありません。Mach-O(ファイル形式)のデータ構造を解析したり、編集したりできるプログラムは広く普及しています。

Rubyプログラミング言語では、ruby-macho [15]ライブラリがMach-Oバイナリパーサーとエディターの実装を提供しています。

マッハOランナー

理論上は、Mach-O 形式のプログラムは、Mach-O イメージをメモリにロードできるコードによって、プログラムがビルドされたオペレーティング システム以外のオペレーティング システムでも実行できます。ただし、使用しているコンピューターの CPU タイプと一致する Mach-O バイナリ イメージが存在する必要があります。ほとんどのデスクトップ コンピューターとラップトップ コンピューターにはx86プロセッサーが搭載されているため、x86 バイナリの Mach-O は、メモリにロードされたセクションを実行できます。iPhone や iPad 用のプログラムなど、Mach-O にARMバイナリしかない場合は、互換性のある ARM コア (必ずしもApple Siliconコアとは限らない) を搭載したコンピューターでのみ実行できます。それ以外の場合は、 QEMUなどのエミュレーション ツールを使用し、ARM 命令を同等の x86 命令に変更する必要があります。

Mach-O をロードして直接実行する際、実際的な問題として「未定義シンボル」が挙げられます。バイナリは通常、真空中では存在せず、動作するために Mach-O バイナリ(ライブラリ)から関数/メソッド(シンボル)を呼び出します。シンボルが見つからないことがこのエラーの原因となります。iPhone (iOS)、macOS、watchOS、tvOS 用の Mach-O ファイルはそれぞれ異なるライブラリ群を前提としているため、この問題により非互換性が生じます。これらのライブラリは、プログラムを実行しようとしているマシン上に存在するか、Mach-O ローダーが独自のアダプタ関数またはホストオペレーティングシステムの既存の関数を使用して置き換える必要があります。呼び出されるライブラリルーチンは、バイナリが対象とする OS のルーチンと同じアプリケーションバイナリインターフェースを提供するか、アダプタルーチンを提供する必要があります。

  • NetBSDのいくつかのバージョンでは、バイナリ互換性の実装の一環としてMach-Oサポートが追加され、一部のMac OS 10.3バイナリを実行できるようになりました。[16] [17]
  • Linux向けには、浜地真一郎氏によって10.6バイナリをロードできるMach-Oローダーが書かれました。[18]このローダーをベースにしたより拡張性の高いソリューションとして、DarlingプロジェクトはmacOSアプリケーションをLinux上で実行できる完全な環境を提供することを目指しています。
  • ravynOS(旧称airyxOS)は、 FreeBSDにmacOSライクなユーザーランドを導入するための取り組みです。まずソースコードの互換性を提供し、次にバイナリの互換性を提供することを目指しています。

Darwinオペレーティングシステム#派生プロジェクトも参照してください。これには、macOS/iOSのバイナリ互換性を実現するための他のいくつかの取り組みが含まれています。同じDarwinカーネルを直接ベースとした取り組みでさえ、Appleがオープンソース化していないライブラリやその他のコンポーネントを置き換えるために追加のコードが必要でした。

参照

参考文献

  1. ^ Mach-Oプログラミングトピックス(PDF) . Apple. 2006年11月28日.
  2. ^ 「OS X ABI Mach-O ファイルフォーマットリファレンス」。Apple Inc. 2009年2月4日。2014年9月4日時点のオリジナルよりアーカイブ。
  3. ^ Avadis Tevanian, Jr.; Richard F. Rashid; Michael W. Young; David B. Golub; Mary R. Thompson; William Bolosky; Richard Sanzi (1987年6月). 「Machにおける共有メモリとメモリマップファイルのためのUnixインターフェース」. USENIXサマーカンファレンス議事録. 米国アリゾナ州フェニックス: USENIX協会. pp.  53– 67.
  4. ^ ab 「データ型」。OS X ABI Mach-O ファイルフォーマットリファレンス。Apple Inc. 2009年2月4日 [2003]。2014年9月11日時点のオリジナルよりアーカイブ。 2023年3月15日閲覧
  5. ^ GitHubの loader.h
  6. ^ GitHubのabc machine.h
  7. ^ “darwin-xnu/osfmk/mach/machine.h at 2ff845c2e033bd0ff64b5b6aa6063a1f8f65aa32 · apple/darwin-xnu”. GitHub . 2024年12月24日閲覧
  8. ^ 「ユニバーサルバイナリと32ビット/64ビットPowerPCバイナリ」。OS X ABI Mach-Oファイルフォーマットリファレンス。Apple Inc. 2009年2月4日 [2003]。2014年9月4日時点のオリジナルよりアーカイブ。
  9. ^ 「ユニバーサルmacOSバイナリの構築」。Apple Developer
  10. ^ "fat_header". OS X ABI Mach-O ファイルフォーマットリファレンス. Apple Inc. 2009年2月4日 [2003]. 2014年9月4日時点のオリジナルよりアーカイブ。
  11. ^ "fat_arch". OS X ABI Mach-O ファイルフォーマットリファレンス. Apple Inc. 2009年2月4日 [2003]. 2014年9月4日時点のオリジナルよりアーカイブ。
  12. ^ 「ロードコマンドのデータ構造」。OS X ABI Mach-O ファイルフォーマットリファレンス。Apple Inc. 2009年2月4日 [2003]。2014年9月11日時点のオリジナルよりアーカイブ。 2023年3月15日閲覧
  13. ^ "segment_command". OS X ABI Mach-O ファイルフォーマットリファレンス. Apple Inc. 2009年2月4日 [2003]. 2014年9月11日時点のオリジナルよりアーカイブ。 2023年3月15日閲覧
  14. ^ "segment_command_64". OS X ABI Mach-O ファイルフォーマットリファレンス. Apple Inc. 2009年2月4日 [2003]. 2014年9月11日時点のオリジナルよりアーカイブ。 2023年3月15日閲覧
  15. ^ William Woodruff (2021年11月15日)、Mach-Oファイルを解析するための純粋なRubyライブラリ。
  16. ^ Emmanuel Dreyfus (2006年6月20日). 「Mach and Darwin binary compatiblity [sic] for NetBSD/powerpc and NetBSD/i386」 . 2013年10月18日閲覧
  17. ^ Emmanuel Dreyfus (2004年9月)、NetBSDにおけるMac OS Xバイナリ互換性:課題と実装(PDF)
  18. ^ Shinichiro Hamaji、Linux 用 Mach-O ローダー - 私が書きました...

参考文献

  • レビン、ジョナサン(2019年9月25日). *OS内部構造、第1巻:ユーザーモード(v1.3.3.7版). ノースキャッスル、ニューヨーク州:Technologeeks. ISBN 978-0-9910555-6-2
  • Singh, Amit (2006年6月19日). Mac OS X 内部構造:システムアプローチ. Addison-Wesley Professional. ISBN 978-0-13-270226-3
  • Wayback Machineの OS X ABI Mach-O ファイル形式リファレンス(2014 年 9 月 4 日アーカイブ) (Apple Inc.)
  • Mach-O(5) –  DarwinmacOSファイル形式マニュアル
  • Mach オブジェクト ファイル (NEXTSTEP ドキュメント)
  • Mach-O ダイナミックライブラリリファレンス
  • Mach-Oのリンクとロードのトリック
  • マコビュー
  • JDasm (macOS、iOS、Windows PE、ELF 用のクロスプラットフォーム逆アセンブラー、およびファイル形式分析ツール)
Retrieved from "https://en.wikipedia.org/w/index.php?title=Mach-O&oldid=1323683079"