公式エミュからのROMダンプ技法

当サイトで公開しているROM Masquerade(ROMマスカレード)を使えば、
「Wiiバーチャルコンソール」や「Android用dotemu移植ゲームソフト」などの
エミュレータベースのゲームソフトから元となるROMイメージを抽出できます。

そして、Ver1.20から新たに実装した『ブルートフォースCRC検出』により、
mamedb.comなどのROMサイズやCRC情報、展開アドレスなどを記載した
情報サイトを見れば、(ソフトによっては)公式エミュからカンタンにROMデータを
抽出できるようになりました。

本項は、私の知る限り最も難易度の低いエミュレータベースのPS2用ゲームソフト
ハムスター「オレ達ゲーセン族 熱血高校ドッジボール部」
の解析手順と、ROM抽出の概念を解説します。
ちなみにタイトルの通り「アーケード版」のゲームソフトの移植作品です。

~第1プロセス「ROM格納ファイルを特定する」~

エミュレータベースの移植ゲームもメーカーによって方式は様々。
1.グラフィックや音声だけ転用してプログラムは完全新規(非エミュ型。この場合は抽出不可)。
2.オリジナルのROMイメージを内包し、エミュレータで動作(抽出可。最も難易度が低い)。
3.ROMイメージを加工したものを内包し、エミュレータで動作(抽出可。ただし難易度は高い)。
などなど。
そして「ROMイメージを内包」と言っても、”maincpu.bin”のように個別ファイルだったり、
実行プログラム内にリソースとして組み込まれているものもあったりバラバラ。
これを判断する最もカンタンな方法は「ファイルサイズ」です。

元ROMのファイルサイズはググれば見つかるのですが、アーケード基板であれば
アーケードエミュレータ『MAME』を実行してプロパティを見てもOKです。
今回の「熱血高校ドッジボール部」に関しては先述のmamedb.comにも情報があります。
mamedb.com : Nekketsu Koukou Dodgeball Bu (Japan) (MAME version 0.147)
これを見るとstatus nodump(未ダンプ)の63701.bin(16KB)を除く合計754キロバイトが、
ROMイメージの合計サイズであることがわかります。

PS2版のDVDをパソコンに入れてフォルダを表示すると…
PS2熱血高校ドッジボール部SOUNDフォルダにデータがあるわけないので他から絞り込むと3つですが、
DODGE.PSS = 動画ファイル。
FONT.PF = フォントデータ。
となるとプログラム SLPM_627.05 にリソースとして格納されているのが確定します。

~第2プロセス「最も小さいROMの格納位置を確定させる」~

ROM MasqueradeでSLPM_627.05を開いたら、mamedb.comのデータベースを参考に、
「最もファイルサイズの小さいROM」から絞り込みます。
その理由はとっても単純、ブルートフォースCRC検出には時間がかかるからです。
例えば「熱血高校ドッジボール部」で最もサイズの大きい(128KB)の”tj22j4-0.121″を
ROM Masqueradeでサーチすると、Core i7-4770Sですら検出まで2分10秒
これが一発でヒットすれば良いものの、長期戦になると相当ツライ。
逆に、最も小さい(1KB)ファイル 22j8-0.158 であれば、わずか2秒程度で発見できます。

実際の作業ですが、ROM MasqueradeでSLPM_627.05をロードした状態で、
Dump Actionにある[Go Analyze]ボタンで画面下部ダンプエリアにロードした後、
探したいROMファイルに関する以下の3要素を入力してサーチします。

・サイズ
mamedb.comでは10進数表記ですがROM Masqueradeは16進数表記で入力します。
22j8-0.158であれば、10進数表記で1024、16進数だと400です。

・CRC値
厳密には”CRC32″の値を入力します。mamedb.comからコピペで良いでしょう。
22j8-0.158であれば、c368440fを入力します。

・ステップ幅
CRCの値を何バイトごとに探すかを16進数で指定します。原則は2の倍数値を指定し、
大抵は”4″でヒット、8ならその倍速なので8→4→2..の順でサーチすると良いでしょう。

