TOP MAP UP

AFSコンバータ・暗号化ADXについて

暗号化ADX どういう暗号化なのか

 ADXにおけるScale値に乱数によるXORがかかっている。ADXのデータ全体でなく、Scale値のみにかかっているので、デコードにおいても一回のXORを行えば良いため、速度的にも従来と変わらないと言っても差し支えない。データの形式にフィットしたナイスな暗号化であると言える。
 乱数は現在までの調査によると、測定可能な範囲で周期があり(要するに結構短い)、反転等を使用した算術乱数であると想定されるが、ライブラリの対応次第によっては固定テーブルによる乱数等も出現するかもしれない(どうやら乱数生成その物がライブラリ内部で行われているように感じる)注意点としてはソフト毎に全く異なった乱数をかけれるので、その都度解析作業を行う必要がある

法的な問題

 ここで提供する解析手法は「乱数生成式」その物を暴露するものでなく(つまりコードそのものの著作権的な部分には触れない)、「乱数テーブル」その物も暴露しない(求められる乱数テーブルはどこまで逝っても性質的に「もっとも確かそうな値」でしかない)
 データその物から数値を解析するので、プロテクト解除とは言い切れない(仮に完璧な解除が出来たとしてもそれは偶然でしかない)

解析手法

 参考までにリオパラダイスの曲を、実験対象として提示する。暗号化がかかったままデコードしたファイル。これはノイズで大音量で聞くと耳やオーディオ機器にダメージを与えるかもしれないので注意

 まずは暗号化されたADXから暗号化されているScale値を抜き出す(以降これをSCLファイルと呼ぶ)
 (コマンドラインは afs /as ????.adx
 これらのScale値は基本的な性質として
  波形の振幅を表現する値であるため、上位ビットは波長が長く、下位ビットは波長が短くなる。
  また上位ビットはゼロである確率が高く、曲の先頭付近は無音状態がある場合が多いので、下位ビットまでゼロである確立が高い。
  曲の長さに合わせて様々なサイズで出力されているが、実際には一定周期になっているはず

 以上の性質より
 ビットサーチによりSCLファイルの周期を割り出す(この周期は一番大きいものを使うべき)
 (コマンドラインは afs /sb /sk /sl???? ????.scl ビット反転も探すなら/sbを/snに変える)
 このビットサーチは周期を割り出すだけでなく、どのビットがどことどのくらい一致したのかという情報も同時に保持し、ビットサーチにおいて一致したものは「確実な値」として記録される(であるので十分な一致長を指定しないと、ノイズが紛れ込む可能性がある。逆に言えば、どこまでの一致長であれば「偶然同じ」を排除できるかがポイントになると思われる)注意点としては、一致した範囲の両端の多少の範囲は偶然一致してしまった、という可能性を含んでいるということだ。このツールではこういった部分も「確実な値」として扱っている(本来ならば窓関数の様な物を導入するのが良いだろう)

 ビットサーチを行ったSCLファイルは更に新しく作成される(これらには一致情報などが含まれる)
 これらのSCLファイルを元に多数決を行う(この時に最初に割り出した周期を指定する。これによりSCLファイルの縮小化が行われる)
 多数決は前述のような「確実な値」は、そのまま確実であると判断して多数決を行わずに結果として採用する。その他のどちらか良くわからない値に限って、複数のSCLファイルの値を用いて0/1に投票を行い多数決を行う
 本来は多数決のよう、複数ファイルの情報を統合して、ノイズの分散化(これは逆に言えばノイズを取り込む事にもなる)で、お茶を濁す前に、もっと確からしい値を推論する手法があるのかもしれないが、それがツールとして組み込みにくいファクターもある(論理的に成立していても、処理の仕方として汎用性に乏しいため、ADXの解析手法として主流であるかは懐疑的な為)ソース付きでリリースしているので、そういったカスタムの重み付けを行った物を各自製作して欲しい。

 以上のような処理を経て生成したSCLファイル(非常に巨大なので注意)を使って暗号化を解きデコードしたもの(まだ多少ノイズがある)である

 ちなみに以上の解析手法は、暗号化テーブルが算術圧縮等による、いわゆる規則性の無い優秀な乱数表から来る物であっても有効な手法である(確率的な手法しか使っていないので)
 しかし参考例で挙げているリオパラでは、実はビット毎に規則的な性質を持っている事が、事前の目視観察で判明していた。また、今回のビットサーチの結果などから、bit0/15は全て0、bit1は周期が0x8000で後半半分は前半半分のNOT値である、bit2以降はbit Nは周期がbit N-1の半分である、といった事も判明した。
 以上の規則的性質から今回特別に(面倒なのでw)AFSコンバータの方にScale値をゼロクリア/NOT Shadow/Shadowを行うPS2リオパラダイスのスペシャルルーチンを組み込んである。以上の処理を行い、暗号化を解きデコードしたもの(暗号完全解除)である。またツールの実際の使い方の参考として、リオパラダイス向けのバッチファイルを示す

070815
 まくちゃんから指摘があり「音割れが発生している」との事だったので、係数0(通称ベースボリューム)を調整するオプションを追加した。
 ちなみにこのベースボリュームだが、今までは0x4000を使用していた。これまで問題が発生してなかったのは、もともと収録されているデータが上限値(0x8000)を超えなかったためである。しかし今回のリオパラでは超えてしまっているようなので、論理的に超えない値を計算で算出してみた。
 まず係数1/2はそれぞれ29336,13136である。これらを最終的にベースボリュームも含んで0x4000で割る。結果的に割った値が0x8000を超えなければ論理上は音割れは発生しない。で、0x8000を超えないためには、ベースボリュームも含んだ係数の総計が2を超えなければ良いはずなので、この値を求めると、約0x1e49(7753)となる(上記解除データは差し替え済み)

 注意点として断っておくが、リオパラダイスにおいてはこういった規則的な暗号化テーブルであったが、他のソフトでもそうであるとは限らない。しかしPantasy Star Universeも規則的暗号化テーブルであったので、PS2のCPUパワーやADXの性質を考えれば、規則的テーブルが採用される可能性は高いと思われる。

080317
 ゲームラボ4月号にXBOX360アイドルマスターLove for Youのデータが暗号化がかかっている、との記事が載っていた。
 (個人的には当然俺のこのツールを使っても暗号化が解けないから、記事でも「解けた」と書いてない物と思っていた)
 が、実際には簡単に解く事が出来た。

 今回検証に伴いいくつかの変更を加えた。
  AIXをADXにスプリットする機能
  ADXのループの処理を内部的に、明示的に指定が無い限りは行わない
  SCLファイルのスペシャルルーチンとしてアイマスL4Uの物を追加(処理概要はリオパラと同じ)
 以上の変更により、アイマスL4Uでも暗号化を解除できた事を報告しておく。

コマンド書式

AFS [option] [target file]

[option]
/al[ループ回数]ADXファイルにループ情報がある場合に、ループ回数の指定
/afADXファイルにループ情報がある場合に、ループ後、再度ループに入りつつ4秒間でフェードアウトの指定
/fn[タイプ]AFSの保持するファイル名情報を強制的に指定する
0:ファイル名を無視する(ナンバリングによる出力)
1:(old type) 一番最初のアイテムの前にファイル名のテーブルへのアドレス
2:(new type) 一番最後のアイテムがファイル名のテーブル
/bv[ベースボリューム]ADXデコードに用いるベースボリュームの指定(0x4000-0x0000、デフォルト0x1e49)
/asADXファイルよりScale値等を書き出したSCLファイルを作成
/sb対象のSCLファイルをビットサーチする
/sn対象のSCLファイルをNOTでビットサーチする
/skビットサーチにおいてスキップモードの指定 *
/sl[長さ]ビットサーチにおける一致長の指定。16進数で指定 *
/ss[位置]ビットサーチにおけるサーチ開始ビットの指定。16進数で指定
/se[位置]ビットサーチにおけるサーチ終了ビットの指定。16進数で指定
/sv対象のSCLファイルで多数決を行う。SCLファイルは複数指定化
/sc[長さ]SCL多数決、ADX暗号解除に使用するSCLのサイクル長さの指定。16進数で指定
/ad[パス]ADX暗号解除に使用するSCLファイルの指定。デフォルトはdefault.scl
/soSCLファイル出力時、通常addr並びで出力する所を、bit並びで出力する
  
/zrADX変換時にPS2リオパラダイスのスペシャルルーチンを発動する
/ziADX変換時にXBOX360アイドルマスター Love For Youのスペシャルルーチンを発動する



その他

実行にはMicrosoft Visual C++ 2008 再頒布可能パッケージ (x86)が必要(OpenMPで使用)
最新バージョン AFS_r080317.zip
CRIのミドルウェアADX/AFS/ROFS等についての情報