最大値検索1、2とはケタ数が違う要素での プログラム解析を紹介します。 今回の題材は真・三國無双3です このゲームには、敵を倒した数「KOカウント」があります このカウントの上限はゲームの画面を見た限りでは 恐らく9999人ではないかと思われます 早速、270Fで16bit検索をしてみると 00143454が見つかりました実際にはもっと多くの場所でヒットしますが 今回は説明という事で正解の場所を書いています 自分で探す時は検索で見つかる候補から数箇所にを絞って コード化するなどして、確かめる必要があります さあ、見つかった場所を見てみると slti at,v1,$2710という命令が存在します これは「v1の値より2710が大きければatに0001を格納」 という動作をしています。 もしv1(現在KO人数)が2710(10000)を超えていなければ 「v1の値より2710が大きいのでatに0001を格納」 atの値が0001なので、bne命令で分岐が起こり addiu v1,zero,$270fの命令は実行されません (表示はli v1,$0000270f) しかし、v1(現在KO人数)が2710(10000)を超えている場合 「v1の値が2710より大きいのでatに0000を格納」 atの値が0000なのでbne命令での分岐は起こらず処理はそのまま進み addiu v1,zero,$270fを通過して値をストアする (表示はli v1,$0000270f) つまり最大値である9999を書き込むようになります ここまで分かったら、後は最大値検索パターンBのように 分岐命令をnopにするだけで最大値に修正されるので 2014344C 00000000 〜暗号化〜 1C83B774 1456E7A5 でKOカウント即9999の完成です 分岐潰しは数値をnopにするだけで可能ですが プログラムの勉強の意味を込めて他の方法も紹介します atレジスタの値が0000か0001かで分岐が決まるので slti at,v1,$2710 の命令を、atが必ず0000になるように 他の命令に書き換えてみましょう 一般的に思いつくのはaddiu命令でatに0000を代入する物です 24010000 addiu at,zero,$0000 他にも、movz命令でzeroレジスタを転送する物 0000080a movz at,zero,zero もっと複雑に、pinteh命令で書き換えてみたり 70000aa9 pinteh at,zero,zero 分岐潰しと言っても、いくつもの方法があります その時の気分で変えても良いですし 自分特有の潰し方を作るのも面白いですね。