2009年10月5日から2009年10月1日までの日記を表示中

2009年10月 5日 (月)

今日のハードオフ

ファミコンソフトが結構増えてたけど,箱に詰め込んでレジ前に縦に4個も5個も積み上げるの漁りにくいから勘弁してくれ (;´Д`)

つっぱり大相撲他

というわけでやっとつっぱり大相撲ゲット.105円でした.同じ箱に前からあった超汚い350円のが入っているのが何とも・・・.

C77

受付確認ハガキが届いておりました.当落は来月頭だっけ?はー.

2009年10月 4日 (日)

セイヴァー2を電池レス化してみる その3

電話で起こされたのを機に,そのまま作業再開.サウンドテストの表示が変な問題は,単純にデコード不要な領域を見落としていて,文字列データの部分をデコードしてしまっていたのが原因でした.

ここで既知の問題は一通り片付いたので本日一発目の実機チェック.実機でもばっちりゲームまで到達しました.写真は何かハメコミっぽいけど違いますよw.

実機でも起動した

が,いざ遊んでみるといきなりリセット発生.どうも2回目のダウンを奪う直前にリセットがかかるっぽい (;´Д`).MAMEでも再現するし.今度はどこだー.

今回も例外ベクタにブレークポイントを仕掛けまくったら今度はアドレスエラーで落ちてることが判明.でもスタックを見てもどこで落ちているのかやっぱりよくわからん・・・.仕方ないので落ちる直前でトレースを取るようにしてやったところ原因がわかりました.本来デコード不要なところをデコードしてるせいで,その値をROMから読んでjmpした際にめちゃくちゃなところに飛んでいました.

何でこんな初歩的なのを今まで見落としていたのか・・・と思ったら,この部分,デコードするとちょうど 68000 の命令になるらしく,dis.x の出力ではデータではなく自然な命令列になってました (;´Д`).こういうパターンもやっぱりあるのか・・・

他にもこういうのがあったとしても dis.x 側から探すのはさすがに厳しそう.そこでデコード前のROMデータに対して現時点で判明しているデコード不要の部分のみをわざとデコードしたデータを作ってみました.こうすると,データの殆どの部分がランダムな値の並びになるので,未発見のデコードが不要な部分の規則的なデータの並びが目立つようになり,バイナリデータの目視で発見しやすくなるという具合です(笑).hexdump の出力をざーっと目で確認してみたところ,3ヶ所くらいデコード不要指定漏れが見つかりました.ほんと抜け漏れなく探すの難しいわー.

これらの修正で,勝利しても落ちなくなりました(笑).よかったよかった.というわけで,あらためて実機でプレー.落ちずに1周してくれましたよ.わーい.ていうかモリガンでクリアしたんだけど,エンディングのカットってこれでいいのかw?

エンディング

スタッフロール

ちなみにテストモード内のメモリテストがNGになるんですよねー.ワークRAMの方は 0xFFFFF0 からの16Byteを飛ばすようにして回避できましたが,ROMの方がよくわからん.何を計算していて,答えはどこにあるんだろうなー.

メモリテスト

そんなわけで,とりあえず68000初心者でも根性とROM焼き環境があれば電池レス化は可能ということが確認できました (笑).死んだ板がまだあと2個あるので,次はもう少しエレガントにやる方法を模索していきたいですね.デコード前のデータのランダムさをうまく数値化して半自動化できたら面白いかもなぁw.あと今回全く試さなかったんですが,dis.x以外の逆アセンブラも試してみたいところ.

あと,本当は「ここが俺の見つけたデコード不要領域だぜ!」とか「ここにパッチを当てろッ」とか出したいんですが,どこまで出していいものやら.それからMAMEベースに作ったツールとかもそのうち出せればと思うんですが,MAMEのソースを流用したエミュレータ以外のものはライセンス的にどうなんだろう的な・・・

ちなみに電池レス化するとメモリのアクセスレイテンシが減るからタイミングがずれるという説もありますが,そもそもゲームは1フレーム内でやること全部やったらフレーム同期待つだろうから,アクセスレイテンシが減って違いが出るとしたら処理落ちするくらい処理が重くなったときとかですかねー.考えたくないけど,プロギアとかだと差が出るのかなぁ.いやだなぁ.

2009年10月 3日 (土)

セイヴァー2を電池レス化してみる その2

一昨日の続き.MAMEでvsav2を動かした場合と比べてみたところ,vsav2dの方が途中で全然違う命令を実行し始めるために暴走していたことが判明.同じアドレスから読んでいるのになぜだ・・・と思ったら,デコードしなければならない領域をデコードし忘れていたのが原因でした.本来は命令であるべきところをdis.xがデータとして誤認識しており,それをデコードしなくてよい値と判断してしまったのがその原因 (;´Д`).そしてなぜかmove.bの先頭2byteと次の2byteの間にラベルがついており,上の方で addaでそのラベルが参照されているのがさらにその原因です.dis.xに-k オプションをつけたりはずしたりしても効果なし.こういうのは手で探して直さないとだめかー (´・ω・`)

というわけでdis.xの出力のデータ領域を上から1個1個確認しながら手で直しているうちに今度は別の問題が発生.データ領域であることはほぼ確実な領域でも,デコード前の値は超ランダムな感じで,デコードすると意味のありそうな値になる領域が結構あるのです.見るからにデコードした方が正しい値っぽい.うー,どういうことだ?同じデータ領域でもデコードした方がいいものとしない方がいいものがある?

規則性がよくわかりませんが,とにかくデータ領域だからなんでもデコード不要というわけではなさそうです.そんなわけで,再度 dis.x の出力結果を上から順番に追い,デコードするとランダムな感じの値になってしまうところを探すことにしました.

デコードすべきデータ領域は,dis.xの出力結果の値の並びが見るからに整然としていていかにも意味のありそうな値となっており,逆にデコードすべきでない領域は,デコード前の方を見るとランダムなデータの中に突然規則的なデータが現れるため一目瞭然.こうやって1個1個見比べて見つけ出して行きます.どうもデコードが不要な領域はアドレスレジスタ間接形式でアクセスされる領域っぽいですなぁ.どういう仕組みになってんだ?FC0とかFC1の信号見てデコードの有無を切り替えているのか?

と,そんなこんな感じで頑張って1MByte分のデータを追って,130個ほどのデコード不要領域を抽出しました.あっさり書いてますが,めちゃくちゃ辛いですw.さっそく抽出した情報を元にvsav2dのROMイメージを作り直してMAMEで動かしてみたところ,見事にオープニングデモが始まりました!やった! 方針は間違っていなかったようです.が,オープニングデモが1周して,実際のゲームプレーのデモに入るところで強制リセット (´・ω・`).あと,F2 (テストスイッチ) を押しても強制リセットがかかります.しょんぼり.

