最近相次いで見つかっているPSPのセーブデータexploitですが、Wagic, Magic the Gathering, and PSP homebrewsでwololo氏が次のステップとなるバイナリーローダーの作り方の記事を掲載していました。【情報源:Wagic, Magic the Gathering, and PSP homebrews】
長文に付き、文字数制限のため翻訳のみでお伝えします。
時間がなくて翻訳になかなか取りかかれずwololo氏が記事を書いてからちょっと時間が経過してしまいましたが、内容としては時間と共に陳腐化するものでは全くないので非常に参考になると思います。
バイナリーローダーの作成GripshiftとMOHH exploitから学んだので、今はバイナリーローダーの作成方法の簡単なガイドなら作れると思います。
この記事について
PSPでHomebrewを実行するための最初のステップはユーザーモードexploitを発見することです。これはゲームでのバッファーオーバーフローや画像を操作するといったテクニックを利用してPSPのRAMをコントロールすることになります。
こうした脆弱性を見つけて、値が可変するレジスタ$raをフルコントロールします。次のステップはその実証となります。バイナリーローダーを作るにあたり基本的な考え方は、記述したコードからメモリースティックに置いたファイルにある別のコードを読み込み実行させるということになります。
バイナリーローダーの作成は方法さえわかってしまえばそんなに複雑ではありませんが、どこかに情報が集まっている訳ではないためできるかどうかは知識の有無に依存してしまいます。
ということでこちらです警告: 私自身最近になってようやくその方法を知ったばかりです。 ですからこれから書く方法は最良の方法とは言えないかもしれません。MIPS(CPUアーキテクチャ)のように自分でも理解していない部分はおもいっきり流してます。そうそう、Makefileは行けそうな時にはRubyでスクリプトを記述しました。ネットに書いてあることはすべて本当だとは思わない程度に読んでくださいね。
このガイドでは皆さんが既に$raの値を自由に変えることならばできるという前提で書きます。ゲームのセーブデータを例にあげてみましょう。XMBでの脆弱性を見つけた場合だと少しやり方が変わりますが、主要な所は同じです。PSPLinkの使い方も知っているものとします。HEXエディタの使い方やCやMIPSを扱うに当たっての言語の記述の仕方、基本的なMakefileの大まかな知識、そしてHomebrewを作りたいという気持ちも既にお持ちだとの前提です
目次
セーブデータexploitを使ってバイナリーローダーを作成するためのステップは以下です:1.ジャンプする場所を探す
2.インポートするファンクションを探す
3.バイナリーローダーをコンパイルする
4.バイナリーローダーをセーブデータに書き込む
5.ゲームに適用するSDK(開発キット)を作成する
6.動作を実証するためのバイナリーファイルを作成する(Hello Worldなど)
7.セーブデータを暗号化し直すジャンプする場所を探す
PSPLinkを起動させ、いつものやっているようにゲームをクラッシュさせます。そのまま次のステップを実行していきます。$raのコントロールができたら、バイナリーローダーのコードを入れたいアドレスにジャンプさせるようにします。原則としてコードはセーブデータの中に書きますので、セーブデータがRAMのどこからどこまでに入っているかは知っておく必要があります。当然セーブデータとRAMを見て比較しなければなりません。クラッシュした後にRAMをダンプするにはPSPLinkでsavemem 0x08800000 20000000 memdump.binと入力してください。これによりPCにmemdump.binという約20MBのファイルが保存されます。
セーブデータの中の分かりやすい部分をまず探してください。同じ文字や数字が続いている部分が分かりやすいでしょう。その部分と同じ部分をダンプしたデータの中から探します(もちろんHEXエディタを使います)。下の画像ではダンプデータが左でセーブデータが右になります。
ダンプデータでセーブデータと同じ部分を見つけることができればジャンプしたいアドレスを知ることができ、セーブデータのどこにコードを書けば良いのかが分かります。この例の場合見つけたパターンはセーブデータの場合0x43F0から始まっていて、それがダンプデータでは0x32C3E0になっています。実際にダンプを開始したアドレスは0x08800000からなのでRAM上での実アドレスは0x8800000 + 0x32C3E0 (=0x08B2C3E0)ということになります。PSPLinkがまだ開いていたらmemdump 0x08B2C3E0 20と入力してメモリダンプしてみれば先ほどのパターンが出てくるかを確認できます(アドレスの部分は自分で決めたアドレスにしてくださいね。もちろん。)
選んだセーブデータ内の数百バイト以上あるエリアのパターンと全く同じパターンがあるという、ジャンプさせたい場所は正確に知りたいでしょう。そのエリアでセーブデータとダンプデータに違いがあった場合、それはセーブデータブロックがそのエリアで完全に読み込まれなかったということになりコードを書くことがより困難になります(コードがRAM内に散乱するよりも1ヶ所にまとめたいでしょう)
ということで第一ステップとしては: ジャンプするに相応しい場所(0x08B2C3E0)を探してSDDATA.BIN(0x43F0から)にバイナリーローダーを入れ込むことになります。インポートするファンクションを探す
ここからはかなり難しそうなところへ踏み込みます。かなり本格的な知識が必要なように感じますが、実際にはそれほどでもありません。その理由はつまり、良いツールがすでにあるからです。
Homebrewのコードを書くときには、PSPSDKのファンクションを呼び出します。ただしゲームを利用するexploitの場合にはRAM内のどこでファンクションを呼び出すのかがあらかじめ分かりません。そのためきちんと探し出してリダイレクトしてやる必要があります。
ではゲームの場合で考えてみましょう。ゲームからEBOOT.BINを抜き出して復号化するとします。EBOOT.BINはゲームのISOファイル内にあるのでまずそのISOファイルを用意しなければなりません。ゲームがUMDだった場合、カスタムファームウェアであればISOファイルに変換することは簡単です。どのカスタムファームウェアでもUSB Driveオプションがついていますので問題ありません。(ゲームがPSNで購入したものだった場合にはNPDecryptorでISOファイルに変換できます)。
まもすけ注:NPDecryptorは著作権を侵害しているという理由で現在ネット上からほとんど削除されてしまっています。ほとんどの場合、EBOOT.BINは暗号化されているのでprxdecrypterを使ってさらに復号してやる必要があります。
一度EBOOT.BINを復号化してしまえば、prxtoolを使ってそこから情報を抜き出せます。コマンドは以下です:prxtool -f EBOOT.BIN
これによってゲームに使われている個々のファンクションの実アドレスが分かります。Homebrewやバイナリーローダーで使えるファンクションはこのようになっています。
ファンクション名に対応して16進数の値の後にライブラリの名称があることが分かるでしょう。ここから、その関連性が分かるだけでなくNIDSライブラリ/ファンクション名の関連付けが分かるxmlファイルも入手できます。こういったxmlファイルはsilversprings氏(Lan.st管理人)のサイト(http://silverspring.lan.st/)でも入手可能です。
xml nidsファイルが手に入ったら、次のようにコマンドを入力してください。prxtool -f -n yourfile.xml EBOOT.BIN
更に分かりやすいものが出てくるでしょう。:)
この結果はどこかへ保存しておいてください!
もしprxtoolにファイルはprxではないと言われたら、どこかの復号化で失敗しているか、違うEBOOT.BINを使ったか(ISOファイル内にはダミーのEBOOT.BINが複数あり)の可能性が大です。
この記事はPSPのexploitでBinary Loaderを作ろう 第2部へ続きます。