4 ポイント 投稿者 GN⁺ 2025-04-07 | 1件のコメント | WhatsAppで共有

iOS 14 QEMUエミュレーションの旅の始まり

  • 既存のオープンソースプロジェクト alephsecurity/xnu-qemu-arm64 を使っていたが、read-only で拡張性に欠ける問題があった
  • その後 TrungNguyen1909/qemu-t8030 プロジェクトを使うことで、次の機能を活用できた:
    • iOSの復元機能(USB接続用QEMUを同伴)
    • iOS 14の起動
    • 最新のQEMUバージョンをベース
    • 詳細なWikiドキュメントを提供
  • launchd.plist の修正によりシェルおよびSSHアクセスに成功し、良い出発点となった
  • 目標は、UIとアプリを実行できる完全なiOSエミュレーション環境の構築である

カーネルパッチとPongoOSの導入

  • t8030 プロジェクトはQEMU内部でカーネルパッチを当てる構造だった → 保守性と拡張性の問題が発生
  • 脱獄の経験をもとに、PongoOS を通じて checkra1n パッチを適用する構成へ移行
  • QEMUでSRAMサイズを増やしてPongoOSを実行し、checkra1n-KPFモジュールを注入
  • ブート時にブートロム/iboot機能の欠落でFPU未設定の問題が発生 → ARMドキュメントを参考に解決
  • A13以降でPAC(Pointer Authentication)が導入され、一部パッチが無効化された
  • task_for_pid0 (tfp0) の例として、PAC導入前後のバイナリを比較

カーネルパッチ自動化ツールの開発

  • 既存のcheckra1n動的パッチ方式は読みづらく修正しにくい → 宣言的なテキストベースのパッチ方式を導入
  • 2つの Mach-O バイナリを比較してアセンブリ差分を抽出し、テキストパッチを生成
  • Pongoで起動後にメモリをダンプしてカーネルを再構築 → 全パッチをテキストファイルに整理しコメント化

グラフィックレンダリング: Metal vs ソフトウェアレンダリング

  • iOSはすべてのUIレンダリングを Metal API経由で行う → GPUが必要
  • GPUエミュレーションが複雑なため、代替案を検討:
    • ソフトウェアレンダリング
    • Metal呼び出しを実機へプロキシ転送
  • iOS 14では gpu=0 bootarg が削除された → QuartzCoreを解析してfallback動作を確認
  • 脱獄端末で QuartzCore をパッチし、ソフトウェアレンダリングが動作することを確認(遅いが可能)
  • Metalプロキシ案も実験したが、Objective-CおよびAPIの複雑さにより中断

フレームバッファとIOSurfaceのデバッグ

  • t8030 QEMUにはフレームバッファ実装がない → ChefKissInc/QEMUAppleSilicon フォークを使用
  • 初期ブート時にはAppleロゴと進行表示が見えたが、その後は黒画面 → デバッグ開始
  • IOMFB kextの解析結果、2つのモードが存在:
    • 固定アドレスのフレームバッファ(初期表示用)
    • DMAベースのマルチプレーン構成
  • システム起動中はDMAベースのモードが使われる → QEMUのトレースでカーネルレジスタ設定を確認
  • しかし依然として画面には何も表示されなかった

アドレスランダム化の無効化

  • カーネルのアドレスランダム化はボード初期化コードで無効化できる
  • ユーザー空間のランダム化は _load_machfile をパッチして無効化
  • dyldキャッシュはすべての動的ライブラリを含む巨大なバイナリ → ブート時に固定アドレスへロードされる
  • Cツールを作成してdlopen後に _dyld_* 関数でアドレスを確認
  • GDBで dyld ライブラリをデバッグ可能にした → 特に IOMFBSpringBoardQuartzCore に注目

USBログへのアクセスとlockdowndの回避

  • 実機では idevicesyslog でシステムログを収集できる → USB認証が必要
  • lockdowndは鍵の保存にSEPが必要なkeybagを使用 → エミュレータには存在しない
  • 既存関数の位置にシェルコードを挿入し、鍵ファイルから直接ロードするようにした
  • USB接続されたQEMU間で鍵認証の回避に成功 → ログ収集が可能に
  • QuartzCoreが正常に初期化され、ソフトウェアレンダリングを使っていることを確認

