2025/10/15 11:44 Reverse Engineering iWork

ロボ子、今日はiWorkファイルの解析について話すのじゃ!

iWorkファイル、ですか。Pages、Keynote、Numbersなどのファイル形式ですね。

そうじゃ!Appleは2013年にiWorkのドキュメントフォーマットをXMLからProtocol Buffersベースのバイナリ形式に変更したらしいのじゃ。

なるほど。それで、どのように解析するんですか?

まず、Pages, Keynote, Numbersの実行ファイルからprotobufメッセージ記述子を抽出するのじゃ。そして、SwiftのprotobufライブラリのVisitor APIを使って、記述子を人間が読める`.proto`ファイルに変換するぞ!

Visitor APIですか。便利そうですね。

Appleはprotobufの上にオブジェクト指向レイヤーを構築し、継承やリフレクション機能を追加したらしいのじゃ。凝ってるのう。

さらに、iWork Archive (IWA)内の各メッセージはタイプIDを持ち、対応するSwiftクラスへのマッピングが必要とのことです。

そうそう!Fridaを使って`TSPRegistry`からタイプIDとクラス名のマッピングを抽出するのじゃ。

IWAドキュメントはディレクトリバンドルまたはZIPアーカイブ形式で、Index.zip(またはIndex/ディレクトリ)にドキュメント構造が格納されているんですね。

IWAはSnappy圧縮を使用するが、Appleの実装は標準から逸脱し、CRC32チェックサムを省略しているのがミソじゃ。

ふむふむ。IWAは一連の圧縮されたprotobufメッセージを含むアーカイブチャンクで構成され、各チャンクは長さを示すvarintと`TSP.ArchiveInfo`メッセージで始まるんですね。

`ArchiveInfo`メッセージには、メッセージのタイプIDと長さが含まれているのじゃ。

IWAフォーマットはインクリメンタルアップデートをサポートし、`should_merge`フラグでメッセージのマージを指定するとのことです。

パーサーは2パスシステムを使用し、最初に非マージメッセージをロードし、次にインクリメンタルアップデートをマージするのじゃ。

Pages, Keynote, Numbersは同じIWAフォーマットを共有するものの、コンテンツ構造は異なるんですね。ドキュメントレコード(ID 1)でアプリケーションを判別する、と。

画像は`TSD_ImageArchive`メッセージに格納され、`Data/`ディレクトリ内のファイルを参照するのじゃ。オーディオ、ビデオ、3Dモデルはすべて同じ`TSD_MovieArchive`メッセージタイプを使用するぞ。

数式は`TSD_ImageArchive`メッセージに格納され、LaTeXまたはMathMLソースがIWAファイル内の拡張フィールドとして存在するんですね。

テーブルは`TST_TableModelArchive`に構造とデータが格納され、セル内容は圧縮されたバイナリ形式でタイルストレージに保存されるのじゃ。

テーブルはタイル(通常256x256セル)に分割され、各セルのデータは12バイトのヘッダーで始まるバイナリ構造にパックされるんですね。

セルにはDecimal128値、Double値、タイムスタンプ、文字列ID、リッチテキストIDなどのオプションフィールドが含まれるのじゃ。

セル境界線は個々のセルではなく、連続した境界線ランを定義するストロークレイヤーを使用するんですね。

通貨セルは独自のセルタイプとフォーマット情報を持ち、ISO 4217コード、小数点以下の桁数、記号の表示などを指定するのじゃ。

数式を含むセルの計算値はドキュメントにキャッシュされるんですね。

図形は複数のジオメトリタイプをサポートするパスシステムを使用し、`PathSource`列挙型で表現されるのじゃ。

グラフはデータグリッド、軸、シリーズスタイル、凡例を組み合わせるんですね。

スタイル要素(段落、文字、セル、図形)は継承チェーンを使用し、プロパティはチェーンをたどって解決されるのじゃ。

配置されたすべての要素には、フレーム、回転、Zインデックス、座標空間などの空間情報が含まれるんですね。

KeynoteスライドとNumbersシートの場合、描画可能オブジェクトは空間位置(上から下、左から右)でソートされるのじゃ。

パーサーはVisitorパターンを使用し、`IWorkDocumentVisitor`プロトコルを実装して、ドキュメント要素のトラバーサル順にコールバックを提供するんですね。

すべてのコードはSwiftパッケージとしてgithub.com/6over3/WorkKitで入手可能じゃ!

すごいですね、博士!ところで、この解析技術を使って、何か面白いことはできませんか?

うむ、例えばじゃな、iWorkファイルの中身を全部猫語に変換するとか…

それ、需要あります…?
⚠️この記事は生成AIによるコンテンツを含み、ハルシネーションの可能性があります。
