
TRANSFORMERS: Forged to Fight は、トランスフォーマー世界観の中でも最もカリスマ性の高い兵士たちを操作する3D格闘ゲームです。オプティマスプライム、メガトロン、バンブルビー、ラチェット、サウンドウェーブ、グリンダーといったビッグネームが登場。そうです、あなたの読み通り。トランスフォーマーシリーズのお気に入りキャラクターたちが勢揃いします。
このパッケージには、Transformers: Forged to Fight の動作するオフラインブートと、そこに至るまでに使用したすべてのツール、パッチ、リバースエンジニアリングノートが含まれています。これは、次の、はるかに大きなステップ(つまり、ゲームのサーバー側コンテンツをゼロから再構築すること)に取り組む時間とエネルギーがある人に引き継がれることを意図しています。ここにあるものはすべて文書化されているため、私のようにゼロから始める必要はありません。
何かに手を触れる前に、このファイル全体を読んでください。特に「落とし穴」のセクションは、あなたの日数を節約してくれるでしょう。
ゲームは完全にオフラインで起動し、ライブサーバーがどこにもない状態で、実際のインタラクティブなホーム画面に到達します。ホーム画面からメニューはクラッシュすることなくナビゲートできます:基地、ボット一覧(アカウントに所有ボットが存在)、ファイトモード選択、クリスタル画面、通常のポップアップやヒント。完全なログインフローが完了し、すべてのオンラインサブシステムが接続され、初回体験とチュートリアルのゲートがクリアされます。スクリプト化されたイントロ戦闘(オプティマス vs スタースクリーム)は、バトルの読み込みを開始するまでに進み、3Dキャラクターモデルがレンダリングおよびアニメーションします。
これが難しい部分であり、解決済みです。クライアント自体がオフラインで再び生きています。
実際のゲームプレイは動作しません。ストーリーにはミッションが表示されず、戦闘は完全に読み込めません。これはバグではなく、パッチで修正できるものではありません。
Forged to Fight は完全にサーバー権限型でした。スマホのアプリは基本的にコントロール付きの画面に過ぎません。ゲームに関するほとんどすべてがアプリ内に存在していたわけではありません。すべてのミッション、すべての戦闘、すべての敵のラインナップ、ロスター全体のステータスとアビリティ、経済、およびすべてのバランスは Kabam のサーバー上に存在し、セッションごとにデバイスにストリーミングされていました。サーバーが2020年初頭にシャットダウンされたとき、そのコンテンツデータベースも一緒になくなり、私が到達できる範囲で公開またはアーカイブされることはありませんでした。
したがって、状況はきれいに二分されています。アートとオーディオは残っています。なぜなら、それらはアプリ内に同梱されているからです(re_notes/ASSET_INVENTORY.txt を参照)。すべてのキャラクターは完全な Unity アセットバンドルであり、モデル、テクスチャ、リグ、アニメーションクリップ、アニメーターコントローラー、エフェクト、オーディオが含まれています。環境、建物、UI、ポートレート、カットシーン、ダイアログもすべてそこにあります。生き残らなかったのは、ゲームにどのアセットを使用するか、それらをどのように戦闘やミッションに組み立てるか、そして各ボットの実際の数値が何であったかを教えるデータです。すべてのピースは存在します。それらをどのように組み合わせるかを知るものが残っていないだけです。それを再構築することが残っているすべての仕事です。
4つの可動部品があります。それらが連携して、未改変のゲームが Kabam と通信していると思い込ませます。
ネイティブバイナリパッチ。ゲームは Unity IL2CPP であるため、ロジックは編集可能なスクリプトファイルではなく、コンパイルされた ARM ライブラリ libil2cpp.so に存在します。patches/patch_il2cpp.py は、そのライブラリ内の6つの関数を書き換えて、死んだサーバーチェックを回避します。2つの証明書ピンパスを無効にして独自の TLS 証明書が受け入れられるようにし、ライブ設定が null であってもマネージャー登録ブロックを強制的に実行させ、ローカルデバイスセッションでログインを成功させ、通常は「ログイン失敗」ダイアログを表示するサブシステムの致命的エラーを抑制します。また、単一の依存関係エントリを再注入します(落とし穴のセクションを参照)。これにより、ランタイムフックが実際に読み込まれます。出力は libil2cpp.patched.so です。
偽の Sparx サーバー。server/fakeserver.py は Kabam のバックエンドの代わりをします。TLS 443 およびプレーン HTTP 80 で待機し、ゲームの API 呼び出しに応答します。定型応答は server/responses/ にあり、エンドポイントごとに1ファイル、メソッドとパスで命名されています(例:GET__account_data.json)。いくつかのエンドポイントはコード内で動的に応答します(ファイルからではありません)。なぜなら、ゲームがリクエストから値をエコーすることを期待しているからです(チュートリアルエンドポイントとヒーロー詳細エンドポイント)。応答のエンベロープは {"error":null,"result": ...} です。Sparx エラーペイロード内のフィールドは err と綴られており、error ではないことに注意してください。この詳細は重要であり、見逃しがちです。
ネイティブランタイムフック。tools/nativehook/ は libdothook.so をビルドします。これはゲーム起動時に読み込まれる小さなライブラリで、ゲームが読み取るすべてのデータキーをログに記録し、さらにいくつかのターゲットを絞った動作の微調整を行います。これは他のすべてを可能にしたフィードバックループです:ゲームが何を要求しているかを正確に教えてくれるため、応答を合成して検証できます。これは実行前にインストールされる純粋なバイト上書きインラインフックです。なぜなら、これの通常のツール(Frida)はエミュレータの ARM 変換レイヤーでクラッシュするからです。
実行時のデータフローは次のとおりです:ゲームが Kabam ドメインに HTTPS 呼び出しを行い、hosts ファイルがそれを PC に送信し、偽のサーバーが server/responses/ からの応答で応答し、パッチされたライブラリが証明書と応答を受け入れ、フックが読み取られた内容をログに記録します。このループが、このビルド内のすべての画面を立ち上げた方法です。
README.md このファイル
TECHNICAL_NOTES.md より深い技術リファレンス:パッチ、復元されたデータ構造、発見事項
patches/
patch_il2cpp.py 6つのネイティブパッチと依存関係の再注入
disasm_fn.py ヘルパー:オフセットで関数を逆アセンブル
find_callers.py ヘルパー:関数の呼び出し元を検索
find_str_ref.py ヘルパー:文字列への参照を検索
server/
fakeserver.py 偽の Sparx サーバー
gen_certs.sh TLS 証明書と CA を再生成(以下を参照)
setup_device.sh デバイス側のネットワークと信頼設定のリファレンス
iterate.sh クイック再起動とキャプチャループ
responses/ ゲームが呼び出すエンドポイントごとに1つの JSON ファイル
tools/
provision_ldplayer.sh エミュレータを作業状態に再プロビジョニングするワンショットスクリプト
setup_arm64.sh ツールチェーン設定ノート
decompile_targets.py Ghidra ヘッドレスデコンパイラを指定オフセットで駆動
find_xrefs.py バイナリ全体のクロスリファレンス検索
apply_labels.py IL2CPP シンボルラベルを適用
light_analyze.py 軽量静的解析ヘルパー
frida_attach.py Frida ヘルパー(参考用に保持、libnb の注意事項を参照)
frida_run.py
hook_dot.js
nativehook/
hook.c libdothook.so のソース、ランタイムフック
libdothook.so プレビルドフック、arm64
deploy.sh フックのビルドとデプロイ
relaunch_and_capture.sh ゲームを再起動してログをキャプチャ
hook/dothook.c 以前のフックバリアント、参考用
re_notes/
dump.cs 完全な IL2CPP ダンプ:ゲーム内のすべてのクラス、メソッド、フィールド
decomp_out.c 主要関数のデコンパイルされたボディ
decompile_targets.txt デコンパイルする価値のあるオフセット
ASSET_INVENTORY.txt アプリ内にすでに同梱されているアートとオーディオ
re_notes/dump.cs は、残された作業にとって最も価値のあるファイルです。これはゲームの完全な型モデルです:すべてのクラス、すべてのメソッド、そして重要なことに、クライアントがサーバーから読み取るすべてのデータフィールド。それはバックエンド API 全体の地図です。応答の形状を知る必要がある場合、答えはそこにあります。
これらは意図的に除外されています。大きいか、著作権があるか、秘密であるか、自分で生成すべきものだからです。
com.kabam.bigrobot、バージョン9.2.0)。約800 MB。自分でコピーを入手してください。パッケージ名とバージョンは TECHNICAL_NOTES.md にあります。libil2cpp.so とゲームアセット。どちらも APK から直接取り出せます。APK を解凍すると、ライブラリは lib/arm64-v8a/ の下に、アセットは assets/ の下にあります。server/gen_certs.sh を実行して独自のペアを作成し、デバイスの信頼ストアを新しい CA にポイントしてください。libil2cpp.so に対して patches/patch_il2cpp.py を実行します。re_notes/dump.cs を生成したものです。ARM 変換対応エミュレータ(LDPlayer 9が使用されました、root と書き込み可能なシステムが必要)、PC 上の Python、および上記のセクションのアイテムが必要です。
bash server/gen_certs.shpython patches/patch_il2cpp.py path/to/original/libil2cpp.so --applytools/nativehook/deploy.sh を参照。python server/fakeserver.py。エミュレータからポート443および80で到達可能である必要があります。bash tools/provision_ldplayer.sh <your-PC-LAN-IP>。エミュレータを再起動するたびに再実行してください。ログインでハングする場合は、他の何よりも先に「落とし穴」セクションの最初の項目を確認してください。
これらは私に数時間を費やさせたものです。同じ時間を費やさせないために書き留めています。
libdothook.so を参照しているかどうかです。正確なバイトとオフセットは、パッチスクリプトと TECHNICAL_NOTES.md に文書化されています。provision_ldplayer.sh を再実行する必要があります。そうしないと何も接続されません。err であり、error ではありません。間違ったものを使うと、クライアントが静かに無視するか、誤って処理する応答が生成されます。これが本当の仕事であり、大規模です。以下がその概要と開始点です。
目標は、かつてクライアントにストリーミングされていたサーバー側コンテンツを手作業で再作成することです:クエストとミッション、マップとその敵のラインナップ、各ボットのステータスとアビリティを含む完全なロスター、戦闘フォーミュラ、経済。これらはもう存在しないため、すべてをクライアントが期待する正確な形状で新規に作成する必要があります。
機能する方法は、このプロジェクトが基づいているループです。フックを接続してゲームを実行します。フックはクライアントが読み取るすべてのキーをログに記録します。クライアントが提供していないものを要求すると、何が欲しかったのかが正確にわかります。その後、適切な形状の応答を合成し、server/responses/ に配置するか、fakeserver.py の動的ハンドラに追加し、再起動してクライアントがそれを受け入れて先に進むことを確認します。繰り返します。現在のビルド内のすべての画面は、この正確な方法で立ち上げられました。re_notes/dump.cs は、実行する前に各構造の形状を教えてくれます。なぜなら、クライアントが読み取るすべてのフィールドをリストしているからです。
攻めるべき妥当な順序:
decompile_targets.py を使用)、正確なフィールドを読み取ってください。ASSET_INVENTORY.txt にリストされたバンドルに存在するため、数値とアビリティ定義のみを作成し、アセットは作成しません。TECHNICAL_NOTES.md を参照してください。規模について現実的になりなさい。ファンがシャットダウン前にライブサーバーデータを保存したゲームでさえ、プライベートサーバーを立ち上げるのは長いプロジェクトです。ここでは開始するための保存データがないため、すべての数値とすべてのアビリティは調査または再発明され、クライアントに対して検証される必要があります。本当のゲームを目指す場合、これは複数人、複数年の努力です。とはいえ、道筋はもはや謎ではありません。ブートは解決され、フィードバックループは存在し、型モデルはダンプされ、アセットは無傷です。残っているのは、非常に大量の注意深いデータ再構築であり、未知のもののさらなるリバースエンジニアリングではありません。
まず TECHNICAL_NOTES.md から始めてください。これはより深い技術リファレンスであり、正確なパッチ、復元されたデータ形状、および特定の発見事項が、この README よりも詳細に記載されています。その後、ループを実行してください。
幸運を祈ります。今やそれは本当のマシンです。ただコンテンツが再構築される必要があるだけです。
デバイスの配線。エミュレータは Kabam のドメインを PC に送信し、偽の証明書を信頼する必要があります。tools/provision_ldplayer.sh はこれを一度に行います:パッチされたライブラリとフックをプッシュし、hosts ファイルを介して Kabam のホスト名を PC の LAN アドレスにリダイレクトし、偽の CA をシステムの信頼ストアにマウントし、SELinux を緩和します。エミュレータを再起動するたびに実行してください。これらのマウントは再起動後も持続しないためです。