ポケットモンスター クリスタルのRTAではラジオ塔のIDくじで1等に当選しマスターボールを入手するチャートが存在します。
上記の動画では「さいしょから はじめる」を押してタイマーを始める前に状況再現を行うことで、IDくじを01001になるように調整し、道中で入手するオニスズメ(ひきゃく)のおやのIDと一致させてマスターボールを入手しています。
本記事では状況再現を使わずに0x1500制御コードによる任意コード実行を用いてIDくじを01001にする方法について紹介します。
IDくじ調整手順
環境
ポケットモンスター クリスタルの日本語版のみに対応しています。ポケットモンスター 金・銀や日本語版以外のバージョンには対応していません。また、通信交換ができることを前提としています。ポケットモンスター 金・銀については以下の記事をご覧ください。
📄ポケットモンスター 金・銀・クリスタル IDくじ調整(任意コード実行)
手順1: 他のソフトの準備
IDくじの調整を行いたいソフトとは別のソフトを用意します。この別のソフトは金・銀・クリスタルを用意してください。赤・緑・青・ピカチュウには対応していません。また動作確認のしやすさのためクリスタルで用意することをおすすめします。IDくじの調整を行いたいソフトとは別のソフトでバイナリエディタを用意してください。
手順1-1: メールの作成
メールを作成してパソコンに転送してください。メールの内容は何でも良いです。パソコンにメールを転送した後バイナリエディタを使って特定のアドレスの中身を以下のように書き換えてください。
バンク | アドレス | 中身 |
---|---|---|
00 | A7F9 | 4F |
00 | A7FA | 15 |
00 | A7FB | 08 |
00 | A7FC | 05 |
00 | A7FD | C9 |
00 | A7FE | 00 |
00 | A7FF | CD |
00 | A800 | 7E |
00 | A801 | 06 |
00 | A802 | CD |
00 | A803 | 9D |
00 | A804 | 2F |
00 | A805 | 26 |
00 | A806 | AC |
00 | A807 | 2E |
00 | A808 | 90 |
00 | A809 | 3C |
00 | A80A | 22 |
00 | A80B | D6 |
00 | A80C | FE |
00 | A80D | 22 |
00 | A80E | 36 |
00 | A80F | E9 |
00 | A810 | 26 |
00 | A811 | D8 |
00 | A812 | 2E |
00 | A813 | 3F |
00 | A814 | CB |
00 | A815 | F6 |
00 | A816 | 11 |
00 | A817 | 34 |
00 | A818 | 01 |
00 | A819 | C9 |
上記のように書き換えることでパソコンにあるメールの1通目の内容を書き換えることができます。このメールはIDくじの調整を行いたいソフトに送るためのメールとなります。クリスタルではこのメールを読む際にフリーズしないことを確かめてください。メールを読んだ後にバイナリエディタを使って特定のアドレスとその中身が以下のようになっていることを確かめてください。なお中身の書き換えはしないでください。
バンク | アドレス | 中身 |
---|---|---|
00 | AC90 | 01 |
00 | AC91 | 03 |
00 | AC92 | E9 |
D83F | 40~7F、C0~FF | |
FF8D | 00 | |
FF8E | 00 | |
FF8F | 00 | |
FF90 | 00 |
金・銀ではこのメールを読んでも何も起きません。
手順1-2: メールの複製
メールを手持ちのポケモンの1匹目に持たせてください。メールの内容は何でも良いです。手持ちのポケモンの1匹目にメールを持たせた後バイナリエディタを使って特定のアドレスの中身を以下のように書き換えてください。
バンク | アドレス | 金・銀 | クリスタル |
---|---|---|---|
00 | A600 | AF | 4F |
00 | A601 | CD | 15 |
00 | A602 | 9D | 08 |
00 | A603 | 30 | 05 |
00 | A604 | 3E | C9 |
00 | A605 | 0A | 00 |
00 | A606 | 26 | AF |
00 | A607 | A7 | CD |
00 | A608 | 2E | 9D |
00 | A609 | F8 | 2F |
00 | A60A | 22 | 3E |
00 | A60B | 01 | 0A |
00 | A60C | 7A | 26 |
00 | A60D | 01 | A7 |
00 | A60E | 11 | 2E |
00 | A60F | 23 | F8 |
00 | A610 | A8 | 22 |
00 | A611 | CD | 01 |
00 | A612 | D6 | 7A |
00 | A613 | 30 | 01 |
00 | A614 | C9 | 11 |
00 | A615 | 23 | |
00 | A616 | A8 | |
00 | A617 | CD | |
00 | A618 | F2 | |
00 | A619 | 2F | |
00 | A61A | 11 | |
00 | A61B | 34 | |
00 | A61C | 01 | |
00 | A61D | 37 | |
00 | A61E | C9 |
このように書き換えることで手持ちのポケモンの1匹目に持たせたメールの内容を書き換えることができます。金・銀ではこのメールを読んでからバイナリエディタを開いてアドレスCF21を実行することでメール1通目の内容を10通に複製することができます。クリスタルではこのメールを読むことでパソコンにあるメールの1通目の内容を10通に複製することができます。
手順1-3: メールの輸送
手順1-1で作成したメールをポケモンに持たせて通信交換を行いIDくじの調整を行いたいソフトに移動させます。この手順1-1で作成したメールは今後も使うことになるので手順1-2で複製させておくと良いです。
手順2: 実際のプレイ
- 通信交換で受け取ったメールを読んだ後にリセットをします。リセットをする前にセーブはしなくてもよいです。メールの下側に数字が出現するのは想定通りです。
- 「さいしょから はじめる」を選択し、ようびをにちようびにします。
- ようびが変わるまでにコガネシティに行き、オニスズメ(ひきゃく)を入手してからIDくじを引きます。
上記の手順でIDくじが01001となり、マスターボールを入手することができます。

