自分用に改造したDeSmuME
- ベースになっているのはtrunkのリビジョン3771
- diff: http://gist.github.com/587467
- win32用実行バイナリ: http://oupo.xrea.jp/misc/DeSmuME-my-r3771.zip
改造箇所:
- PUSH_LR命令が実行されたときに呼ばれるemu.registerenterfunc
- 命令アドレスごとの条件付実行ログ機能 (emu.start_log_cond / emu.end_log_cond)
- ROMファイル全てをメモリに読み込まない変更 (NO_LOAD_ALL_ROM)
- memory.getregister / memory.setregister の prev_insn_addr / curr_insn_addr / next_insn_addr
- Luaを実行したときに自動的にカレントディレクトリがスクリプトのディレクトリになるように
- 命令アドレスごとの戻り値のログ機能 (emu.start_log_return / emu.end_log_return)
- Luaから逆アセンブルをファイル出力できる機能 (emu.output_disasm_arm / emu.output_disasm_thumb)
- メモリ上にあるバイト列が出来たときにコールバックを呼ぶ機能 (memory.register_bytes_pattern)
いろんな場所でフックを追加しているので当然普通のDeSmuMEより重いです
役に立つようならぜひ使ってみてください
P.S.
僕はまだポケモンBW買ってないです...
いろいろ追記で書いていく
- 自分が使っているいろんなユーティリティ関数: http://github.com/oupo/emu-scripts/blob/master/lua/myutil.lua
emu.registerenterfunc
これはなんのために作ったかっていうとスタックトレースをとりたかったから
emu.start_log_cond / emu.end_log_cond
実行アドレスごとに条件がtrueかfalseか記録する。これを二つのStateで比べたりしたらある判別をしている処理とか分かるかもしれないと思って作った
NO_LOAD_ALL_ROM
ROMファイルがでっかいと全体をメモリに読み込んでたらきついので
実装するのが面倒なのでこれ有効にすると一部の機能が無効になる
ところでファイル全体に読み込んでいたのをファイルをシークして読み込むようにする変更って、mmapとか使ったら今までのメモリアクセスのままでファイル全体はメモリに乗らないように出来たりするのかなー。
prev_insn_addr, curr_insn_addr, next_insn_addr
- prev_insn_addrはここの命令ってどっからジャンプしてきてんのってときに使う
- next_insn_addrはたとえばなにかよくわからない関数呼び出しがあって引数をいろいろたくさん変化させてみて戻り値を確かめたいってときに、関数呼び出しの次の行でmemory.setregister("next_insn_addr", ...)して関数呼び出し前に戻ったりとかして使う
emu.start_log_return, emu.end_log_return
start_log_condの戻り値版。割とこの機能はポテンシャルがあるんじゃないかと予想している
emu.output_disasm_arm / emu.output_disasm_thumb
最近はndsdisじゃなくてこっちを使っている。ndsdisは結果がいくつか間違っている箇所があったりコメントが過剰で見づらいなーと思ったので。
アドレスが小さくなる方へのジャンプとどこかの命令のジャンプ先に設定されているアドレスは先頭の記号をかえているのでそれをエディタのシンタックスハイライトで設定するとプログラムの構造がいくぶんかは見やすくなる
memory.register_bytes_pattern
あるASCIIの文字列があるんだけどメモリサーチしても見つからない、きっとメモリサーチするころにはほかの値で上書きされちゃってるんだろなーってときに使った。
こんなかんじ
memory.register_bytes_pattern(string_to_byte_array("FooBar"), function(addr) printf("addr=%.8x, pc=%.8x", addr, PC()) end)