mirror of
https://github.com/qtmleap/revkit.git
synced 2026-09-28 14:01:50 +02:00
chore: prepare for commit message generation without code changes
This commit is contained in:
@@ -0,0 +1,44 @@
|
||||
---
|
||||
applyTo: 'hook_netflix_android.js,hook_msl.js,run_android.sh,docs/auth_flow_android*.md'
|
||||
---
|
||||
|
||||
## Android 認証フロー (LLM 向け)
|
||||
|
||||
### ドキュメント構成
|
||||
|
||||
| ファイル | 内容 |
|
||||
|---|---|
|
||||
| `docs/auth_flow_android.md` | フロー概要・Mermaid 図・鍵交換・Cookie フロー・ProxyESN ライフサイクル・セキュリティ観察 |
|
||||
| `docs/auth_flow_android_api.md` | 全 API のリクエスト/レスポンス詳細 (Header/Cookie/Body 表)・Persisted Query 一覧・完全タイムライン |
|
||||
|
||||
### 認証フロー要約
|
||||
|
||||
1. **Phase 0:** `ProxyEsn.$init` で PXA ESN の TTL チェック。期限切れなら再取得フラグ ON
|
||||
2. **Phase 1:** 7 リクエストを並列送信 (appboot, getProxyEsn, aleProvision#1, RenewSSOToken, CurrentCountryQuery, Interstitial×2)
|
||||
3. **Phase 2:** レスポンス受信。CurrentCountryQuery で `NetflixId`/`SecureNetflixId` Cookie 発行、appboot で `nfvdid` Cookie 更新
|
||||
4. **Phase 3:** AccountQuery, aleProvision#2 (→PXA ESN 確定), PromoProfileGateVideoDataQuery
|
||||
5. **Phase 4:** 約 30 秒後に FetchConfigData, AccountQuery#2
|
||||
|
||||
### エンドポイント
|
||||
|
||||
| 略称 | ホスト | 用途 |
|
||||
|---|---|---|
|
||||
| appboot | `android14.appboot.netflix.com` | デバイス登録 |
|
||||
| prod.ftl | `android14.prod.ftl.netflix.com` | MSL API + non-MSL GraphQL |
|
||||
| prod.cloud | `android14.prod.cloud.netflix.com` | MSL GraphQL |
|
||||
|
||||
### 認証方式の二重構造
|
||||
|
||||
- **MSL API** (`prod.cloud`, `prod.ftl` の MSL エンドポイント): Master Token + User Auth Data で認証。Cookie 不要
|
||||
- **Non-MSL GraphQL** (`prod.ftl/graphql`): `NetflixId` / `SecureNetflixId` Cookie で認証
|
||||
|
||||
### 鍵交換
|
||||
|
||||
- アルゴリズム: RSA-OAEP-256 (鍵交換) + A128GCM (セッション暗号化)
|
||||
- aleProvision は 2 回呼ばれる。#1 は起動直後、#2 は getProxyEsn レスポンス後
|
||||
- 同一 RSA-2048 公開鍵を使用。サーバーが新セッション鍵を発行
|
||||
|
||||
### Frida フック固有の注意
|
||||
|
||||
- `hook_msl.js` が `ProxyEsn.$init` で `expired=true` を強制。通常は TTL が有効ならキャッシュ使用
|
||||
- キャプチャ内の PXA ESN 再取得は Frida による強制失効の結果
|
||||
@@ -0,0 +1,54 @@
|
||||
---
|
||||
applyTo: 'ipa_extracted/**'
|
||||
---
|
||||
|
||||
## MSL 解析手順 (LLM 向け)
|
||||
|
||||
### 静的解析
|
||||
|
||||
1. IPA を展開: `unzip -o Netflix-15.48.1.ipa -d ipa_extracted/`
|
||||
2. MSL バイナリ: `ipa_extracted/Payload/Argo.app/Frameworks/MslClient.framework/MslClient` (arm64 Mach-O)
|
||||
3. ObjC クラス抽出: `strings MslClient | grep -E '^\+\[|^\-\[' | sed 's/\[//;s/ .*//' | sort -u`
|
||||
4. C++ シンボル抽出: `nm --demangle MslClient | grep 'netflix.*msl'`
|
||||
5. JSON フィールド名・定数: `strings MslClient | grep -E '^(mastertoken|headerdata|payloadchunk|scheme|...)$'`
|
||||
|
||||
### 動的解析 (Frida)
|
||||
|
||||
`hook_netflix.js` を Frida Gadget 注入済み IPA で実行。`run.py` が `@@LOG@@{json}` をパースし `logs/{date}/{domain}/` に保存。
|
||||
|
||||
**Hook 関数と目的:**
|
||||
|
||||
| 関数 | Hook 対象 | 取得データ |
|
||||
|---|---|---|
|
||||
| `hookSSLPinning()` | `-[* URLSession:didReceiveChallenge:completionHandler:]` (NF/Netflix/Osprey) | SSL pinning 回避 |
|
||||
| `hookSSL()` (無効) | `SSL_write` / `SSL_read` (libboringssl) | TLS 平文 (MSL 暗号文のまま) |
|
||||
| `hookMSL()` | `IosMslClient -sendAPIRequest:extraHeaders:params:userAuthData:requestOptions:callback:` | **暗号化前の API パス (args[2]) とパラメータ (args[4])** |
|
||||
| `hookMSL()` | `IosMdxCryptoContext -encrypt:` / `-decrypt:` | MDX 暗号化前後のデータ |
|
||||
| `hookObjCTrace()` | `+[NSURL URLWithString:]` / `-[NSMutableURLRequest setHTTPBody:]` | URL と HTTP ボディ |
|
||||
| `hookCrypto()` (無効) | `CCCrypt` / `SecKeyEncrypt` / `SecKeyRawSign` | CommonCrypto/Security 暗号処理 |
|
||||
| `hookMslCrypto()` | `aesCbcEncrypt` / `aesCbcDecrypt` (MslClient) | AES-CBC 鍵・IV・平文・暗号文 |
|
||||
| `hookMslCrypto()` | `signHmacSha256` (MslClient) | HMAC 鍵・署名対象・署名値 |
|
||||
| `hookMslCrypto()` | `aesKwUnwrap` (MslClient) | KEK・ラップ鍵 → セッション鍵 |
|
||||
| `hookMslCrypto()` | `dhComputeSharedSecret` (MslClient) | DH 秘密鍵・公開鍵・素数 → 共有鍵 |
|
||||
| `hookMslCrypto()` | `rsaEncrypt` / `rsaDecrypt` (MslClient) | RSA 入出力 |
|
||||
|
||||
**C++ 引数の読み方:** `std::vector<uint8_t>` は `+0x00: __begin_` (ptr), `+0x08: __end_` (ptr)。size = end - begin。
|
||||
|
||||
**ObjC args オフセット:** args[0]=self, args[1]=_cmd, args[2]~ が実引数。
|
||||
|
||||
### ログイベント種別
|
||||
|
||||
| event | 内容 |
|
||||
|---|---|
|
||||
| `msl.api` | MSL API リクエスト (domain, url, params) |
|
||||
| `msl.encrypt.input` / `msl.decrypt.output` | MDX 暗号化/復号データ |
|
||||
| `msl.aesCbcEncrypt.*` / `msl.aesCbcDecrypt.*` | AES-CBC の key, iv, plaintext, ciphertext |
|
||||
| `msl.hmacSha256.*` | HMAC の key, data, signature |
|
||||
| `msl.aesKwUnwrap.*` | AES-KW の kek, wrappedKey, unwrappedKey |
|
||||
| `msl.dh.*` | DH の privKey, pubKey, prime, sharedSecret |
|
||||
| `url` | URL アクセス |
|
||||
| `http.request` | HTTP リクエスト (method, url, content_type, body) |
|
||||
|
||||
### 詳細ドキュメント
|
||||
|
||||
MSL プロトコルの構造・暗号スタック・クラス構成の詳細は `docs/msl.md` を参照。
|
||||
Reference in New Issue
Block a user