RPGツクール3に簡易メモリエディタを導入して任意コードを実行する

外部ツール等を一切使わずにRPGツクール3内に簡易メモリエディタを導入して他のPS1ソフトで任意コードを実行する方法を紹介します。
 

動作環境

PS1(SCPH5500)およびPS2(SCPH70000)で動作確認済み。
おそらくPS1、PS2ならどの型番でもできると思います。
 

必要なもの

  • RPGツクール3のソフト
  • 任意コードを実行したいPS1ソフト
  • PS1メモリーカード

 

概要

やる事をざっくり説明すると

  • システムデータの上書きセーブ中にメモリーカードを引き抜くことで、2つのデータが混在した本来あり得ない形のセーブデータを作り出す。(チェックサムは調整により回避する)
  • このデータをロードして「システムデータとして編集可能なメモリ領域」の参照位置を狂わせ、本来編集不可能なメモリ領域を編集可能にする。
  • それによりモンスター編集画面のプログラムを部分的に改変し、任意のメモリアドレスの中身を任意の値に書き換え可能な簡易メモリエディタを作り出す。
  • 簡易メモリエディタによりメモリを書き換えた後、システムコールのLoadExec呼び出しにより書き換えたメモリを維持したまま他のソフトを起動する。

という流れになります。
 

導入手順

手順1:サンプルゲームのデータをロードし、ダンジョンを編集する

まず、メインメニューの[サンプルロード]を選択してサンプルゲーム(ゴブリくんの冒険)のデータをロードした後、[データを作る]を選択し、エディットメニューから[ダンジョン]を選択して以下の操作を行います。
 

  1.  [コピー]でNo28の「ヨクアル草原」をコピー元として選択し、No108の「ラスダン10」からNo114の「ラスダン16」まで順番に上書きコピー。
  2.  [編集]でNo51の「END」を選択し、名前を ウオイエツッッア に変更し、「データを更新して終わる」で終了。
  3.  No1の「オープニング」を選択し、背景を0番に変更し、「データを更新して終わる」で終了。
     

手順2:システムデータのセーブ

メインメニューに戻り、[メモリーカード]→[データセーブ]→[システムデータ]と選択してセーブします。(6ブロック)
 

手順3:システムデータの上書きセーブ

もう一度[サンプルロード]でサンプルゲームのデータをロードし、何も編集せずにそのまま先程のデータに上書きする形でセーブします。1つ目の●が点灯して2ブロック目の書き込みが始まったらメモリーカードを引き抜いて強制的にセーブを中断します。
(2ブロック目と3ブロック目は全く同じデータになるように調整してあるので、この範囲の書き込み中ならどこで引き抜いても問題ありません)
 

手順4:モンスターの移動

メモリーカードを挿入し、先程のシステムデータをロードします。
エディットメニューから[モンスター]を選択し、[移動]でNo10の「スピリット」をNo210に、No7の「イタチ」をNo127に移動し、「データを更新して終わる」で終了します。
 

手順5:ダンジョンの削除

[ダンジョン]を選択し、[削除]でNo108からNo114までのダンジョンを全て削除します。
この際、必ずNoが小さい方から順番に削除していくようにします。
 

手順6:モンスター配置の編集

[モンスター配置]を選択し、[編集]でNo20の「ボスキャラ城」を選択します。
[モンスター選択]で↓のように上から4、5、6番目をNo210の「スピリット」、No127の「イタチ」、No15の「エルフ」に変更し、「データを更新して終わる」で終了します。

データ無し
データ無し
データ無し
スピリット
イタチ
エルフ
データ無し
データ無し

 

手順7:モンスターの編集

[モンスター]を選択し、[編集]でNo24、31、No32、No33のパラメーターを以下の値に変更します。(Noが小さい方から順番に編集すること)
(△がついているものは負数もしくは上限値を超える値が入っているので、最初に△ボタンを押して一度値を変化させた後でないと確定できないことに注意)

  No24 No31 No32 No33
りお ぼ  (HP) 28 8704 変更なし(156) 4610
      (MP) 変更なし(7956) 16 変更なし(8536) 8 △
ヘハ 逗 (攻撃力) 0 21 8225 以降変更なし
マハ   (防御力) 9299 △ 9219 130  
     (す速さ) 2 △ 11 2  