入力後「Go Attack!」を実行し、見つからなければ別のROMを…と繰り返します。
もし全て出てこなかったら、そのデータは何らかの暗号化もしくは圧縮が施されており、
ROM Masqueradeだけでは解析できない、ということになります。
(その場合もエミュレータでメモリダンプを保存してそれを解析すれば大抵OKです)。

~第3プロセス「芋づる式に他のROMも探す」~

先ほどの 22j8-0.158 の値を元にサーチすると以下の結果が得られます。
DetectCRC:C368440F ADR:002C17D0 SIZE:00000400
これは“SLPM_627.05″のアドレス002C17D0から1024バイト = 22j8-0.158 と一致
という意味ですが、多くのROMイメージは「実アドレスとレイアウトを一致」させる
傾向にあるので、この近辺に他のROMが密集している可能性があるのです。

ターゲットエリア指定は通常「開始アドレス(通常0)~ファイル終端」に指定されていますが、
この開始アドレスをDetectCRC(002C17D0)に指定し、22j8-0.158の次(22j8-0.159)の
CRC値6059F401をサーチ対象に入れて「Go Attack!」で即座に次のROMが見つかります。

逆方向(下から上)に調べたい場合は、1つ前のROMサイズをDetectCRCから引くとOKです。
22j8-0.158の1つ前 = 22j7-0.82 (サイズ65536 = 16進数10000バイト)なので、
22j8-0.158のアドレス(002C17D0) - 22j7-0.82サイズ(10000) = 2B17D0

実はこの2B17D0こそが22j87-0.82のアドレスなのですが、Target Areaの開始アドレスに
この値を入れて[Go Analyze]でダンプエリアの開始位置を変えてからサーチすれば、
普通ならとても時間がかかるはずが一瞬でヒットします。
(サーチ1回目の瞬間に該当するので、まあ当然ですね)。

このままサーチしていくと以下のような結果が得られます。

File Size CRC Addr status
22j4-0.139 65536 aa674fd8 001F97D0 ?
22j5-0.33 32768 C31E264E 002097D0 100%
63701.bin 16384 ??? 002117D0 nodump
tj22j4-0.121 131072 D2922B3F 002217D0 100%
tj22j3-0.107 131072 79CD1315 002417D0 100%
tj22j1-0.2 131072 9ED27A8D 002617D0 100%
tj22j2-0.35 131072 768934F9 002817D0 100%
22j6-0.83 65536 744A26E3 002A17D0 100%
22j7-0.82 65536 2FA1DE21 002B17D0 100%
22j8-0.158 1024 C368440F 002C17D0 100%
22j9-0.159 1024 6059F401 002C1BD0 100%

さて、63701.binの”status : nodump”については「未ダンプ(エミュレーションに不要)」ですが、
“22j4-0.139”に関しては「CRCが一致しないため、理論上の位置」を表記しています。
(22j5-0.33のアドレス002097D0 - 22j4-0.139のサイズ10000 = 001F97D0)

そして上記範囲を切り出して圧縮したものを”nkdodge.zip”に圧縮してMAMEに読ませても、
ブラックアウトしたまま起動しません。
つまり”22j4-0.139”はそのまま範囲を切り出すだけではいけない、ということです。
mamedb.comを見ると、このファイルは”Region maincpu”で、”offset 10000″…
要はメインCPU用プログラムで、開始アドレス10000、ということのようです。
他にmaincpuで開始アドレス0のものはありません。
ここで次のアプローチです。

~第4プロセス「CRCが一致しない場合の変形アプローチ」~

ROM Masqueradeには
“Extract ODD & EVEN (Stripe Mode)” = 偶数/奇数バイトだけ抽出
“Endian Conv” = エンディアン変換
などの機能があり、これらで範囲をいじるとCRCが一致する場合もあります。

この判断もmamedb.comの情報で分かることが多いです。
例えば、先ほど挙げた22j4-0.139のように”offset 10000″など、
offset 0以外の値でスタートしている場合は
『そのまま切り出してもまず動かない』です。