注意
任意コード実行をしたら、しばらくはIDくじの番号が固定されます。具体的には、ひる10じからはじめる場合は任意コード実行後10時間以内に、ひる5じ50ふんからはじめる場合は任意コード実行後17時間50以内に「さいしょから はじめる」を選択して時間を設定する必要があります。しばらくはIDくじの番号が固定されるため、RTAのやり直し等でリセットする場合でもそのまま「さいしょから はじめる」を選択してやり直しをして大丈夫です。一定時間経過するとIDが固定されなくなるので、うまくいかないと思ったら任意コード実行を適宜行うようにしてください。
おまけ1: ドードリオGBによる3倍速
ポケモンスタジアム金銀のドードリオGBを使った3倍速RTAでは、3倍速をするために殿堂入りしたソフトでプレイする必要があります。通信交換で受け取った手順1-1のメールを読んでセーブをしてからもう一度GBビルを始めることで3倍速をすることができるようになります。
おまけ2: バイナリエディタ
以下の手法で導入したバイナリエディタはわざマシン17を使うことで起動することができますが、ポケモンスタジアム金銀のGBビルで起動することはできません。
そこでメールを読むことでバイナリエディタを起動できるように調整を行います。メールを手持ちのポケモンの1匹目に持たせた後(ポケモンスタジアム金銀のGBビルを使わないで)バイナリエディタを使って特定のアドレスの中身を以下のように書き換えてください。
バンク | アドレス | 中身 |
---|---|---|
00 | A600 | 4F |
00 | A601 | 15 |
00 | A602 | 08 |
00 | A603 | 05 |
00 | A604 | C9 |
00 | A605 | 00 |
00 | A606 | 3E |
00 | A607 | 03 |
00 | A608 | 01 |
00 | A609 | BA |
00 | A60A | 00 |
00 | A60B | 11 |
00 | A60C | 00 |
00 | A60D | C8 |
00 | A60E | 21 |
00 | A60F | DE |
00 | A610 | AF |
00 | A611 | CD |
00 | A612 | 9D |
00 | A613 | 2F |
00 | A614 | CD |
00 | A615 | F2 |
00 | A616 | 2F |
00 | A617 | CD |
00 | A618 | AD |
00 | A619 | 2F |
00 | A61A | CD |
00 | A61B | 8A |
00 | A61C | 05 |
00 | A61D | CD |
00 | A61E | 00 |
00 | A61F | C8 |
00 | A620 | 37 |
00 | A621 | 80 |
00 | A622 | 11 |
00 | A623 | 34 |
00 | A624 | 01 |
00 | A625 | C9 |
このように書き換えることで手持ちのポケモンの1匹目に持たせたメールの内容を書き換えることができます。このメールを読むことでバイナリエディタを起動することができます。ただし上記のバイナリエディタを導入しているセーブデータで実行するようにしてください。
技術的補足
IDくじの番号の仕組みについては以下で解説していますので省略します。
📄ポケットモンスター 金・銀・クリスタル IDくじ調整(任意コード実行)
アドレスに関する補足
ポケットモンスター 金・銀・クリスタルでは、メールは以下の場所に格納されます。
手持ちのポケモンのメール
- 1匹目:00:A600-00:A629
- 2匹目:00:A62A-00:A653
- 3匹目:00:A654-00:A67D
- 4匹目:00:A67E-00:A6A7
- 5匹目:00:A6A8-00:A6D1
- 6匹目:00:A6D2-00:A6FB
パソコン
- パソコンに預けているメールの数:00:A7F8
- 1通目:00:A7F9-00:A822
- 2通目:00:A823-00:A84C
- 3通目:00:A84D-00:A876
- 4通目:00:A877-00:A8A0
- 5通目:00:A8A1-00:A8CA
- 6通目:00:A8CB-00:A8F4
- 7通目:00:A8F5-00:A91E
- 8通目:00:A91F-00:A948
- 9通目:00:A949-00:A972
- 10通目:00:A973-00:A99C
データ構造
内容 | サイズ |
---|---|
メッセージ | 33 |
メール著者名 | 5 |
メール著者のID | 2 |
ポケモンの種類 | 1 |
メールの種類 | 1 |
0x1500制御コードによる任意コード実行
0x1500制御コードによる任意コード実行はポケットモンスター クリスタルで発見された任意コード実行の手法でポケットモンスター 金・銀では実行できません。テキスト文字列内の0x15制御文字の後に0x00が続く組み合わせが関係しています。
0x15制御文字を読み込むことで次の文字を引数としてモバイルスクリプトが実行されます。次の文字の内部番号が0x01~0x0Fならばモバイル関数を実行し、0x10以上ならばモバイルスクリプトを終了する処理となっています。しかし0x00については適切に処理されずにアドレスCD46が実行されます。
Self-contained setup and bootstrapの仕組み
この記事で使用している手法は、以下の記事で「Self-contained setup and bootstrap」として紹介されている方法でpferoさんによって設計されたものです。この手法の特徴は、文字列内に0x15と0x00を配置するだけでなく、その間に特定のバイト列を挟むことで、任意コード実行の準備と実行を一つの文字列で完結させることができる点です。
構造
本記事で使用しているメールコードは、すべて以下の構造に従っています。
4F 15 08 05 C9 00 [実行したいコード]
なお実行したいコードはdeレジスタの中身を50にし、キャリーフラグを立てた状態で最後にret命令を実行する必要があります。
各部分の詳細:
- 4F(改行制御文字)
- テキストを下の行に表示する制御文字
- カーソル位置をアドレスC5E1に固定する効果がある
- これにより後続の処理で使用されるアドレスが予測可能になる
- 15(モバイルスクリプトモード)
- テキストエンジンをモバイルスクリプトモードに切り替える
- 08(モバイル関数の呼び出し)
- この関数は次の2バイトを引数として受け取る
- 05 C9(引数)
- 08モバイル関数への引数
- 05はアドレスCD48に、C9はアドレスCD49に書き込まれる
- 05は表示する数字の桁数を指定(5桁)
- 00(バグトリガー)
- 本来は無効なモバイル関数番号
- アドレスCD46へのジャンプを引き起こす
08モバイル関数の動作
08モバイル関数が実行されると以下の処理が行われます:
- モバイルの数字を出力する関数を呼び出して数字を表示(5桁)
- カーソル位置が5文字分進む(C5E1→C5E6)
- 新しいカーソル位置アドレスC5E6をアドレスCD46とCD47にリトルエンディアンで格納
- [$CD46] = 0xE6
- [$CD47] = 0xC5
- 引数から受け取った値をその後のアドレスに配置される
- [$CD48] = 0x05
- [$CD49] = 0xC9
結果として、アドレスCD46からのメモリは以下のようになります。
CD46: E6 C5 05 C9
バグ発生時の動作
00によってバグが発生すると、アドレスCD46にジャンプして以下のコードが実行されます。
WRA0:CD46 E6 C5 and a,C5
WRA0:CD48 05 dec b
WRA0:CD49 C9 ret
これらの命令は安全な命令として機能し、最終的にret命令によって00の直後のアドレス(つまり[実行したいコード]の部分)を実行します。
IDくじ調整のプログラム
説明
アドレスD014の実行でキャリーフラグを立てて、アドレスD020の実行でdeアドレスの中身が50となるように調整を行っています。なおメール本文の 21
は通信交換をする際に FE
に書き換えらえれるためメールに記述しないようにしています。
WRA0: D008 CD 7E 06 call 067E
WRA0: D00B CD 9D 2F call 2F9D
WRA0: D00E 26 AC ld h,AC
WRA0: D010 2E 90 ld l,90
WRA0: D012 3C inc a
WRA0: D013 22 ldi (hl),a
WRA0: D014 D6 FE sub a,FE
WRA0: D016 22 ldi (hl),a
WRA0: D018 36 E9 ld (hl),E9
WRA0: D01A 26 D8 ld h,D8
WRA0: D01C 2E 3F ld l,3F
WRA0: D01E CB F6 set 6,(hl)
WRA0: D020 11 34 01 ld de,0134
WRA0: D023 C9 ret
バイナリ
CD 7E 06 CD 9D 2F 26 AC 2E 90 3C 22 D6 FE 22 36 E9 26 D8 2E 3F CB F6 11 34 01 C9
メールの複製
説明
SRAMバンク00のアドレスA7F8の中身を0Aにし、1通目のメールの内容を2~10通目に複製するプログラムを記述しています。
金・銀
WRA0: CF21 AF xor a
WRA0: CF22 CD 9D 30 call 309D
WRA0: CF25 3E 0A ld a,0A
WRA0: CF27 26 A7 ld h,A7
WRA0: CF29 2E F8 ld l,F8
WRA0: CF2B 22 ldi (hl),a
WRA0: CF2C 01 7A 01 ld bc,017A
WRA0: CF2F 11 23 A8 ld de,A823
WRA0: CF32 CD D6 30 call 30D6
WRA0: CF35 C9 ret
クリスタル
WRA0: D008 AF xor a
WRA0: D009 CD 9D 2F call 2F9D
WRA0: D00C 3E 0A ld a,0A
WRA0: D00E 26 A7 ld h,A7
WRA0: D010 2E F8 ld l,F8
WRA0: D012 22 ldi (hl),a
WRA0: D013 01 7A 01 ld bc,017A
WRA0: D016 11 23 A8 ld de,A823
WRA0: D019 CD F2 2F call 2FF2
WRA0: D01C 11 34 01 ld de,0134
WRA0: D01F 37 scf
WRA0: D020 C9 ret
バイナリ
金・銀
AF CD 9D 30 3E 0A 26 A7 2E F8 22 01 7A 01 11 23 A8 CD D6 30 C9
クリスタル
AF CD 9D 2F 3E 0A 26 A7 2E F8 22 01 7A 01 11 23 A8 CD F2 2F 11 34 01 37 C9
バイナリエディタ
説明
SRAMバンク03のアドレスAFDE以降の中身をアドレスC800以降へコピーをしてC800を実行するプログラムとなっています。なおメールを使ってバイナリエディタを起動する際にはアドレス058Aを実行してLCDを有効にする必要があります。
WRA0: D008 3E 03 ld a,03
WRA0: D00A 01 BA 00 ld bc,00BA
WRA0: D00D 11 00 C8 ld de,C800
WRA0: D010 21 DE AF ld hl,AFDE
WRA0: D013 CD 9D 2F call 2F9D
WRA0: D016 CD F2 2F call 2FF2
WRA0: D019 CD AD 2F call 2FAD
WRA0: D01C CD 8A 05 call 058A
WRA0: D01F CD 00 C8 call C800
WRA0: D022 37 scf
WRA0: D023 50 ld d,b
WRA0: D024 11 34 01 ld de,0134
WRA0: D027 C9 ret
バイナリ
3E 03 01 BA 00 11 00 C8 21 DE AF CD 9D 2F CD F2 2F CD AD 2F CD 8A 05 CD 00 C8 37 50 11 34 01 C9