EXCEEDの同人ソフト開発日記という名の備忘録

趣味のゲームソフト開発人。プロなのかアマなのかは不明(不定)らしい。

任天堂のソフトはいつも予定通りに出てこないって言われるけど、
ソフト作りっていうのは、そういうもの。
ゲームソフトは、期限までにやれと言われて、徹夜したり死に物狂いでやったからといって、
期待通りのものにはならない。そういうふうにすると、
結局、チームは妥協しなければならなくなる。
妥協させられて、できたものは、粗くなってしまう。
ユーザーは目が肥えていますから、受け付けてもらえない

山内 薄

自分用メモ

MC68000コードバイナリをソースに復元する方法。


dis.x は v3.15
has060.x は v3.09+87
を使う

つまり、某ROMを吸い出して、それをソースに復元する方法(笑)

普通、8ビットパラレルのEPROM(27c020)2つの構成で、偶数、奇数アドレスに割り振られているから、これをミックスして1つのファイルにする。(ミックスすると多分 512KB になる(笑))

とりあえず、バイナリから 0x00000000〜0x000000FF のベクタテーブルを切り取る。(経験からいうと、のちのち dis る時にこのテーブルがディスアセンブル行為の弊害になることがあるから)

これを dis.x で -h や -y などを付けて何回かdisってみて、割合綺麗なコードを吐くスイッチの組み合わせのアタリをつける(こればっかりは経験がものをいうような気がする)


※ただし、-k は付けてはいけない(付けない方がいい)そもそもベタバイナリなので、
 dis時に全てがコードセクション(.text)と見なされる訳だから、
 命令の中を示すラベルは絶対に存在する
 (言い換えると、命令の中を示すラベルしか存在しない扱いになる)
 ので・・・たぶん・・・

 -b スイッチは -b1 でいいと思う。(相対ジャンプをサイズ指定で組むプログラマがいる(いた)とは思えないし、後でいくらでも変更が利く所だし、ヘタに -b2 とか指定すると、初期段階ではコンパイル時に相対ジャンプが届かないエラーが出るし・・・)

アタリがついたら、-e でラベルファイルを吐き出す。

そして、ラベルファイルにベクタテーブル内で明らかにプログラム領域に飛んでいると思われるアドレスに p(小文字)をつけて、今度は -g スイッチでラベルファイルを読み込ませて disる。(とくにリセット時のPCを設定するベクタ 0x00000004.l は必須)

ここで、リセット時のPCからのソースが復元できるだけでかなりの進展があるはずなので、一度、disが吐き出したソースをコンパイルする。

(例)
※ベクタテーブルの 0x00000004.l の内容が 0x000005d8 で、
 68kbin.bin は 先頭256バイトを切り取ったバイナリファイル

dis --old-syntax -z100,5d8 -a1 -b0 -h -g68kbin.lab 68kbin.bin > prog.s
has060 -w prog.s
lk /b100 prog.o (←HLK はベースアドレス指定が出来ないので、純正のリンカを使う)
cv /rn prog.x

できた prog.r をprog.bin(ベクタテーブルを切り取ったバイナリ)と比較する。比較には、Windowsフリーソフト Stirling がお勧めなので、これで比較。相違箇所当然沢山でてくるが、それぞれの相違サイズが2程度なら経験から、かなり良好な状態といえる。(大体は相対ジャンプや絶対アドレスのズレからくる相違のはず。)

注意しなくてはならないのが、相違箇所はベクタテーブルカットの関係で、0x100バイトオフセットがずれているので、例えば、相違場所が 0x408 と出ているのなら prog.s の 0x508 バイトのオフセットで相違が発生していることになる。


あとは、ソース眺めながら、ラベルファイルを書き直して、コンパイルして比較を繰り返しながら、テーブルファイルとかも定義していくと、いずれコンパイルを掛けた時にマスターバイナリと全く同じ内容の完璧なバイナリが吐き出される(はず)


で、完璧なバイナリが出来ても、まだ安心はできない。例えば、パッチを当てる程度のことであれば、これで問題がないが、ソースコードを改造する場合は、絶対アドレッシングを相対アドレッシングに完璧に変えていないとコンパイルして動作させた時に100%暴走してしまう。まあ、こればっかりは地道にソースを追っていくしかない・・・・。