22j4-0.139であれば、まずROM Masqueradeで”001F97D0 to 002097D0″の範囲を
[Go Analyze!]→[Save DumpFile]で”test.bin”などのファイルに書き出した後、
バイナリエディタでチェックすると0000-7FFFまではちゃんとしたデータなのに、
8000-FFFFが全て0000000….という状況が確認できます。

わざわざ64キロバイトのROMの後半32キロバイトを全部000..なんて
ROMが高価な当時にこんな無駄な設計なわけがないので、
そもそも理論上の位置が違うと考えます。

そこで、後半32キロバイトがハズレなら後ろに32キロバイトずらします。
(32キロバイト = 10進数32768 = 16進数8000)
001F97D0 – 8000 = 001F17D0

この直上は0000000….だし、アドレス001F17D0から64キロバイトを切り出すと
無駄なデータもなさそうだしバッチリ!!
…なんてこともなく、ここを保存してもブラックアウトしたままです。
ここで定石パターンは、次の2通りです。

1.『mamedb.comのoffsetの値が巨大な数値なら真ん中で分割して上下を逆連結』
アドレス001F17D0からそのまま64KB切り出すのではなく、
001F17D0から32KB (1F17D0 – 1F97CF) … top.bin
001F97D0 から32KB (1F97D0 – 2017CF) … bottom.bin
を切り出して、これをさらに上下逆に連結します。
コマンドプロンプトより下記コマンドを実行
>copy /b bottom.bin+top.bin 22j4-0.139
ROMマスカレードv1.30から『Swap 1stHalf &2ndHalf』ボタンを実装しました。
swap_1sthalf_2ndhalfこの1ボタンでダンプ範囲のデータを前半と後半で真ん中でぶった切って
上下入れ替えて連結します。
先にネタバレしますが、これが正解(CRC:AA674FD8で一致)です。
ちなみにAndroid版メタルスラッグもこれと同じP_ROM構造です。

2.『mamedb.comのoffsetの値が奇数ならOddやEvenを選択して分析する』
mamedb.comに”offset 1″のように妙な表記になっている場合は、
奇数バイトと偶数バイトに別々のROMが割り当てられている場合があります。
※奇数列を取り出したい場合。
「熱血高校ドッジボール部」には採用されていませんが、NEOGEOのC_ROMなどに
このデータパターンが見られます。

~第5プロセス「一括切り出しバッチファイル化」~

ROM Masqueradeでも一通りの切り出し作業は出来ますが、
拙作のROMCutterとバッチファイルの組み合わせでさらに簡略化できます。
本来このツールは、Android版NEOGEOソフト解析に作ったものですが転用しました。

内容は以下のような感じ(ファイル名は”nkdodge.bat”などで保存)。
—- ここから
rem maincpuだけ上下分離
romcutter SLPM_627.05 22j4-0.top   001F97D0 8000
romcutter SLPM_627.05 22j4-0.bot   001F17D0 8000
copy /b  22j4-0.top+22j4-0.bot 22j4-0.139
del /q 22j4-0.top
del /q 22j4-0.bot
romcutter SLPM_627.05 22j5-0.33    002097D0 8000
romcutter SLPM_627.05 63701.bin    002117D0 4000
romcutter SLPM_627.05 tj22j4-0.121 002217D0 20000
romcutter SLPM_627.05 tj22j3-0.107 002417D0 20000
romcutter SLPM_627.05 tj22j1-0.2   002617D0 20000
romcutter SLPM_627.05 tj22j2-0.35  002817D0 20000
romcutter SLPM_627.05 22j6-0.83    002A17D0 10000
romcutter SLPM_627.05 22j7-0.82    002B17D0 10000
romcutter SLPM_627.05 22j8-0.158   002C17D0 400
romcutter SLPM_627.05 22j9-0.159   002C1BD0 400
—- ここまで

今回の作業内容をそのままコマンド化した内容ですが、これで切り出したファイル一式を
“nkdodge.zip”に圧縮してMAMEなどに読ませばプレイ可能です。

「オレたちゲーセン族」は他にも色々シリーズがあるので、
他にも抽出可能なタイトルがあるかもしれませんね。

最後に。
>>解析結果をまとめた”ROM Extract Wiki”はコチラ

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です