ホ   (魔法耐性) 1025 1025 △ 1025 △  
(Y     (EXP) 0  30 0 △  
と   (ゴールド) 9360 38498 △ 41096 △  

 
全て変更出来たら×ボタンを3回押し「データを更新して終わる」を選択します。
その後、No24のモンスターデータ編集画面に入ると簡易メモリエディタが導入された状態となります。
 
この簡易メモリエディタはゴールドの編集ボックスを閉じた時、その値(0から65535まで)を
[魔法耐性の値 * 256 + EXPの値]のアドレスにリトルエンディアンの2バイト値として書き込むという
機能を持ちます。
魔法耐性、EXPはともに0から9999(0x270F)まで変更可能なので、つまりこれは
メインメモリ(0x00000000から0x001fffffまで)の全範囲に任意の値を書き込み可能であるということを意味します。
 

  • 注意点
    書き込み前の値を確認する手段がないのでアドレスを間違えると基本的に修正が効きません。
    〇ボタンでも×ボタンでもゴールドの編集ボックスを閉じた時点で値が書き込まれてしまうので、誤ったアドレスのままゴールドを選択しないよう十分注意する必要があります。

 

使用例

簡易メモリエディタにより、ゲームの動作に支障が出るようなものでなければどんなコードの実行も可能になるので、システムコールのLoadExec呼び出しにより電源を入れたまま(つまり、メモリを完全に初期化させずに)他のPS1ソフトのディスクに入れ替えてそのゲームを開始することができるようになります。
これにより何らかのシステムコール(_bu_initなど)にフックを仕掛けた状態でゲームを開始できるので、事実上他のPS1ソフトでも任意コード実行が可能になります。
 
試しに「INT版FF7でニューゲーム開始時のマップをデバッグルームに書き換える」というコードを実行させてみます。
まず、LoadExecを呼び出せるよう簡易メモリエディタで以下の入力を行います。(ここは入れ替えるソフトによらず共通) 

魔法耐性 EXP ゴールド
1135 192 2
1135 194 9220
1135 196 6025
1135 198 3074
1135 200 1
1135 202 9221
魔法耐性 EXP ゴールド
1654 192 7152

 
次に、メモリアドレス0x00012bd4以降の文字列 “cdrom:\MAIN.EXE;1″ を入れ替えたいソフトのSYSTEM.CNF内のBOOTの右側に記述されている実行ファイル名(INT版FF7なら”cdrom:\SLPS_010.57;1”)に書き換えます。
 

↓

つまり、メモリアドレス0x00012bda以降に 0x535C, 0x504C, 0x5F53, 0x3130, 0x2E30, 0x3735, 0x313B と書き込む必要があるので

魔法耐性 EXP ゴールド
299 218 21340
299 220 20556
299 222 24403
299 224 12592
299 226 11824
299 228 14133
299 230 12603

と入力します。
 

次に、FF7起動後にコードを実行させる仕込みをします。
今回は_bu_init(A(70h))の関数ポインタを書き換えて、そこでゲーム開始時のマップIDを書き換えるコードを実行させてみます。
_bu_initの関数ポインタはメモリアドレス0x000003c0にあるので、ここの中身の値を0x00190000(FF7が起動して_bu_initが呼び出されるまで上書きされないメモリ領域)に書き換えます。

魔法耐性 EXP ゴールド
3 192 0
3 194 25

 
さらにメモリアドレス0x00190000以降に、ゲーム開始時のマップIDを0x41(デバッグルーム)に書き換えた後、_bu_initの関数ポインタを正常な値に戻してから_bu_init処理に戻るコードを入力します。

魔法耐性 EXP ゴールド
6400 0 852
6400 2 35842
6400 4 65
6400 6 9219
6400 8 1
6400 10 15361
6400 12 7128
6400 14 42019
6400 16 960
6400 18 44034
6400 20 8
6400 22 64
6400 24 0
6400 26 0

 
ここまでの入力が完了したらトレイを開けてINT版FF7のディスク1に交換した後、□ボタンを押すことでゲームが起動します。
直後の_bu_init呼び出しによりゲーム開始時のマップIDを書き換えるコードが一度だけ実行されるので、そのままニューゲームを選択すればデバッグルームから開始します。
 

動画

実際に実機で試してみた動画です。

コメント

タイトルとURLをコピーしました