PAC(Pointer Authentication)の回避

  • backboardd の修正中にPACエラーが発生 → ARMv8.3で導入されたセキュリティ機能
  • PAC命令をNOPに置き換える方式は侵襲的すぎる
  • PAC命令は互換モードでコンパイル可能 → QEMUでPACを無視すれば実行できる
  • QEMU 7ではPAC回避不可 → QEMU 8.2.1へ移行
  • Apple専用命令やGL例外レベルなど、多数のQEMUカスタムコードの移植が必要
  • 結果としてQEMU 8でiOSのブートに成功し、PACの無力化も可能になった

backboardd とグラフィック出力の確認

  • backboardd は動作しているが画面表示がない → 複数の原因が考えられる
  • DMAメモリをダンプしても有意な出力はなかった
  • iosurface_lock でアドレスを確認してフレームをダンプしたが、圧縮された形でGPUへ渡されているようだった
  • iPhone X(t8015)では非圧縮出力を確認 → QEMUのDTBを修正し、chip-id を t8030 → t8015 に変更
  • 結果としてブート後にAppleロゴが表示された

進行バーとシステムエラーの追跡

  • ロゴの後に白い進行バーが表示 → 90%で停止
  • ログ解析により mobileactivationdSpringBoardFoundation の問題を発見 → パッチ後にUIが変化
  • 進行停止問題を解決するため、多数のシステムログ解析が必要

dyldキャッシュとユーザー空間パッチの自動化

  • カーネルと同じ方式で、ユーザー空間にもテキストベースのパッチ方式を使用
  • dyldキャッシュは2GBと大きく、修正効率が悪い → 内部ツールを改善して:
    • dyld内のオフセットを追跡
    • dd コマンドで特定位置を直接パッチ
  • カーネル署名検査の回避パッチも並行して必要

PreBoard の起動とUIの確認

  • PreBoard アプリはエラー時に表示されるシステムアプリ → 直接起動可能
  • VNCサーバーを追加し、キーボードで画面ロック解除を試行
  • アンロック後、vImage フレームワークがAMX(Apple Matrix Coprocessor)命令を使用 → QEMUは未対応
  • vImage のソフトウェアfallback経路へパッチして問題を解決
  • パッチ後、テキスト入力可能な画面の表示に成功

結論

  • SpringBoard起動直前まで到達 → 完全なUI実行はもはや時間の問題
  • カーネル、ユーザー空間、グラフィック、セキュリティ機能(PACなど)を多角的に解析し、パッチを実施
  • QEMUベースの実用的なiOSアプリのデバッグおよびテスト環境の可能性を確認

1件のコメント

 
GN⁺ 2025-04-07
Hacker Newsのコメント
  • https://github.com/devos50/qemu-ios プロジェクトが iPhone OS 3.x をサポートするまで発展してほしい。そうなれば、初期の iPhone アプリをデジタル保存のために体験できるようになる
  • https://github.com/touchHLE/touchHLE も素晴らしいが、標準アプリ以外ではパッチが必要
  • https://github.com/TrungNguyen1909/qemu-t8030/… の手順に従って実行したが、何度もクラッシュした。それでもかなりクール
  • QEMU で NumWorks N0100 と HP Prime G1 をエミュレートしたことがある。公式ファームウェアを実行できる程度には成功していた
  • このプロジェクトの面白い活用法: ハードウェアサポートの良いスマートフォンに postmarketOS をインストールし、QEMU を使って Android フォン上で iOS を起動すること。QEMU をカスタマイズして、スマートフォンのハードウェアを iOS VM に渡せるかもしれない
  • Apple ハードウェアなしで Linux システム上から Safari のテストや iOS のコンパイルができるという意味なのか気になる
  • https://github.com/ChefKissInc/QEMUAppleSilicon
  • ネットワーク接続についての言及がない。WiFi やセルラーモデムのチップセットはエミュレートしていないようだ。エミュレートされたデバイスをインターネットに接続する方法が気になる。USB 経由の Ethernet のような方法かもしれない
  • アーカイブ版: https://archive.ph/l1CwO
  • これを再現できるリポジトリがあるのか気になる
  • Apple がマルチプラットフォームの iOS 開発を受け入れるには何が必要なのか気になる