既存手法の調査
このページには、本プロジェクトが車輪の再発明をしていないことを示すため、既存の手法を記録しています。調査日:2026-10-29。
概要
ビルドごとに多態化し、Ren'Py スクリプト、すべてのアセット、エンジンを同時にカバーする、商用レベルの汎用的な Ren'Py 向け保護ツールは存在しません。この空白は現実のものです。公開されているツールはすべて攻撃側(アンパッカーとデコンパイラ)に属しており、わずかな保護の試みもプロトタイプにとどまるか、1 つの層しかカバーしていません。
Ren'Py 自体の形式の仕組みとその弱さ
.rpaアーカイブはインデックスとファイルを連結したものにすぎず、せいぜい XOR による「難読化」の鍵があるだけで、暗号化はされていない.rpycスクリプトは、Ren'Py の AST を pickle にして zlib で圧縮したもの- Ren'Py の公式ガイダンスは、難読化は気軽な閲覧を防ぐにすぎず「ある程度の技術を持つプログラマーなら容易に破れる」としている。主任開発者はアセット暗号化の要望(renpy/renpy#2546)を実現不可能としてクローズした。ゲームは実行時に自身のアセットを読み込まなければならず、アンパックに必要なものはすべてゲームと共に配布されるうえ、アセットはいずれにせよメモリや画面から取得できるためである
攻撃側のツール(保護済みビルドが無効化すべき対象)
unrpyc の難読化解除が実際に扱えるもの
以下は deobfuscate.py に基づく内容です。どのような単純な改変が無意味であるかを示すため、重要な情報です。
- スロット抽出器(順に試行):標準の
RENPY RPC2ヘッダー、ヘッダーのない旧形式(ファイル全体が 1 つの zlib ブロック)、extract_slot_headerscan(マジックが変更またはずらされている場合に 36 バイトのヘッダーパターンを走査)、extract_slot_zlibscan(ヘッダーが破壊されている場合に、チェックサムが有効な zlib の開始バイト0x78を走査して候補を展開) - 多層のペイロードデコーダー(
DECRYPTORS):最大 10 層で、各層の後に pickle の読み込みを再試行する。decrypt_zlib、decrypt_hex、decrypt_base64、decrypt_string_escape
示唆: マジックバイトの変更、ヘッダーのずらし、ペイロードの zlib/base64/hex/エスケープによるラップは、いずれも unrpyc を阻止できません。特に zlib スキャナーはヘッダーに対する小細工を無効化します。本当に無効化するには、標準の pickle/zlib 形式から完全に離れ(独自の AST 形式)、さらにクラスとフィールドのレイアウトをビルドごとに変える必要があります。そうすれば「偽の renpy モジュール」という手法は結び付ける対象を失います。
これまでの保護の試み
- ichfly/renpy-Asset-Protect:鍵を用いるローダーと付属の C 実行ファイル(AES + SHA-256)によってアセットのみを保護する。品質はプロトタイプの段階で、鍵テーブルがハードコードされ、デバッグ用のファイル書き出しも含まれる。作者はDRM ではないと明言し、この手法は容易に回避されると述べているが、何の工夫もなくそのままダンプされるよりはましだとしている
- コミュニティの言い伝え(Lemmasoft、知乎):
.rpaの名前の変更、16 進エディタによるヘッダーの編集、画像ファイル内へのスクリプトの隠蔽、エンジンが読み込むアーカイブのホワイトリスト化など。いずれも容易に回避されるか、検証されていない
公式とコミュニティの見解
- renpytom(Ren'Py の主任開発者):アセットの完全な暗号化は「不可能」であるとして機能要望をクローズした。また、エンジンや OS のアップデートでゲームが動かなくなった際に修正が難しくなるため、難読化は行わないよう勧めている
- uyjulian(コントリビューター):複雑なアーカイブ形式であっても、実行中のゲームのメモリのダンプや画面のキャプチャによって破ることができる(NinjaRipper、KrkrExtract を参照)。注入型の抽出ツールを本当に阻止するにはカーネルレベルのアンチチートが必要になる
- unrpyc のメンテナー:「いたちごっこ」であることを明確な理由として、特定のゲームの難読化解除を求める機能要望は受け付けない
この最後の点こそが RenMori の戦略上の突破口です。汎用ツールにゲームごとの対応を組み込む者がいない以上、「ビルドごとに異なる」ことはそれだけで持続的な優位性となります。
設計に反映された結論
- RPA と標準の rpyc/pickle 形式から完全に離れる:ヘッダーやエンコードの小細工はすでに
unrpycが対処している - ビルドごとの多態化が中核となる価値であり、都合のよいことにランタイムのコストがゼロであるため、パフォーマンス優先の方針に合致する
- ユーザーに誠実であること:成果は「汎用的なアンパッカーが存在せず、ゲームごとに専門家のコストがかかる」ことであり、「解析不可能」であることではない(脅威モデルを参照)
出典
- Ren'Py のアセット暗号化の要望(実現不可能としてクローズ):https://github.com/renpy/renpy/issues/2546
- Lemmasoft「Protect .rpa and .rpyc from unpackers and decompilers」:https://lemmasoft.renai.us/forums/viewtopic.php?p=389272
- 旧 Ren'Py Wiki「Obfuscating Your Game」:https://renpy.org/wiki/renpy/doc/reference/Obfuscating_Your_Game
- unrpyc:https://github.com/CensoredUsername/unrpyc(`master` の
deobfuscate.py) - rpycdec:https://github.com/cnfatal/rpycdec
- unrpa:https://pypi.org/project/unrpa/
- rpatool:https://github.com/Shizmob/rpatool
- RenPack:https://github.com/Kroste/RenPack
- RenpyEx:https://github.com/rolanfreeman6-png/RenpyEx
- ichfly/renpy-Asset-Protect:https://github.com/ichfly/renpy-Asset-Protect