Files
revkit/.github/copilot-instructions.md
T

6.3 KiB
Raw Blame History

プロジェクト概要

Netflix iOS/Androidアプリのリバースエンジニアリングプロジェクト。 対象アプリが送信するHTTPリクエストの安全性を検証するため、暗号化されたリクエストボディの復号に必要な鍵・アルゴリズムを特定する。

対象アプリ

  • アプリ名: Netflix
  • Bundle ID (iOS): com.netflix.Netflix
  • Bundle ID (Android): com.netflix.mediaclient

環境構成

項目 バージョン / 値
Python 3.12(パッケージ管理: uv)
Frida 17.8.0
Objection 1.12.3

対象デバイス

デバイス OS ホスト
iPhone (Jailbroken) iOS 15.8.3 192.168.0.34
Pixel 4a (5G) / bramble Android 14 (API 34) 192.168.0.37

ドキュメント運用

保存先

ドキュメント作成を指示された場合、以下の2種類を必ず作成すること:

種別 保存先 形式
LLM向け .github/instructions/{名前}.instructions.md frontmatterに applyTo を記述し、関連ファイルパターンを指定。構造化された簡潔な形式
人間向け docs/{名前}.md 散文形式。図解にはMermaid記法を使用し、テーマは %%{init: {'theme': 'dark'}}%% を指定すること

制約

  • 1ファイルが400行を超える場合は、指示がなくてもトピック単位で分割すること
  • ファイル名はスネークケースを使用すること

主要ドキュメント一覧

LLM向けの詳細コンテキストは以下を参照すること:

  • .github/instructions/*.instructions.md — ファイルスコープ付きLLM向け指示(applyTo で適用先を指定)
  • docs/ — 人間向けドキュメント
パス 内容
docs/msl_ios.md iOS MSLプロトコルの構造・暗号スタック
docs/msl_android.md Android MSLプロトコルの構造
docs/manifest_ios.md iOSマニフェスト仕様
docs/manifest_android.md Androidマニフェスト仕様
docs/auth_flow_android.md Android認証フロー
docs/esn_android.md Android ESN仕様
docs/pxa_esn.md PXA ESN仕様

ツール使用ルール

Objection

重要: 以下の非推奨コマンド・オプションをコード生成やコマンド提案で絶対に使用しないこと。

禁止 代替 説明
explore start アプリへの接続コマンド
--gadget / -g --name / -n 対象アプリ指定オプション

正しい使用例:

objection -n "com.netflix.Netflix" start

Frida

  • コマンド実行時は必ず -H <ホストIP> を指定して対象デバイスに接続すること
    • iOS: -H 192.168.0.34
    • Android: -H 192.168.0.37
  • 実行中アプリ一覧の確認: frida-ps -H <ホストIP> -a

アーキテクチャ

目的

対象アプリの暗号化通信(MSL等)をFridaでフックし、暗号化前の平文データ・復号済みデータ・暗号鍵・IVなどを取得する。

JS / Python の役割分担

レイヤー ファイル 責務
JavaScript (Frida) hook_*.js 対象アプリのプロセス内で動作。暗号関数・API呼び出しをフックし、引数や戻り値(鍵・IV・平文・暗号文など)を @@LOG@@{json} 形式で console.log に出力する。データの加工・保存はしない。
Python (ホスト) run.py Fridaプロセスを起動・管理する。stdout から @@LOG@@ プレフィクス付きの行をパースし、ドメイン別・イベント別にJSON/バイナリファイルとして logs/ に保存する。MSL平文とHTTPリクエストの紐付け、Cookie/ヘッダの自動エクスポートも行う。

ログプロトコル

JavaScript側は以下の形式で標準出力にログを送る:

@@LOG@@{"event":"msl.aesCbcEncrypt.key","key_b64":"...","ts":"..."}
  • プレフィクス @@LOG@@ に続くJSON文字列をPython側がパースする
  • event フィールドでイベント種別を識別する
  • バイナリデータは _b64(Base64)または _hex(16進数)サフィックスのフィールドで渡す

シグナルハンドリング

run.py は SIGINT / SIGTERM を捕捉し、Fridaサブプロセスを安全に終了させる(terminate → 3秒待機 → kill)。Ctrl+C での中断時もログの集計とCookie/ヘッダのエクスポートが finally ブロックで実行される。フックスクリプト作成時は、JS側での終了処理は不要(Python側が管理する)。

コード構成

パス 役割
hook_netflix.js iOS用フックスクリプト(ObjC/C++関数のフック)
hook_netflix_android.js Android用フックスクリプト(Java/JNIメソッドのフック)
hook_msl.js MSL暗号関数の個別フック
hook_cronet.js Cronetネットワーク層のフック
hook_esn.js ESN取得用フック
hook_headers.js HTTPヘッダ/Cookie取得用フック
run.py メインランナー(iOS/Android両対応、--android フラグで切替)
run_android.sh Android用シェルラッパー
run_cronet.py Cronet用ランナー
__handlers__/ Objectionハンドラ

新しいフックを書くときの方針

  1. 静的解析で対象関数を特定する: フックを書く前に、アプリのバイナリを静的解析して目的の関数・メソッドを探すこと。推測でフック対象を決めてはならない
    • iOS: strings, nm --demangle, class-dump 等でMach-Oバイナリからシンボル・クラス・セレクタを抽出する
    • Android: jadx でAPK/DEXを逆コンパイルし、クラス名・メソッドシグネチャを確認する。ProGuardで難読化されている場合は既存フックのコメントにあるマッピングを参照する
  2. JS側: 対象関数をフックし、取得したデータを @@LOG@@{json} で出力するだけにする
  3. Python側: ログのパース・整形・保存・紐付けロジックは run.py に集約する
  4. バイナリデータはJS側でBase64または16進数に変換してからログに含める
  5. 終了処理はPython側が担うため、JS側で Script.on('unload') 等の後処理は基本不要