Loader)へ移植するの3つです。この分野ではHBLプロジェクトメンバーであるwololo氏が古くからexploitに関する情報をブログで紹介してくれており、私も何度か翻訳して日本語で紹介してきました。その結果日本版ゲームで複数のexploitが見つかっていますが、今回はそれらのチュートリアルを再編集しまとめてみました。exploitを発見したら、是非GameGazフォーラムに投稿して、日本でのPSPシーン盛り上げに一役買ってくださいね。新たなexploitにHBLを移植する第1章は、実は過去に翻訳していません。wololo氏が記事を書いたのは1年半以上前でしたのでかなり内容をアレンジしています。翻訳とは言い難いです。第2章は大人のためのゲーム講座の記事を再編集したものです。第3章はwololo氏が最近投稿した記事ですので初翻訳となります。PSP】この記事は、exploitに成り得る脆弱性なのか単なるクラッシュなのかを切り分けるためのチュートリアル記事です。PSPでのセーブデータexploitの見つけ方のチュートリアルでもあります。セーブデータを読み込んだPSPをクラッシュさせるのはPSPのexploitへの第一歩であることは間違いありませんが、クラッシュ=exploitではありません。クラッシュだけですべてを公開することはソニーに対策をお願いし、より強固なファームウェアへの成長を促していることになります。最近はexploitとして使っているゲーム名を公開しないことが一般的になっています。何らかの結果(HENやHBLなど)へ繋がる前に公開することも強固なファームウェアへの成長を促しているに過ぎないため現在ではしてはいけないこととして扱われています。World”という文字を表示する自作コード起動に成功しただけですので実用性には欠けると言わざるを得ません。h.binの形でコンパイルしたHomebrewであれば起動しますが、EBOOT.PBPとして利用されているPSPのHomebrewの起動はできません。spartaaaaaa方式”を利用しています。これはセーブデータの名前の部分に続けて”a”のような文字を続けて入れたセーブデータを作成しクラッシュを引き起こすことで脆弱性を探す方式です。プレーヤーが最初のゲーム起動時に入力する名前の部分を脆弱性を探す際に利用するのはPSPが確実に読み込むデータでありセーブデータ内のどこに格納されているのかが分かりやすいという理由からです。理論的には名前の部分でなくとも確実に読み込むと分かっているデータエリアであれば構わないのですが、チュートリアルとしてはやはり簡単な名前の部分を使う前提でお話しします。Worldを公開しましたが、私はハッカーと呼ばれる人種ではありませんし、ましてやプログラマーでもありません。そのため表現として不適切な部分があるとは思いますが御了承下さい。この記事を読むにあたり、基本的なプログラミングについての概念、特に変数やアドレス、配列といった知識は知っておいた方が良いと思います。コマンドラインについても扱い方を知っておいた方が良いでしょう。アセンブラの知識はあるに越したことがありませんが絶対に必要なものでもありませんが、アセンブラの知識はあった方がより理解が深まるでしょう。セーブデータexploitの基礎セーブデータexploitのほとんどは”バッファーオーバーフロー”という脆弱性を利用しています。バッファーオーバーフローとは、プログラムが確保したメモリサイズを越えて文字列が入力されると領域があふれて(オーバーフロー)しまい、予期しない動作が起きることを言います。バッファオーバーフローを利用した(ソニーの見地からは不正な)アクセスに成功すると、バッファーオーバーフローを引き起こしたプログラムが持っているアクセス権の範囲で任意の動作を行なうことが可能となります。10個分の配列を用意してあるところに11個のデータを格納しようとすると1個分あふれてしまいます。その結果どうなるかと言うと、メモリー内の予期せぬところのどこかにそのあふれた1個分のデータが格納されることになり、詳しくは後で述べますが面白い結果を生むことがあるのです。バッファーオーバーフローについてはこちらの記事が分かりやすいでしょう。バッファーオーバーフローを引き起こすための最も一般的な方法は(セーブデータ内の話として進めますが、必ずしもセーブデータでないとできないということはありません)非常に長い文字列をセーブデータ内のどこかに仕込む方法です。文字列は文字の集まりなので仕込むのは簡単です。プレーヤー名は一般的には復号化されたセーブデータファイルであれば、そのファイル内のどこにあるのかを探すのは非常に簡単です。ゲーム中に入手したゴールドメダルの数が格納されている場所を探すのは簡単なことではありませんが、名前であればHEXエディタにある検索機能を使えば非常に簡単です。名前の場合文字コードを考えなければならない日本語(2バイト文字)にするよりはアルファベットを用いた1バイト文字のほうが検索が簡単になります(「まもすけ」よりも「mamosuke」の方が簡単です)。バッファーオーバーフローを引き起こす目的でプレイヤー名をゲームで入力しセーブデータを作成する場合は、ひらがなしか受け付けないなどの特殊な場合を除いてプレーヤー名をアルファベットで入力しておくことをお勧めします。PSPでプレイヤー名を入力する際何文字目かでそれ以上入力できないようになっている場合がほとんどですが、できる限り限界まで文字を入れておいた方が検索の精度が上がります。名前の文字列がセーブデータのどこにあるのかを見つけたら、次のステップはそこに非常に長い文字列を入れてみることです。spartaaaaaaa・・・」と上書きして入力しています。PORTABLE2』の場合は「mamosuke」という文字列を見つけたら、それに続けて「aaaaa・・・」と「a」を連続して入力しました。上書き、追記どちらでも構いませんが、文字列はHEXエディタで単純に挿入するとその分セーブデータ全体のファイルサイズが大きくなってしまいますので(破損データになる恐れがあります)1バイト分「a」を入れる場合は元のセーブデータに必ず上書きするようにしてください。ここでは『Gripshift』に倣って「aaa・・・」と入力すると説明しましたが、必ずしも「a」である必要はありません。「A」でも「b」でも「c」でも「Z」でも構いません。HEXエディタには16進数のコードのみで表記される部分と、それをアルファベット文字で表示する部分があるのが一般的です。文字表示部分に「a」と入れれば16進数で表示される部分に「61」と表示されます。同様に「A」は「61」、「b」は「42」、「c」は「63」、「Z」は「5A」です。これはコンピュータ上で文字を利用するために各文字に割り当てられるバイト表現(文字コード)により決まっているためで、文字コードは複数種ありますが簡単なアルファベットであればほとんどが上記のように表示されます。自分が使いやすいと思う文字を1つ決めて、それを名前の部分に連続文字列として入力します。この際、連続して同じ文字にするのを忘れないでください。後に説明しますが、PSPLinkでレジスタにその文字のコードが入っていることの確認がより簡単になります。セーブデータのプレイヤー名に文字を入れると言っても、実際ゲーム中の入力画面で行えるわけではありません。PORTABLE2』の場合はUCJS10075)にありますが、暗号化されているため直接バイナリエディタで開いてもプレイヤー名は見つかりません。セーブデータを編集する時には一旦復号化をして、編集した後にもう一度暗号化をしてやる必要があります。exploitを探す用途の場合にはsavegame-deemerという復号化/暗号化を自動でしてくれるプラグインが非常に便利です。このプラグインを有効にしておけばあとは何も意識することなくセーブデータの暗号化/復合化が可能になります。暗号化したセーブデータはSAVEDATAフォルダに、復号化したセーブデータはSAVEPLAINに自動保存してくれます。復号化したセーブデータに、先ほど述べた「aaa・・・」などを入力してゲームをプレイしてセーブデータを読み込んだ後クラッシュするかどうかをみてください。savegame-deemerを有効にしておけば復号化したSAVEPLAINフォルダ内の該当ゲームフォルダにあるセーブデータ(ファイル名はSDDATA.BIN)を読み込んでくれますので途中で暗号化する必要はありません。一度やってみると分かりますが、殆どの場合ゲームはクラッシュしないか、セーブデータが壊れていると表示されてしまうかのどちらかです。「aaa・・・」と「a」を何文字(何バイト)入れるかにより挙動は異なります。PORTABLE2』の場合はなんと、プレーヤー名の頭のアドレスから数えて1200バイトくらい入れてはじめてクラッシュしました(名前が入っているアドレスから1108バイト目が$raに格納されるというとんでもないものです。名前格納アドレスとは全く関係ないのかもしれません。PORTABLE2』のようにPatapon2とは2桁異なるものまで様々です。ここで大切なのは”どこで諦めるのか”の判断です。しつこく1バイトづつ「a」を入れていくといつかクラッシュするかもしれませんし、その前にデータ破損してしまうかもしれません。あるのかないのか分からない脆弱性に対してしつこく調査を続けて行くのは経験上かなり無駄な労力を消費します。PORTABLE2』の場合、数百バイト程度までデータを入れた段階で諦めてしまう可能性が非常に高いです。PORTABLE2』でexploitを発見できたのであり、普通なら誰もが諦めてしまうことでしょう。データを改造してゲームを起動して動作確認、といったサイクルをひたすら繰り返しますので簡単なことではありません。”これ以上はめんどくさい”と思ったところで一旦線を引き、そのゲームにはexploitが存在しなかったことにして他のゲームで別のクラッシュを探した方が懸命です。改造したセーブデータでPSPがクラッシュするのを発見したら、そのゲームではプログラマーがきちんとクラッシュしないようプログラムを組まなかったということになります。この時点では単なるバグの可能性があるためクラッシュ=バッファーオーバーフローを利用したexploitではないのです。これがexploitなのかどうかは解析してやる必要があり、その解析に使うのがPSPLinkというアプリケーションです。PSPLinkでゲームを起動するここからは少し難しい操作が必要になります。PSPLinkをインストールしてあるCFWのPSPが必要です。PSPLinkのインストール方法などはネットで検索すれば出てきますので割愛します。PSPLinkは数種類のprxファイルで構成されています。PSPではPSPLinkをプラグインの形で利用します。sepluginsフォルダにusbhostfs.prxとpsplink.prxを入れて、そのプラグインをゲーム起動中有効にするためにgame.txtでpsplink.prxを記述しておいてリカバリーメニューで有効にしておいてください。psplink.prxを有効にしておけばusbhostfs.prxはPSPLinkが自動で有効状態にしてくれますのでusbhostfs.prxをわざわざ有効にする必要はありません。基本的にはPSPの画面をPCの画面上に表示するRemoteJoyからリモートジョイスティック機能を無しにしたものがPSPLinkだと思ってください。チュートリアルはどこにでもあるであろうRemoteJoyを使えるようセットアップできていればPSPLinkは使えるはずです。すべてインストールが完了し準備ができたら、PCでusbhostfs_pc.exeを起動してゲームを起動したPSPとPCをUSBケーブルで繋ぎpspsh.exeを起動してください。loaded”と表示された後”/host0:>”と出てきます。セーブデータを読み込んだ後、クラッシュするまでの動作を行ってください。クラッシュはセーブデータ読み込み直後に起こる場合もあれば、何らかの操作を行った後クラッシュする場合まで様々です。クラッシュするとpspshの画面に以下のような画面が表示されます。何を探せば良いのか?ここからはアセンブラの話になりますので少し難しいかもしれません。PSPLinkはクラッシュ直前の各種レジスタの状態を表示してくれます。レジスタはプログラムで使われている32ビットの整数型で、文字やメモリアドレスなどプログラムによっていろんな用途で使われています。exploitを探したい場合には、メモリー内の任意の場所にジャンプすることができるコードが書けるかどうかを調べます。それができる方法はそんなに多くありません。今知る限りでその唯一の方法は”$ra”というレジスタの中身を任意の値に書き換える方法です。address”、つまり”戻りアドレス”の意味ですので、これが何故重要なのかは想像がつくでしょう。$ra”($raにジャンプする)というコマンドとして使われます。$ra自体は通常$spというレジスタからデータを受け取ります。そのため$spに関係するデータが扱えるならば流れとしては良い方向と言えます。他のレジスタではダメなのかと言うと、そうでもありません。場合によっては$spや$raに値を受け渡しすることもあります。その方法の場合は非常に複雑であるためここでは説明しません。exploitとなったクラッシュと、単なるクラッシュを比較する2つのクラッシュの結果を比較してみます。exploitだった『Gripshift』のクラッシュの場合プレイヤー名に「a」を大量に入れました。61は「a」という文字を16進数で表した数字です。これがビンゴ!0x61616161はセーブデータ内に入れた、通常連続した「aaaa」の部分のどこかなので、それさえ突き止めればメモリー内の任意のアドレスへジャンプさせる方法が見つかったことになります。“61”と言う数字があちらこちらにありますが、肝心な$spや$raにはありません。$a1、$a2、$a3に”61′′が出てくる時点でexploitに成り得る可能性はゼロとまで言い切れませんが、スタートとしてはその後の手間を考えると悪い部類だと言えます。$a1、$a2、$a3が何らかの良い影響を与えているかもしれませんのでここで一度PSPLinkで見てみましょう。PSPLinkのEPCという部分に表示されているあたりで何が起こったのかをディスアセンブルしてみます。40′′と入力しています。$spにはなんの影響もなさそうなのが分かりますし、非常に複雑な動きをしているのも分かります。これでは駄目そうです。一般的にはこのような状態であったらさっさと諦めて他のゲームで別のexploitを探すのが賢明です。$raにストアされるアドレスを探すPSPLinkで$raに表示された「aaaa」の4バイトがどこにあるのかを探し、”61′′の代わりに任意の値を入れてやることでPSPのメモリ内の任意のアドレスへジャンプさせることができるようになります。この方法には王道がなく、地道に探して行くしかありません。方法は非常に単純です。61」と成っているはずですので、そこにユニークな数字となる値を順に入れて行き、PSPLinkの結果を見ればそのアドレスが特定できます。0x04030201のように表示されたらそれがビンゴです。1000バイト以上「aaaa・・・」を入れた場合には、例えば1000バイト以下の場合にはクラッシュすらしないことが多いようです。いうことは、クラッシュするようになった1000バイト目以降の部分で同じことを行うだけでアドレスの特定ができます。B0・・・」のように16バイトづつ同じ値を入れておき、まずどの行が$raに該当するのかを調べれば後は簡単です。Loader】この記事についてPSPでHomebrewを実行するための最初のステップはユーザーモードexploitを発見することです。これはゲームでのバッファーオーバーフローや画像を操作するといったテクニックを利用してPSPのRAMをコントロールすることになります。した脆弱性を見つけて、値が可変するレジスタ$raをフルコントロールします。次のステップはその実証となります。バイナリーローダーを作るにあたり基本的な考え方は、記述したコードからメモリースティックに置いたファイルにある別のコードを読み込み実行させるということになります。バイナリーローダーの作成は方法さえわかってしまえばそんなに複雑ではありませんが、どこかに情報が集まっている訳ではないためできるかどうかは知識の有無に依存してしまいます。いうことでこちらです。World”を表示(自作コードの実行が可能なことを証明)することが可能になります。今回サンプルに使ったsparta_sdkはもちろんこのチュートリアルに沿って作ったわけではありませんし、本来であればアセンブラなどの基礎も覚えて上で取り組むべきことであるのは事実です。原則を主張していても実利は生まれません。試してみたらできた、という楽しみ方の提案だと思って読んでください。このガイドでは皆さんが既に$raの値を自由に変えることならばできるという前提で書きます。ゲームのセーブデータを例にあげてみましょう。XMBでの脆弱性を見つけた場合だと少しやり方が変わりますが、主要な所は同じです。PSPLinkの使い方も知っているものとします。Worldなど)7.セーブデータを暗号化し直すジャンプする場所を探すPSPLinkを起動させ、いつものやっているようにゲームをクラッシュさせます。そのまま次のステップを実行していきます。$raのコントロールができたら、バイナリーローダーのコードを入れたいアドレスにジャンプさせるようにします。原則としてコードはセーブデータの中に書きますので、セーブデータがRAMのどこからどこまでに入っているかは知っておく必要があります。セーブデータとRAMを見て比較しなければなりません。memdump.binと入力してください。これによりPCにmemdump.binという約20MBのファイルが保存されます。セーブデータの中の分かりやすい部分をまず探してください。同じ文字や数字が続いている部分が分かりやすいでしょう。その部分と同じ部分をダンプしたデータの中から探します(もちろんHEXエディタを使います)。下の画像ではダンプデータが左でセーブデータが右になります。ダンプデータでセーブデータと同じ部分を見つけることができればジャンプしたいアドレスを知ることができ、セーブデータのどこにコードを記述すれば良いのかが分かります。この例の場合見つけたパターンはセーブデータの場合0x43F0から始まっていて、それがダンプデータでは0x32C3E0になっています。(=0x08B2C3E0)ということになります。20と入力してメモリダンプしてみれば先ほどのパターンが出てくるかを確認できます(アドレスの部分は自分で決めたアドレスにしてくださいね。)実際にはセーブデータ内に先ほど選んだコード記述エリアへジャンプ命令によりジャンプすることになりますので、その場所は正確に把握しておく必要があります。そのエリアでセーブデータとダンプデータに違いがあった場合、それはセーブデータブロックがそのエリアで完全に読み込まれなかったということになりコードを書くことがより困難になります(コードがRAM内に散乱するよりも1ヶ所にまとめた方が良いのです)。ジャンプするに相応しい場所(0x08B2C3E0)を探してSDDATA.BIN(0x43F0から)にバイナリーローダーを入れ込むことになります。インポートする関数を探すここからはかなり難しそうなところへ踏み込みます。本格的な知識が必要なように感じますが、実際にはそれほどでもありません。その理由はつまり、良いツールがすでにあるからです。Homebrewのコードを書くときには、PSPSDKの関数を呼び出します。ゲームを利用するexploitの場合にはRAM内のどこで関数を呼び出すのかはあらかじめ分かりません。そのためきちんと探し出してリダイレクトしてやる必要があります。ゲームの場合で考えてみましょう。ゲームからEBOOT.BINを抜き出して復号化するとします。EBOOT.BINはゲームのISOファイル内にあるのでまずそのISOファイルを用意しなければなりません。ゲームがUMDだった場合、カスタムファームウェアであればISOファイルに変換することは簡単です。Driveオプションがついていますので問題ありません。(ゲームがPSNで購入したものだった場合にはNPDecryptorでISOファイルに変換できます)。まもすけ注:NPDecryptorは著作権を侵害しているという理由で現在ネット上からほとんど削除されてしまっています。ほとんどの場合、EBOOT.BINは暗号化されているのでprxdecrypterを使ってさらに復号してやる必要があります。一度EBOOT.BINを復号化してしまえば、prxtoolを使ってそこから情報を抜き出せます。EBOOT.BINこれによってゲームに使われている個々の関数の実アドレスが分かります。Homebrewやバイナリーローダーで使える関数はこのようになっています。関数名に対応して16進数の値の後にライブラリの名称があることが分かるでしょう。ここから、その関連性が分かるだけでなくNIDSライブラリ関数名の関連付けが分かるxmlファイルも入手できます。いったxmlファイルはsilversprings氏(Lan.st管理人)のサイト(http://silverspring.lan.st/)でも入手可能です。nidsファイルが手に入ったら、次のようにコマンドを入力してください。EBOOT.BIN※yourfile.xmlは任意の.xmlファイル名です。分かりやすいものが出てきます。基本的にはこちらを使います。この結果は必ず保存しておいてください!もしprxtoolにファイルはprxではないと言われたら、どこかの復号化で失敗しているか、違うEBOOT.BINを使ったか(ISOファイル内にはダミーのEBOOT.BINが複数あり)の可能性が大です。バイナリーローダーをコンパイルするこのステップを実行する前にMatiaz氏とFreeplay氏のsparta_sdkをダウンロードすることをお勧めします。Gripshiftのexploitを利用したsparta_sdkはバイナリーローダーの参考例として非常に有用です。バイナリーローダーはアセンブラで書いてしまうとそれ自体は非常にシンプルなものになります。SDKを利用してCをベースに書くこともできますが、sparta_sdkのバイナリーローダーはMIPSアセンブラで書かれているようです。アセンブラはC/C++よりもハードルが高いのですが、今回はMatiazs氏の作ったものを今回発見したexploitのケースに当てはめてみたいと思います。何ヶ所かを置き換えるだけ、ということになります。sparta_sdkのloader.Sのファイルを開いてみてください。binLoaderで使われている関数アドレスを置き換えることとなります。Matiaz氏はGripshiftで使えるようなアドレスを入れていますので自分が見つけたゲームexploitとはそこが異なります。記述してある4つの関数(sceIoOpen、sceIORead、sceIOClose、sceKernelDcacheInvalidateRange)を、先ほど作成したリストに沿ってGripshiftでの値を自分のゲームでの値に置き換えてください。先ほど私が作ったリストで言うと、sceIoCloseとなっている0x08A69854を0x08C88590に置き換える、などという感じです。リストにない場合です。その場合にはsceKernelDcacheWritebackInvalidateAllが代わりに使えますので探してみてください。ファイルネームがストアされているアドレスも変えてやる必要があります。ファイルネームとは自分で作ろうとしているバイナリのファイル名のことで、よく使われるのがms0:/h.binです。これをセーブデータのジャンプ箇所のあたりに文字列として記述しておかなければなりません。そのアドレスをasmコードとして出しておいてください。下記の例で言うと、ms0:/h.binというファイルネームをジャンプポイントより0xF0バイト後ろに置いたことになるので、spartaの0xC0をF0に書き換えます。注意しておきたいのはコンパイルしたバイナリーローダーの長さはF0より小さくしなければならないことです。しないとファイルネームのところがバイナリーローダーのコードで上書きされてしまいますよ。変えなければならないのはそのくらいです。このファイルをコンパイルしてSDDATA.BIN(暗号化されていないセーブデータ)の中に書き込んであげましょう。アセンブラのコンパイルはPSPSDKで提供されている各種ツールのなかでも特に難しいということはありません。sparta_sdkをヒントに、ここでコンパイルのためのコマンドを紹介します。a.bin最初がコードをコンパイルするコマンドで、次がそれをバイナリー版にするコマンドです。バイナリーローダーをセーブデータに書き込むバイナリーローダーのコンパイルができればあとは簡単で、セーブデータに書き込むだけです。手でコピペしてもいいですし、お好きなスクリプト言語を使っても良いでしょう。注意してほしいのは先ほどこの記事でも書きましたが、$raにいれたアドレスから始まるよう正確に書き込むということです。書き込みをするにあたり、SDDATA.BINファイルにexploitの読み込み+バイナリーローダーをコンパイルして書き込みを直接やってしまえるように私の場合はRubyでスクリプトを組みました。コードは自分で見つけたexploit用に大幅に書き換えなければならないので画像としてお見せしておきます。コードを書き込むための方法は自分がやり易いと思うやり方で実行していただいて構いません。worldをアセンブラで作って入れておけば良いことにお気づきでしょう。バイナリーローダーなどではなくもっと簡単なコード(例えばsceKernelExitGameを呼び出すなど)を試してみるのも良いですが、まずは自分の書いたコードを確実に動作させることに専念してください。難しそうに思えますが、実はそうでもありません。関数をセーブデータにインポートできていればお茶の子さいさいです。必要なのはprxtoolを使って入手したインポートする関数リストだけで、sparta_sdkのサンプルフォルダにあるsdk.hをアップデートするだけです。迷うようなことは全くありません。今回の例でいうと、0x08C88590を0x08A69854に置き換える、などです。先ほどの”.S”ファイルと同じです。実は、sparta_sdkのsdk.hファイルはベストな例とは言えません。exploitのsdk.Sを一度見てみた方が良いでしょう。これもアセンブラですが超シンプルで、関数がどうとかを探す必要すらありません。imports”ファイルを分析するための簡単なRubyのスクリプトを作りました。prxtoolにもこの操作をする上で役立つオプションはあるようです。exploitにあるsdk.hを探してみてください。”.S”と”.h”というファイルがそうです。Worldは本当に簡単です。SDKにあるサンプルを書き換えや流用できたわけですからね。最初はできるだけ小さなファイルを作るところから始めて下さい。簡単に実証するためのCのコードは“sceKernelExitGame()”を呼び出すことです。作成したSDKとバイナリーローダー(先ほど作成したもの)がきちんと動作することを確認する分にはそれで十分です。sparta_sdkのイベントをすべて自作sdk用に置き換えるだけだと考えてください。sdk.Sを使った場合はmakefileに若干変更を加えなければなりません(その場合はspartaのMakefileではなくMOHHのMakefileを見て考えてみてください)。コンパイル後に出力するファイル名はh.binにします。バイナリーローダーがms0:/h.binを読み込むようにしてあるので、そのh.binをメモリースティックのルートに配置します。バイナリーローダーが入っているSDDATA.binはSAVEPLAINというフォルダ名のサブフォルダ内に配置します。以上の準備が完了したらゲームを起動してください(もちろんSaveGameDeemerとPSPLinkのプラグインは有効にしておきましょう)。Worldが表示されるはずです。トラブルシューティングexploitの動作がうまく行かない場合、いくつかの原因が考えられます。コンピューターのプログラムは書かれた流れ通りに実行されるだけなので、動作環境が不十分であってもバカ正直に間違った動作をしてしまいます。そんな時はPSPLinkの利用が成功の鍵となります。クラッシュしてしまったらRAMの状態を調べてみてください。すべて正しい場所にあって、おかしな理由で途切れたりしていませんか?実際に動作しているかを確認するためにバイナリーローダーにブレイクポイントを追加してみてください。Worldが設定したアドレスに読み込まれているかを確認してください。Worldでブレイクポイントを設けてみてください。あとはいかに簡素化するかです。操作をある程度自動化しないで一つ一つのステップを手動で行っているとかなり苦痛に感じるかもしれません。私は作業を自動化するようなスクリプトを作ることにまず時間を割いた方が良いと思います(バイナリーローダーのコンパイルやそれをセーブデータに書き込む作業など)。これなら自信があると言う言語でスクリプトを作りましょうセーブデータを暗号化し直す最後のステップは公式ファームウェアでexploitを動作させるようにすることです。SEDというツールでセーブデータexploitを暗号化できます。SEDでの暗号化にはgamekeyが必要です。gamekeyはSaveGameDeemerで作られるSAVEPLAINデータの中にあります。ms0¥PSP¥SAVEPLAIN¥XXXX.bin(XXXXはゲーム自体のコード:パタポン2日本版ならUCJS10089.bin)というデータの一番最後の部分がgamekeyです。XXXX.binをバイナリエディタで開いてファイルの一番最後の部分を見ると、次のようになっています。・ファイルの一番最後の20バイトは必ずゼロ・その直前の16バイトがそのゲームのGamekey薄く色がついているところがGamekeyになります。その16バイトだけを抜き出してgamekeyが作れます。SEDの場合は16バイトのXXXX.bin(:パタポン2日本版ならUCJS10089.bin)というファイル名にしてms0¥PSP¥GAME¥SED¥gamekeyフォルダにコピーしておきます。あとはSEDを起動すればセーブデータの暗号化/復号化は自由自在です。SEDの使い方についてはググってください。いい加減な説明ですね。exploit】セーブデータを利用したユーザーモードexploitを見つけて、次にバイナリーローダーを作成。次はどうしたらよいのでしょうか。Worldだけというのはもう誰も喜んでくれません。Worldが実現できることはは素晴らしいことですが、それだけでは何の成果も得られません。ソニーに対してexploitの存在をアピールするだけで、せっかくの脆弱性が何らかの結果に結び付く前に早々とパッチされてしまうことは自明の理です。exploitを発見後の次のステップといえば、理想的にはHENやカスタムファームウェアとなります。それを実現するには新たにカーネルexploitが必要ですが、それを発見することは相当困難です。ユーザーの利益に成りうるより現実的な選択はHBLの移植となります。HBLはノーマルPSPで合法的なコンテンツを楽しむための扉を開くアプリケーションです。我々はそのためにHBLを開発したのですからセーブデータを使ったゲームexploitをHBLに移植することは簡単にできるようになっています。このチュートリアルはこの記事を書いている現時点ではファームウェア6.31以下であれば対応しています。理論上HBLはこの先出るであろうファームウェアでも動作するはずですが、もちろん今後新たなセキュリティシステムが採用されてしまう可能性もありますのでその場合にはチュートリアルに沿って移植しても動作しないこともあり得ます。Homebrewの互換性や実行速度に影響を与える)の内容が変わってしまう可能性もあります。実はカンタンHBLはPatapon2以外のセーブデータexploitにも簡単に移植できるようになっています。特定の一ファイルを除き、ゲームごとに必要なファイルは後程詳しく書きますがほとんどがサブフォルダごとに分けて入れておくことになります。Worldのコーディングに必要な知識、Ruby言語の知識が必要です(一般的にはRuby以外のスクリプト言語を知っていれば簡単に把握できます。違いはそんなに多くありません)。HBLのソースを入手しコンパイルする移植への最初のステップはBLのソースを入手しコンパイルすることです。可能であればコンパイル後のHBLを既にリリース済みのexploitで正しく作業が出来ているかを確認するための動作確認を行ってください。HBLのソースはこちらからダウンロードしてください(SVNクライアントが必要です)。コンパイルするためにはPSPSDKが必要です(バイナリーローダーを作成したのであれば既にお持ちだと思います)。コンパイル自体は非常に簡単ですが、ある特定のexploitで起動するようHBLをコンパイルするのであればそのexploitごとにフォルダを作成しておく必要があります。Golf(US)』用のexploit用にコンパイルしているという形になります。新たに発見したexploit用のフォルダを作成するもうお分かりだと思いますが、HBLを移植したいexploitのためのフォルダをまず作成することになります。wololoというゲームでexploitを発見したと想定してみましょう。その場合はeLoaderフォルダの中にwololoという名称のサブフォルダを作成することになります。我々の基本的なスタンスとしては別のexoploitが見つかればそのフォルダに入れるためのファイルは別途提供する方針ですし、我々がすでに提供しているexploitにも反映させたいと考えています。実際patapon2フォルダの構成を見てみましょう。このフォルダ内には6つのファイルと2つのフォルダがあります。これらに新たに発見したexploitで動作するよう修正を加えていくことになります。個々のファイルごとに説明したいと思います。新たに発見したexploit用のファイルを作成するツール類フォルダは実際には絶対必要というものではないのですが、これから移植していくにあたりメモリーダンパーなどのツールは必要ですのでそういったツール類をフォルダに入れておきます。linker_loader.xこれはh.binファイルとリンクさせるためのファイルになります。Worldを作成済であればこのファイルは既に持っていることになります。Worldからコピーしlinker_loader.xへとファイル名を変更して終わりです。sdk_loader.Sこれはh.binのためのSDKです。Worldを作成済であればこのファイルは既に持っているかもしれません。それはsdk.Sというファイル名になっていると思いますのでそのsdk.Sをコピーしsdk_loader.Sへとファイル名を変更してください。ない場合にはゲームから抜き出したEBOOT.BINを使ってprxtoolを実行して作成するか、moskitoolを使ってください。Worldを作成済であればこのファイルは既にあるはずですのでこれ以上詳細は書きません。configフォルダとsdk_hbl.Sまず空のconfigフォルダを作成してください。generator¥eLoaderconf.rbのRubyスクリプトで自動生成されます。sdk_hbl.Sも同様に生成されます。スクリプトを適当なテキストエディタで以下のように変更してください。基本的には各々のexploitのハッシュは把握しているので、HBLで使えるstub(スタブ:他のプログラムを呼び出す際に仲介となるプログラム)がどこにあるのかは分かります。理論的にはstubの見つけ方はm0skit0s氏のフォーラムに書いてありましたが、残念ながら今はフォーラム自体が無くなってしまいました。今回は皆さんのためにRubyスクリプトをeLoader\tools\stubs.rbに用意してあります。使用するにはユーザーメモリーのダンプが必要です。dumperを使って用意するかしてください。用意できたらファイル名をmemdump.binにしてstubs.rbを実行します。メモリダンプはファームウェアごとに必要になりますので他のハッカーやベータテスターに協力を仰ぎ用意してください。(ちなみにファームウェア検知にはかなり多数のメモリダンプが必要になるので出来るならば可能な限り数を集め、ファイルが埋もれて管理できなくならないよう正しく分けて管理しておくことが大切です。)どのライブラリからstubを得られるのかを知るためにPSPLinkでmodlistを実行します。重要なstubはゲームから得られるものになります。通常はmainと呼ばれますが名称が変わることはよくあり、例えばPatapon2の場合にはLaboと呼ばれていました。そのため、基本的にはメモリーダンプごとにstubs.rbを実行するとファームウェアごとのアドレスが分かるようになっています。必要に応じてファームウェアごとにこの作業を繰り返します。結果に応じてそれをeLoaderconf.rbにコピぺしてください。exploit_config.hこのファイルが最も変更する部分が多いです。この書き換えがほとんどすべてと言ってよいでしょう。exploitごとに変化するファイルの定義が含まれており、コンパイル時にHBLへ統合されます。これはRAMにHBLを読み込むためのアドレスのことです。ゲームで使用するRAM領域ではないのはどこなのかの値は把握しておきたいところですが、基本的にPSPに確保できる領域はおおよそ200kB程度です。特定のアドレス指定なしで200kBの領域を確保するためのh.binファイルを作成することによりこの値が分かります。以下のようにしてそのアドレスを入手するようにします。動作させたくないスレッド(小さな単位で実行するプログラム処理)のリストです。スレッドはSceUIDによって定義されますが、値は常に変化してしまうため実際に知りたいのはどこで定義されているのかというアドレスになります。World)起動中にthlistと入力することによりこのスレッドリストが入手できます。次にRAM内の各々のスレッドのUIDを探します。そのアドレスはthidが定義されておりすべてユニークなはずですが、それこそがリストにいれておきたいものです。PSPLinkでuidlistと入力してもアドレスが分かると思いますが私自身試したことがありません。そこまでマメじゃなくて申し訳ない。動作させたくないイベント(実行中のプログラムからの処理要求)のリストです。PSPLinkでevlistと入力すれば出てきます。TH_ADDR_LISTと構造が似ています。動作させたくないセマフォ(並行して動作しているプロセス間で同期を取ったり割り込み処理の制御を行なう機構)のリストです。PSPLinkでsmlistと入力すれば出てきます。TH_ADDR_LISTと構造が似ています。これはゲームのメモリが割り当てられているRAM内のアドレスです。ほとんどのゲームにはあるはずですが、Patapon2のように無いゲームもあるのでその場合には値をコメントアウト(削除せずコメント文として残す)しておきます。この値を見つけるにはPSPLinkでuidlistと入力しSceSysMemMemoryBlockセクションあたりで探してください。0xFFがあるユーザーエリアに属するブロック(00のところではありません!)でスタック(最後に入力したデータが先に出力されるという特徴をもつデータ構造)ではないところを探します。みんゴルexploitの場合はこのブロックはそのまんまのblockと呼ばれているので見つけるのは簡単です。エントリーアドレスが大切なのであり、UIDではありませんよ。これは可能ならばいろいろ変えて定義してみてください。HBLのメモリで問題が出た時にはコメントアウトしてください。ファームウェア検出のための変数は現時点ではトライアンドエラーしかありません。いろんなユーザーからファームウェアごと、モデルごとにメモリダンプをお願いして集めて比較してみるしかありません。目標にするのはファームウェアごとにメモリダンプで同じ部分を見つけ出すことです。ファームウェアが異なればその部分が今度は異なるはずです。linker_hbl.xlinker_loader.xをコピーしてlinker_hbl.xとしてください。アドレス値を先ほどexploit_config.hを作成した際に見つけたHBL_LOAD_ADDRESSの値と置き換えて終わりです。コンパイルeLoaderconf.rbを実行しSDKとconfig(設定)ファイルを生成してください。この操作により今移植しようとしているexploitを含め、eLoaderconf.rbで定義されている全exploitのconfigファイルが生成されます。