ところで実機ではどうなんだろうと思ってこの状態のを焼いてみたところ,こっちでは全く画面出ず _|‾|○. リセットをかけるたびにいつもの灰色画面だったり紫画面だったり・・・あれ?紫画面? 画面をよく見てみると,実は一瞬だけメモリチェックの画面が出ているっぽい.あっという間にチェックが終わって,その後暴走して画面がグレーになるわけか・・・.MAMEだと動くのにー.↓XRGB-3で強制的に画面を保持してみたところ

うっすらとメモリチェックの結果が出ている

とりあえず実機の方をエミュレータと同じところにまで持っていきたいので追ってみたところ,メモリチェックの後に再度ワークRAMを初期化しており,その中で 0xFFFFFx の領域を書き潰していました.ここに変な値を書いたときの挙動がMAMEと違うってことかな.ここを修正したら実機でも見事にオープニングデモに到達するようになりました.やったね! もちろん,デモ終了後リセットがかかるところはMAMEと一緒です(笑)

実機でもオープニングデモが出るところまで到達

さて,次はリセットの原因調査ですね.どうせ例外で落ちているんだろうということで,例外ベクタの先にブレークポイントを張りまくったら引っかかりました.不正な命令を実行しているらしい.ふーむ,本来命令のはずのところをデコード不要のデータとみなしてしまっているところがあるとかその辺かなー.

う,例外ベクタにとんできた際のスタックの見方がよくわからん・・・.仕方ないのでトレース取ったりしてどうにか解決.やっぱりデコード不要の範囲の指定がおかしかった.というわけで,その辺直したらF2で落ちなくなり,オープニングデモ後のプレー画面まで到達するようにもなりました.わーい,もう一息か?

