スロットを一バイトづつずらしながらターゲットの数値を探す。
コマンドラインの精進のためのネタとしてやってみることにする。
もちろん目的はHPをマックスにすること。
- ひとつのセーブデータしかない状態にする。
- HPが271のデータをメモリカードデータから探す。
ひさしぶりのunpack
$ cat epsxe000.mcr| ruby -e 'a=STDIN.read;0.upto(a.size){|i|puts "#{i},#{a[i..i+1].unpack("s*")}"}' | egrep ",271$" 15714,271 15756,271 15758,271
現在のHPが271でHPMAXも271だから、ほぼ15756-9であることはまちがいないだろう。
- 15758-9バイト目を999にしてみる。
$ cat epsxe000.mcr| ruby -e cat epsxe000.mcr| ruby -e 'ad,v=15756,999;a=STDIN.read;a[ad..ad+1]=[v].pack("S*");STDOUT.write a'> a ; mv a epsxe000.mcr
確認もしておく
$ cat epsxe000.mcr| ruby -e 'a=STDIN.read;0.upto(a.size){|i|puts "#{i},#{a[i..i+1].unpack("s*")}"}' | egrep ",999$" 15758,999
見事。
ロードしてみると、「ロードできません」が…しまった。チェックサムでもついてるのか。
その後いろんな調査により、チェックサムの存在を確認
面倒になったのでirbで作業することにしてクリアした。
> a=File.open("epsxe000.mcr.20070720_155319").read;p a[0] > a[0x3da3]=0x3b+0x80 > a[0x3da0,1]=[0x80+0x3b].pack("S*") > a[0x2181]=(a[0x2182..0x3fff]+a[0x2180,1]).unpack("C*").inject(0){|r,i|r+i}%256 > f=File.open("epsxe000.mcr","w");f.write(a);f.close
それぞれ、行を読んで、1バイト書き換えて、2バイト書き換えて、チェックサムを計算し代入、ファイルを書き換える。
ひさしぶりにinjectで気持ちよかったのは内緒。
追記 2008/09/28 22:21:37:
チェックサムは128バイト毎の多連加算方式の場合
a=File.open("./epsxe001.mcr.bak").read ad=0x250f;a[ad],a[ad+1],a[ad+2]=0x7f,0x96,0x98 ad=0x2535;a[ad],a[ad+1]=0xe7,0x03 ad+=2;a[ad],a[ad+1]=0xe7,0x03 ad+=2;a[ad],a[ad+1]=0xe7,0x03 ad+=2;a[ad],a[ad+1]=0xe7,0x03 ad+=2;a[ad],a[ad+1]=0xe7,0x03 a[0x257f]=a[0x2500..0x257e].unpack("C*").inject(0){|r,i|r+i}%256 f=File.open("epsxe001.mcr","w");f.write(a);f.close