【技術検証に関する法的注意事項・免責事項】
本記事に掲載されているメモリ解析、Luaスクリプト実行、およびAIコード生成に関する技術情報は、自らが所有するゲームソフトおよびオフライン環境における技術研究・教育目的の検証記録です。著作権法第47条の3に配慮し、複製ROMの配布、コピーガードの回避(DRM解除)、オンライン環境での不正操作(BOT化)等に関する情報は一切取り扱いません。掲載情報の実行によって生じた損害について、当ブログは一切の責任を負いかねます。
※本記事にはアフィリエイト広告(PR)を含みます。
難易度:中級 ★★☆/対象環境:BizHawk(最新安定版)+Windows/対象ソフト:ご自身が所有するゲーム(ファミコン版RPGを例に解説)。オフラインでの技術検証)
この記事でできること(結論)
この記事では、エミュレーター BizHawk の RAM Search(メモリ検索)を使って、ゲーム内の「HP(体力)」や「キャラクターの座標(X・Y位置)」が入っているメモリアドレスを自分で特定する手順を解説します。ポイントは、RAM Searchの絞り込み条件(Equal / Not Equal / Greater Than など)をどう組み立てるかを Claude(AI)に相談しながら候補を減らしていくところです。うまくヒットしない失敗と、その立て直しまで含めて記録しました。改造やチートを目的とするものではなく、ゲーム内部の値がどこにあるかを「解析して状態を検証する」ための実践手順です。
この記事は前回の「メモリ値を画面に表示する(出力側)」と対になる「値のアドレスを特定する(入力側)」の回です。表示のしかたを先に知りたい人は、末尾の「次に読む」から前回記事へどうぞ。
前提環境
| 項目 | 内容 |
|---|---|
| エミュレーター | BizHawk(公式配布の最新安定版) |
| OS | Windows 10 / 11 |
| 対象ソフト | 自分が所有するゲーム(本記事はファミコン版RPGを例に解説) |
| 使う機能 | Tools → RAM Search(絞り込み)/ RAM Watch(確定後の常時監視) |
| 使うAI | Claude(絞り込み条件の設計・行き詰まったときの立て直しに使用) |
ROMやBIOSの入手方法・配布については本記事では一切扱いません。あくまで自分が所有するソフトを、自分のオフライン環境で技術的に調べることが前提です。
手順の全体像
「アドレスを特定する」とは、たくさんあるメモリの中から、目的の値(HPや座標)と同じ動きをする1個を絞り込む作業です。やることは次の3ステップです。
- 探したい値の性質(増える/減る/変わらない)を決める
- その性質に合うRAM Searchの絞り込み条件をくり返して候補を減らす
- 残った候補を RAM Watch で監視し、目的の値と連動するものを確定する

