戦闘開始時HP満タン

まず、セーブデータ比較や根性サーチなどで
ギャラのアドレスから主人公のHPのアドレスを探します
ちなみにギャラの最大値は「0098967F」です
その結果、主人公(ロディ)の現在HPは
00760428に格納されている事が分かりました。

早速、PS2DISでこのアドレスを参照先に設定し
F3で参照している場所を検索します
すると全部で15箇所でヒットしましたが
その中の「001772D4」周辺を見て下さい。


001772D4でv0にHPのアドレスを格納し
001772E4でv0にa0の値を加算しています
直後の001772E8でワードデータをロードし
また直後の001772ECで何処かのアドレスにストアしています

a0レジスタの数値によってv0の数値が変動しますが
そのa0レジスタの数値を決めているのは
001772BCでロードされているa1レジスタの値です
a1レジスタに格納された数値を
001772D8〜001772E0のsllとaddu命令で計算しています。

このsllとaddu命令でどういう計算をしているか
a1レジスタに色々な数値が入っていると想定して計算すると
「a1に0000が入っている場合はa0は0000」
「a1に0001が入っている場合はa0は0120」
「a1に0002が入っている場合はa0は0240」
と、120ずつ増加する事が分かりました。
(命令毎の数値変動はページ後半参照)

ワークコードでのキャラステータスコードを探した時に
次のキャラとの差は0120hあると判明していたので
a1レジスタの数値はキャラアドレスをズラしていると予想出来ます
となると、001772E8でロードしている数値は
計算上では各キャラクターの現在HPという事になります。

HP現在値を読み込むとしたら、
メニューを開いた時、戦闘に入った時、回復or攻撃時、宿に泊まる時
の4つのどれかではないかと考えられます
しかし、ロードした数値を他のアドレスに書き込んでいるので
この4つの中では「戦闘に入った時」が一番怪しいです
(HP現在値を戦闘時専用のアドレスに複写させる動作に酷似)
となると、もし読み込む数値がHP現在値ではなく最大値だった場合
戦闘開始時にHPが最大値になるかも知れません
早速現在値ではなく最大値を読み込むように改造してみましょう。

現在HPのアドレスに0008hを+すれば最大値のアドレスになるので
ロード命令での0000の部分を0008に変更すれば
最大値のアドレスから数値をロードするようになるので
「lw v0, $0008(v0)」を数値化して暗号化します

A01772E8 8C420008
〜暗号化〜
9C82F510 9094E79D

まずはHPが減ったセーブデータを作っておいて
コードを使った状態でデータをロードして戦闘を始めます
すると・・・戦闘開始時にHPが回復しています
これで戦闘開始時HP満タンの完成です。




sllとadduでの計算

a1レジスタに0000が入っている場合
sllとaddu命令による数値の変動は無く
a0レジスタには0000が格納されます。

a1レジスタに0001が入っている場合
sll a0, a1, 3   a0=0008
addu a0, a0, a1  a0=0009
sll a0, a0, 5   a0=0120

a1レジスタに0002が入っている場合
sll a0, a1, 3   a0=0010
addu a0, a0, a1  a0=0012
sll a0, a0, 5   a0=0240