しかしここでまた問題が.サウンドテストの画面が何か変(;´Д`).これはデコード不要のところを間違ってデコードしちゃっているっぽいなぁ.・・・と,ここで唐突に気力が尽きて本日の解析はおしまい.ほんとすげー疲れるわこれ.明日に続きます.

文字が一部壊れている

夜になって届きましたよ.

オープニングデモ

『今はマネドルっすよ』

マネーアイドルエクスチェンジャー

しかし今見ると絵が結構アレだなw.だがそれがいい.あとデコと訴訟騒ぎがあったとか知らんかったよ.

対戦デモ

2009年10月 2日 (金)

飲み

(その気になれば) 歩いて帰れるのをいいことに終電後まで飲んでました.ビールうますぎる.よく飲んだなぁ.帰宅後,あまりに眠くて何もせずにそのまま就寝.

2009年10月1日 (木)

セイヴァー2を電池レス化してみる その1

10月になったのでそろそろ原稿モードに移らないとまずい感じなわけですが,その前にこれだけはってことでヴァンパイアセイヴァー2の電池レス化に挑戦してみました.例によって超長い上に,途中で終わってるので最終的な結論だけに興味がある人は後日のを読んでくださいw

CPS2のゲームの電池レス化の手順はCPS-2 Shock に書かれています.ただしアウトラインのみで,具体的な使用ツール類やノウハウについては言及されていません.軽く探した感じだとこれ以上の情報は得られなかったので,これと電池切れになったCPS2のROMボードもエミュレーションできるMAMEのソース,それから実際に電池切れになったボードで動いた実績のある suicidetester のバイナリをヒントに頑張るしかなさそうです.

一応 CPS-2 Shock で公開されている電池レス化の大雑把な手順は以下の通り.

  • 暗号化されたデータをデコードしたROMを用意する
  • プログラム中で 0x400000 からの14Byte にアクセスしている部分を書き換えて,0xFFFFF0 からの 14Byteへのアクセスに置き換える
  • メモリ初期化処理で0xFFFFF0 からの領域に何か書いたりしないようにプログラムを書き換える
  • 元々 0xFFFFF0 を使っている処理は他のところを使うように書き換える

まあ要するにROMをデコードして,さらに0x40000x へのアクセスを 0xFFFFFx へのアクセスに書き換えろという話です.本当にこれだけなのかという感じですが・・・.プログラムに修正を加えなければならない理由は特に見つけられなかったんですが,まあ電池が飛ぶとなんでもかんでもFで埋まるせいかな,と.

というわけで,とりあえずデコードから.MAMEのソースによると,暗号化されているのはプログラムROM (27C4096が8個くらい並んでいるアレ) だけで,さらに実際に暗号化されている範囲はゲームによって異なるようです.ヴァンパイアセイヴァー2の場合,0x000000 〜 0x100000 の範囲が暗号化の対象らしいので,デコードするのは3番と4番のROMの中身だけでよいことになります.

CPS2の暗号化処理のアルゴリズムと各ゲームごとのキーは明らかになっており,全部MAMEで実装されているので,まずはMAMEのcps2crpt.cを使ってデコーダを作成してみました.早速吸い出した3番のROMの中身を突っ込んでみたところ,最初の4Byteがスタックポインタらしき値で,次の4Byteがいかにも実行開始アドレスっぽい値のバイナリが出現.実行開始アドレス (らしき値) から先を逆アセンブルしてみたら 0x400000 などを初期化するコードが出てきたので,デコード自体はうまくいっていそうです.ナイス滑り出し.

逆アセンブルした結果を眺めてみたところ,0x40000xへの書き込み部分を4ヶ所ほど発見.さっそくバイナリエディタ (というかEmacs) で0xFFFFFxに書き換えてみました.ひょっとしてこれで動いちゃったりして? といきなり焼き込んでみたけどピクリともしませんでした (´・ω・`) .画面はいつだってグレー.まあ,そんなに簡単にいくわけないですね.にしてもサンハヤトのROM抜き (GX-7) は便利だなぁ.みんなも買った方がいいよw

というわけでここからはMAME上でデバッグします.SDLMAME の電池切れCPS2 (dead_cps2) のゲームとしてヴァンパイアセイヴァー2を追加して (以下vsav2d),デバッグオプションつきでビルドし直してパッチを当てたROMイメージを動かしてみたところ,ばっちり暴走することが確認できました(笑) (もちろんデコードとかしてない素のROMイメージの方 (vsav2) は普通に動く)