ステップ1:RAM Searchを開いて「初回スキャン」する
RAM Search は「前回の値と比べて、どう変化したメモリか」で絞り込む機能です。まずは基準を作ります。
- BizHawk のメニューから Tools → RAM Search を開く。
- 対象のメモリ領域(多くのファミコンソフトでは RAM ドメイン)を選ぶ。
- 値のサイズを設定する。HPや座標は 1 Byte か 2 Byte のことが多いので、まずは対象に合わせて選ぶ(迷ったら後述のとおりAIに相談)。
- 「新規検索(Start new search)」を押して、現在のメモリ全体を基準として取り込む。
この時点では候補は数千〜数万件あります。ここから性質に合わせて削っていきます。
ステップ2:AIに「絞り込み条件」を設計してもらう
ここが今回の肝です。HPや座標は「どう変化させれば見つけやすいか」がそれぞれ違います。自己流でやると候補が減らないので、条件の組み立てをClaudeに相談しました。実際に送ったプロンプトがこちらです。
あなたはBizHawkのRAM Searchに詳しいアシスタントです。
自分が所有するファミコンRPGで、次の値のメモリアドレスをRAM Searchで特定したいです。
それぞれについて、RAM Searchの「比較条件」を使った絞り込み手順を、
操作を再現できる形(何回・どういう順で条件を変えるか)で書いてください。
(1) 主人公のHP … 戦闘でダメージを受けると減り、回復すると増える
(2) フィールド上のキャラの座標(X, Y) … 歩くと1マスずつ規則的に増減する
制約:
- ROMや値の中身は書き換えない(読み取りだけ)
- 使う条件は Equal / Not Equal / Greater Than / Less Than / Previous Value を前提
- 候補が減らないときの「立て直し方」も一緒に
ポイントは、探す値がどう変化するか(増減の条件)を具体的に伝えることです。ここが曖昧だと、AIは一般論しか返してこず、絞り込みが空振りします。
ステップ3:AIが提案した絞り込み手順
返ってきた手順を、実際の操作に落とすとこうなりました。
HPの絞り込み(増減する値の探し方)
- 戦闘に入る直前に 新規検索。
- ダメージを受けてHPを減らす → RAM Search で 「Less Than(前回値より小さい)」で絞り込む。
- 回復してHPを増やす → 「Greater Than(前回値より大きい)」で絞り込む。
- 何もしないターン → 「Equal(前回と同じ)」で、動かなかったものを残す/消す。
- 2〜4を数回くり返すと候補が数件まで落ちます。
座標の絞り込み(規則的に増減する値の探し方)
- 立ち止まった状態で 新規検索。
- 右(または下)に1マス歩く → 片方の軸が増えるはずなので 「Greater Than」。
- 左(または上)に1マス歩く → 「Less Than」。
- その場で動かない → 「Equal」。
- X軸とY軸は別アドレスなので、1軸ずつ絞ると混ざりません。
ステップ4:うまくいかなかった失敗と、立て直し
提案どおりにやっても、最初は座標がまったくヒットしませんでした。候補が0件になってしまったのです。原因を切り分けるため、状況をそのままClaudeに投げました。
座標の絞り込みで、Greater Than を1回かけたら候補が0件になりました。
歩数は1マスだけ動かしています。考えられる原因と、やり直しの手順を教えてください。
返ってきた指摘は次の3点で、どれも「あるある」でした。
① 値のサイズが違っていた
座標を 1 Byte で検索していたが、実際は 2 Byte(画面をまたぐと256以上になる)だった、というパターン。サイズを 2 Byte に変えて新規検索からやり直すと、今度は候補が残りました。
② 「1マス」が内部では複数フレームの移動だった
歩行アニメ中は座標が連続的に少しずつ変化します。アニメが終わって止まってから比較すると、増減がきれいに出ます。動作の途中で条件をかけると空振りします。
③ 表示上の値と内部の値がズレていた(HPの場合)
HPは「画面表示(10進の見た目)」と「内部の生の値」が一致しないことがあります。Previous Value との差分で追う(見た目の数字そのものではなく“減った・増えた”で絞る)と安定しました。
📌 この記事は手順(型)の解説版です。実際に特定できた具体的なアドレス値(例:0x00XXXX)と、絞り込みが減っていく様子のGIFは、実機検証の記録として後日この記事に追記します。まずはあなた自身の環境で上の手順を再現し、出てきた候補を次のステップで確定してください。
ステップ5:RAM Watchで候補を確定する
候補が数件まで減ったら、あとは目的の値と本当に連動しているかを目で確かめます。
- RAM Search の候補を選び、右クリック →「Add to RAM Watch」で RAM Watch に登録する。
- RAM Watch(Tools → RAM Watch)を開いて、候補アドレスを一覧で監視する。
- ゲーム内でHPを減らす/キャラを動かすと、ぴったり同じ動きをするアドレスが1つ見つかります。それが目的のアドレスです。
- 確定したアドレス(例:
0x00XXXX)を控えておきます。次はこのアドレスを、前回記事のLuaテンプレで画面表示できます。
コピペ用:確定アドレスを監視するLua(テンプレ)
アドレスが確定したら、動作確認として値を画面に出しておくと安心です。addr を自分で特定した値に置き換えてください(読み取り関数・領域は環境に合わせて調整)。
-- ===== 確定アドレスの値を監視する最小テンプレ(BizHawk / Lua)=====
-- 対象: 自己所有ソフトのオフライン技術検証
memory.usememorydomain("RAM") -- 読む領域を明示(環境に合わせて変更)
local addr = 0x00XXXX -- RAM Searchで特定したアドレス
local label = "HP" -- 表示ラベル(HP / X / Y など)
while true do
local v = memory.read_u16_le(addr) -- 値の型に合わせ read_u8 / read_u16_be も検討
gui.text(10, 10, label .. ": " .. v) -- 左上にオーバーレイ
emu.frameadvance()
end
よくある質問
これは「チート」や「改造」ですか?
いいえ。ここで行うのは、メモリのどこに値があるかを読み取って突き止める(状態を観測・検証する)ことだけで、ゲームデータやROMを書き換えるものではありません。仕組みの側から見れば「どのメモリがどう変化するか」という状態変化の解析です。本ブログはそれを、自己所有ソフトのオフライン環境で技術的に検証する記録として扱います。
候補がどうしても減りません。どうすれば?
多くは値のサイズ(1 Byte / 2 Byte)か比較のタイミングのズレが原因です。サイズを変えて新規検索からやり直すと、動作アニメが止まってから条件をかける、の2点をまず見直してください。それでも減らない値は「内部エンコードが特殊(BCDなど)」のことがあり、その場合は Previous Value との増減だけで追うのが有効です。
ファミコン以外(SFC・ゲームボーイなど)でも同じ手順ですか?
考え方は同じです。「性質を決める → 条件で絞る → RAM Watchで確定」という流れは全機種共通です。違うのは主にメモリドメイン(読む領域)と値のサイズ・エンディアンで、機種を変えたらこの2点を調整します。
まとめ
RAM Search でアドレスを特定するコツは、探す値の「増える・減る・変わらない」を先に決め、その性質に合う比較条件をくり返すことです。ヒットしないときは、値のサイズ・比較のタイミング・内部エンコードの3つを疑うと立て直せます。ここで特定したアドレスは、前回のLuaテンプレにそのまま差し込めば画面に表示でき、さらに値の変化に応じた処理へと応用が広がります。次回はこのアドレスを使って、HPバーを画面にオーバーレイ表示する演出に進みます。
次に読む


(近日公開)BizHawk LuaでHPバーを画面にオーバーレイ表示する
検証環境をそろえるなら
RAM Search の絞り込みやLua実行を快適に行うには、ある程度のPC性能があると作業が軽くなります。実験環境の候補は次のとおりです。
- 実験用ミニPC / ゲーミングPC を探す(Amazon)
- I-O DATA HDMIキャプチャーボード(USB 3.0接続)(Amazon)
- リバースエンジニアリングツール Ghidra実践ガイド(Amazon)
Amazonのアソシエイトとして、当ブログは適格販売により収入を得ています。
この記事の親ガイド

【予告】この5工程で使うスクリプトをまとめた「コピペで動くLua集+環境構築キット」を配布予定です。価格・配布日は未定で、決まり次第この記事に追記します。



コメント