ホーム > セレクトバグ, プログラミング > セレクトバグでセーブが壊れる理由を推測

セレクトバグでセーブが壊れる理由を推測

Memory mapped IOでセーブ領域がメモリの一部になってるため、そこに書き込んじゃってるんじゃないかなーと思ってます。
Pokémon Bug Litchesゲームボーイの仕様によれば、
初代ポケモンではメモリアドレス0xA000から0xBFFFまではカートリッジRAMらしいので、この範囲に書き込んでやればセーブ領域に書かれるわけです。

ただ、セレクトバグでいじるアドレスは主に0xD124(手持ちの見かけの種族)以降なので、
普通にセレクトバグを起こすだけでは「これより後ろ」の領域にしか書くことはできないはずです。
バッファオーバーフローの最後の良心というべきところでしょうか。
あふれたところより前に書き込むためにはもう一手間かけてやる必要があります。x86ではたまたま「スタックに確保したバッファの後ろにリターンアドレスがある」ため任意のコードが実行できてしまったわけです。
今回のような場合、x86のようにリターンアドレスを変えてやりたい放題、というわけにもいかないため0xD123以前を書き換えることは「道具の-1番目」ということができない以上不可能なのです。
ちなみに、道具名やニックネームの作業用メモリもセーブデータ領域より前にあるので、「道具の名前がオーバーフローしてセーブデータ領域を上書きする」ということもなさそうです。
(原理上、主人公の名前はセレクトバグで書き換えることはできないはず。できる方法を知っている方は教えて下さい。)

そこで終わらなかったのがバグアイテム。
ほぼ推測ですが、アイテムの種類とサブルーチンの飛び先のエントリポイントの対応表があり、
正常なアイテムは正常なサブルーチンのある場所を指しているのですが、
バグアイテムはそのエントリポイントのアドレスが妙なところを指していて、そこを実行すると例の領域に書き込んでフアイルのデータがこわれてしまうのではないかな、と。
例えば、セーブルーチンの途中に飛んでしまうような事があれば間違い無く壊れるでしょう。ただし確率としてはけっこう厳しいのでよっぽど運が悪くないとそんなことにはならないと思います。

可能性が高いのは、VRAMはセーブデータ領域の直前にあるので、描画関係のプログラムが行きすぎてセーブデータ領域を上書きするということ。
・マップ範囲外に出たり妙なマップに飛んだりするとありえないマップを描画しようとして画面外=セーブデータ領域に書き込むことがありえる?
・文字列の描画処理で(それこそx86のgetsのように)書きたい放題してVRAMからはみ出た位置に文字を書いてしまうことがありえる? ・・・あれ、バグった文字列表示したりするの実はやばいんじゃ・・・
どちらにせよ、現在進行形で画面が乱れつつあるうちに電源を切ればセーブは無事という可能性も。目視で確認できるんだろうか。

というわけで誰かデバッガで追ってみてください。

広告
  1. まだコメントはありません。
  1. No trackbacks yet.

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。