vsav2とvsav2dとで挙動を比較してみると,ROMから読み出した飛び先のアドレスがvsav2dとvsav2とで違うために暴走していることが判明.・・・vsav2dの方が正しい値 (デコードされた値) を読み出しているように見えますが・・・.あれ? vsav2の方で読めてる値はデコード前の値だじゃん? あれ? デコードしちゃいけないってこと?

そこで,吸い出したROMをちゃんとバイナリエディタで眺めてみたところ衝撃の事実が発覚しましたw.普通に「WORK」とか「OKAMOTO」とかの文字列がバリバリでてきます.もしかして,命令メモリとしてアクセスする際はデコードした結果を使い,データメモリとしてアクセスする際は生の値を使うとかそういう感じ? そういえば,前にどこかでCPS2は命令部分のみデコードが必要とか読んだような (出典見つけられず).命令メモリのことだと思ってたわ・・・.MAMEだとデコードした後にあらためて m68k_set_encrypted_opcode_rangeとか呼んでいるのはそういうことか.

もしそうだとすると,全体をデコードするのではなく,実行時に命令としてアクセスされる部分だけをデコードする必要がありそうです.これを静的にやろうと思うと,どこが命令でどこがデータとしてアクセスされるのかを見極めなければならないわけですが・・・,うーん.無理やり全体をデコードしても命令だけは出揃うはずなので,これを逆アセンブルした結果を元に解析できるかもしれませんが,GNUのアセンブラだと厳しそう・・・.MAMEでvsav2の方を動かしてトレースを取って調べるという手も考えられますが,これはカバレッジ面で現実的じゃないし・・・どうしたものか.

プログラムを静的に解析して,データとそれ以外とで分離して結果を出してくれる逆アセンブラとかがあればいいんだけど・・・とググってみたところ発見.dis.xというツール.・・・あるんだ.X68000やっぱすげぇ.

これ,X68000用らしいんですが,落として説明を読んだところFreeBSDでも動くっぽい.じゃあLinuxでも動くんじゃない? というわけで make してみたら,make時にいっぱい警告が出るものの普通に動くバイナリができちゃいました (main.cでcurses.hを常にincludeするように変更する必要あり).なんかいい流れじゃない?

さっそくこんな感じでエンディアンを入れ替えたバイナリをdis.xにかけてみたところ,見事にコードとデータが分かれたアセンブリが出てきました.そしてさっきデコードしてしまって問題になった部分は,きちんとデータとして認識されているっぽいです.すごい!素敵!どんなコードかはここに出せないので,まあ想像してくださいw

dis.xの出力を信じて,逆アセンブルの結果をからデータのアドレス範囲を抜き出し,その範囲に入っているデータのみデコードせずに元の値を使うようにしてROMイメージを作り直してやったところ・・・メモリチェックキタ━━━━(゜∀゜)━━━━ッ!!

なんとMAME上でメモリチェックが始まりました.やったね! ってメモリRAMがNGだし.あー,例の 0xFFFFFx アクセス問題か.該当箇所を見つけてそこを修正したら突破・・・したけどメモリチェックから先でやっぱり暴走するw.

というわけで今日はこの辺でおしまい.後日に続くー.

今日のプロギア

2回だけプレー.1回目は4面の下方向に弾をばらまきまくるヘリ2機が同時に出てくるところのちょっと先で終了.2回目は4ボスで終了.地味に進んでいるけど3ボスがまだよくわからん.2ボスもあんまり安定しないなぁ.まあ,あまりにもいつも通りですがw

4ボスで撃沈

いい加減画面デジカメで撮るのもアレだし,綺麗に静止画撮れる環境考えるべきか?でもゲームの度に裏でそれ動かすのもなんか面倒で結局使わなくなりそう・・・

[コメントを書く]

通りすがり 2010/03/11(木) 11:50:07
デジカメの画像の方が、味があって自分は好みです。
結構綺麗ですし、臨場感もあるので。

nosuke 2010/03/13(土) 05:35:15
おお,ありがとうございます.
確かにキャプチャだと実機で動いている感がなくなっちゃうんですよね.
ベストは
プレー中の動画を高画質でキャプチャ
→後で再生して一時停止してデジカメで撮影
かなぁ(笑)

2009年10月5日から2009年10月1日までの日記を表示中

中の人情報

名前:
nosuke (のすけ)
メール:
sasugaanijaのgmail.com
「の」は「@」みたいな
関連リンク:

カレンダー

2009年10月
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31

<<先月分

翌月分>>

最新の10件のエントリ

最近の10件のコメント

過去ログ