変動アドレスのサーチ方法
DSの場合、わずか4メガバイトのメモリをやり繰りする必要があるため、
プログラムによってはパラメータ格納アドレスが変動することがあります。
(例1) [キャラ2バイト×3人] + [敵2バイト×2人] + [マップ4バイト]
Address +00+01+02+03+04+05+06+07+08+09+0A+0B+0C+0D+0E+0F
00000000 00 00 11 11 22 22 00 00 11 11 FF FF FF FF
(例2) [キャラ4×4人] + [敵1024バイト×4人] + [マップ256バイト]
Address +00+01+02+03+04+05+06+07+08+09+0A+0B+0C+0D+0E+0F
00000000 00 00 11 11 22 22 33 33 00 00 11 11 22 22 33 33
00000010 FF FF FF FF
上の例の場合(動的にメモリを確保するとして)、キャラ処理用の変数の確保量が違うため、
敵情報やマップ情報を改造しようにもアドレスが特定できないわけですね。
何故プログラムは変動アドレスに対応できるか?
さて、アドレスが変動してもプログラム側は自由にデータを参照できるわけですが、
これは「データの格納されたアドレスそのものがメモリ上にあり、それを利用する」のです。
先ほどの(例1)と(例2)の場合、マップ(緑文字)データは前者がアドレス0000000A、
後者がアドレス00000010にありますが、プログラム中では以下のように処理されます。
Address code
00012000 ldr r0,[_MapAddr]
00012004 bl _MapRoutine
00012008 bx r14
0001200C _MapAddr: .long 0000000A
r0に_MapAddrラベルのアドレス0001200Cに格納された値(0x0000000A)をロードし、
サブルーチンMapRoutineにジャンプする処理ですが、マップアドレスが変動するたびに
_MapAddrの値を修正することで対応しているわけですね。
(前述の例2のメモリ配置になったとき、_MapRoutineには0x00000010が入っている)。
これを追尾するのがBコード
プロアクションリプレイDS及びemuhasteで実装しているBコードは、
このような指標(というか間接アドレス)を追跡することができます。
上の例の場合に B001200C 00000000 というコードを打つと、
アドレス0001200Cに格納された値(0x0000000A)をベース値(オフセット)として定義し、
D2000000 00000000コードが実行されるまで
「全てのコードのアドレス部にベース値が加算」されます。
つまり変動アドレスを追尾し続けるわけです。
この状態で 02024000 FFFFFFFF のコードを実行すると、
本来は「アドレス02024000にFFFFFFFFを書き込め」という意味だったものが、
「アドレス0202400A (02024000+0000000A) にFFFFFFFFを書き込め」となります。
この変動アドレスの指標をサーチするには
まずは「変動アドレスの00000000番目」となる基準点を探します。
これは「キャラ名」だったり「キャラ番号」だったりと色々あるので、
根性と気合とガッツと直感で探してください。
大まかな場所が特定できたら「それっぽい範囲」をPARAM & STRING SEARCHで探します。
I開始アドレス-終端アドレス

↑画像の場合、ターゲットとなるデータの格納アドレスが020B6200〜020B627Cの
範囲内であると仮定して検索しており、いくつかのアドレスが該当している。
後は「このアドレスの値を適当に書き換える」と良い。
もしも該当した場所の値が変動アドレスのための指標として使われているのであれば、
これが狂うことにより、データがデタラメになるはずです。
そして元の値に戻したときに再び正常になれば大当たり。
これをBコードとして定義してやることで「変動アドレスの追尾用Bコード」が完成です。