M4:多態化・ランチャー・プラットフォーム・Steam
M4 は、ビルドごとの差異化、クロスプラットフォームでの起動、Steam を対象とします。本プロジェクト自身のオープンコアの分割に従い、多態化エンジンとネイティブランチャーはクローズドのコンポーネントであり、Steam、Proton、Windows、Linux は、それぞれの検証に専用のハードウェアを必要とします。このページでは、オープンなベースラインがここで何を実装し検証したのか、そして何がクローズドまたはハードウェア待ちなのかを正確に示します。
ビルドごとの差異化(ベースライン、動作済み)
「1 つのゲームの解析結果を次のゲームに流用できない」という性質は、ベースラインの段階から始まっています。protect を実行するたびに、暗号学的に独立したビルドが生成されます。
- ランダムな 16 バイトの
container_idがすべての鍵導出(HKDF)のソルトとなり、これに加えてファイルごとのランダムな ID と鍵、チャンクごとのノンスが使用される - その結果、同じゲームを 2 回保護すると、異なる
container_id、異なるファイルごとの鍵、異なるコンテナが得られ、あるビルドの鍵で別のビルドを読むことはできない。これはtests/test_cli.py::test_two_builds_are_cryptographically_independentで実証されている - スクリプト鍵はコンテナ鍵から独立している(スクリプト層を参照)
ベースラインがランダム化しないもの:コンテナのバイトレイアウトとフィールドの順序、およびスクリプトの AST のクラス名で、これらは標準のまま(再暗号化のみ)です。
クローズドでの強化:多態化エンジン
クローズドのバイナリプラグインは、ビルドごとに構造、すなわちコンテナのレイアウトとコンパイル済みスクリプトのエンコードをランダム化するため、鍵を手にしていても汎用的な読み取りツールやデコンパイラを書くことはできません。このプラグインは、安定した、文書化されたプロセスインターフェースを介して renmori protect に組み込まれます(アーキテクチャとオープン部分とクローズド部分のインターフェースを参照)。オープンな CLI が統合の起点であり、プラグインがない場合はベースラインで実行します。その仕組みと実装は独自のものであり、非公開リポジトリ MewBaka/RenMori-core で管理されています。
ランチャーとプラットフォーム
ベースラインは Ren'Py の拡張機構(game/renmori.rpe)を通じて読み込まれ、通常の起動処理の中で Ren'Py に同梱された Python の内部で動作します。この仕組みはプラットフォームに依存しません。同じ .rpe が Windows、macOS、Linux、Steam Deck で動作するのは、OS ごとのランチャーのバイナリではなく、Ren'Py の Python と ctypes のみに依存しているためです。
プラットフォームごとの AES-GCM バックエンド(単一のインターフェース、container/crypto.py)は次のとおりです。
ライブラリは Python の実行ファイルと同じ場所から探され(runtime_lib_candidates、単体テスト済み)、CDLL(None) を介して読み込むことはありません。
ネイティブランチャー(クローズド、今後)
コンテナから組み込みの Python を起動し、実行時の鍵導出を行う(autorun.py に鍵を置かないようにする)プラットフォームごとのネイティブランチャーは、クローズドの堅牢化策であり、オープンな成果物ではありません。macOS では、ビルド時に自動で ad-hoc 署名が行われ(無料で、Apple Silicon では必須)、Developer ID での再署名も引き続き可能です。ベースラインは新たな実行ファイルを配布しないため、元の Ren'Py のビルドと比べて署名の負担が増えることはありません。
Steam
- Steam オーバーレイは構造上安全:オーバーレイはゲームのプロセスに DLL を注入するが、RenMori は Ren'Py のファイル読み込みをフックするだけで、プロセスへの注入や DLL インジェクションも、ホットパスでの改ざん対策も一切行わないため、オーバーレイを阻害することはあり得ない
renpy.loaderの外で読み込まれるファイルはディスク上に残る:Steam SDK はsteam_appid.txtを(ローダーを経由せず)直接読み込むため、このファイルはデフォルトで暗号化されない(DEFAULT_KEEP_ON_DISK)。同様のファイルはrenmori.tomlのkeep_on_diskで追加できる。これはtests/test_cli.py::test_steam_appid_kept_on_diskで実証されている- 実績と Steam クラウドのセーブデータは Ren'Py の Python API を経由し、この API には手を加えない。
.rmcは静的なファイルであるため、Steam のファイル検証とアップデートも通常どおり機能する - Steam DRM による二重のラップを行わない:Steam DRM は実行ファイルを書き換えるため、ネイティブランチャーの自己検査と衝突するおそれがあり、いずれにせよ保護としては弱い
Steam、Proton、Steam Deck での完全な実行は、対応するハードウェアの用意を待っている段階です。上記の性質は構造に基づくもの(フックとファイルの配置による)であり、ここでは実行テストを行っていません。
開発者向けのリリースの流れ(ビルド、保護、SteamPipe でのアップロード、どのファイルをどのデポに入れるか、起動オプション)については、Steam へのリリースを参照してください。
M4 のその他の内容
renpy.exists()(以前はディスクのみが対象)がコンテナも参照するようになったため、これを使ってファイルの有無を確認するゲームからも格納済みのファイルが見えるようになった(_install_exists_fallback)
現在の状況
macOS 上の Ren'Py 8.5.2 で検証済みのオープンなベースラインは、ビルドごとの差異化、クロスプラットフォームの .rpe の経路、Steam 向けのファイル配置と構造上のオーバーレイの安全性、renpy.exists のフォールバックです。クローズドまたはハードウェア待ちのものは、多態化エンジン、鍵を導出するネイティブランチャー、そして Windows、Linux、Steam での実機による実行です。