なるほどえたきちのブログじゃねーの

チラ裏雑記帳

ポケモン過去作の解析とか乱数調整とかそこら辺。不定期更新。

【Em】バグポケモン0x085Fを使用した任意コード実行

技アニメ実行とは別の任意コード実行方法が見つかったので紹介します。

このコード実行方法の特徴は以下の通りです。

  • 不正ポケモンコードを利用する
  • プログラムの直参照なのでボックスを適切な状態にしていれば100%成功する
  • 技アニメと比べて実行の手間が少ない
  • スクリプトの記述が必要ない分多くのメモリを処理の記述に使用できる


↓実践動画

以下実行手順です。

1)バグポケモン0x085Fの生成



生成に使用する個体はNPC交換のタネボー(NN:セブン)です。


f:id:BZL:20190923172314p:plain
交換にはラルトスが必要なので所持していない場合は102番道路で捕まえます。


f:id:BZL:20190923172413p:plainf:id:BZL:20190923172425p:plain
カナズミジム隣の民家にいるボーイスカウトに話しかけます。


f:id:BZL:20190923172453p:plain
ラルトスが欲しいと言われるのでタネボーと交換します。


ここで交換したタネボー努力値をH95、A8に調整します。
私は以下の通りに振りました。

マックスアップ*9

ケムッソ*5

ポチエナ*8



f:id:BZL:20190923175740p:plain
努力値の調整が終わったらこのタネボーを材料にダブルコラプションを行います。
成功するとこの画像のようなバグポケモンが生成されます。


2019/10/07 追記
実機環境ではダブコラを行わずPID破損のみ行えば生成されたタマゴを孵化させて0x085Fを入手できます。
PID破損したタマゴが生成された場合はボックス12の11匹目からボックス14の30匹目までを全て空欄にし、ボックス1の名前をボックス1『いぶたぃ び』、ボックス2の名前を『アアアyコくく』にしてからポケセンで孵化させてください。
(ポケセン外で孵化させるとフリーズします。例外が存在する可能性有り)
「おや…?」からの暗転時間が少々長い(恐らくLZ77解凍処理の不正実行によるループ)ですが、約5秒程度待機すれば正常に孵化処理が実行されます。
孵化処理後はメモリが不安定になっている可能性があるのでレポート保存後のリセットをおすすめします。


以上でバグポケモン0x085Fの生成は終了です。
この段階ではまだ0x085Fの様子は見ないでください。

2)任意コードの入力



重要:ボックス12の11匹目からボックス14の30匹目までを全て空欄にしてください。
実行されるプログラムの記述にはボックス名1-14を使用することができます。
プログラムを記述したら0x085Fの様子を見ます。
スクリプト実行の場合ボックスを閉じたタイミングで処理が発動します。
以下はコードの例です。


さいはてのことうへのワープスクリプト

ボックス ボックス名
ボックス1 『くぶ むあめあミ』
ボックス2 『アいメGタ l』
ボックス3 『いむだメえぱうチ』
ボックス4 『アのメえぶけl』
ボックス5 『ぎせ うぃVうい』
ボックス6 『アアアぐはぎ 』
ボックス7 『ねタミび』

ボックス6の『はぎ』の部分を適当な文字列に書き換えるとワープ先を任意のものに変更できます。

ワープ先 対応する文字列
みなみのことう 『はけ』
たんじょうのしま 『はげ』
へそのいわ 『はぢ』



エンディング処理実行

ボックス ボックス名
ボックス1 『 ぶ びじオぬく』




3)コード実行の原理について



完全におまけなので興味なかったら見なくていいです



エメラルドで追加された処理の内の一つにポケモンのアニメーション』というものがあり、ポケモンの種族ごとに様々なアニメーションが割り当てられています。
内部処理的にアニメーションの割り当てには1ByteのID指定と、そのIDに紐付けられたアニメーションのプログラム参照テーブル、そしてポケモンの種族とアニメーションのIDを紐付けるテーブルが使用されます。

バグポケモンは不正なポケモンコードを持っているのでポケモンコードを使用して参照されるテーブルの殆どで不正参照が行われます。(正面画像等の例外は有り)
前述した通りポケモンのアニメーションのプログラムはIDに紐付いたテーブルを参照して実行されるので、不正なIDを渡すと本来プログラムでない領域を参照させることができます。

アニメーションのプログラム参照テーブルは0x085D34E8に配置されています。
このテーブルの内容を調べると有効なアニメーションIDは0x00-0x96でそれ以降のIDは不正領域参照となっていることが分かります。
使用可能な1Byte分のIDを一通り調査した結果、プレイヤーが自由に変更できるRAMを参照させることのできるIDは0xBA(参照RAM:0x0202FFFF)のみとなりました。
0x0202FFFFのプログラム参照の場合、参照位置より先にポケモンを置かないことによってボックス名の格納RAMまで安全にアクセスすることができます。
(0xBDはボックスRAM0x0202FFFEを参照しているので一見使用できるように思えますがTHUMBステートで実行されないアドレスなので除外しています)

ポケモン毎のアニメーションIDの指定テーブルは0x082FA374に配置されているので、この領域を調査することでバグポケモンに割り当てられたIDを調べることができます。
アニメーションID0xBAを参照していて尚且生成に必要な努力値調整数の少ないバグポケモンを調べた結果、0x085Fがこの条件に合致しているのではないかと考えました。

このコード実行バグについて調査・考察した内容は以上となります。
因みにこのコード実行法はFRLGでは無理です。