ポケッモンスター 金・銀・クリスタルで状況再現を使わずに任意コード実行を用いてIDくじを01001にする方法について紹介したことがありました。
📄ポケットモンスター 金・銀・クリスタル IDくじ調整(任意コード実行)
ただしこの手法ではRTAなどで周回をする際、毎回任意コード実行環境を整える必要があり手間がかかってしまいます。
本記事ではポケットモンスター クリスタルで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 | 3E |
00 | A80C | 03 |
00 | A80D | 22 |
00 | A80E | 3E |
00 | A80F | E9 |
00 | A810 | 77 |
00 | A811 | 11 |
00 | A812 | 34 |
00 | A813 | 01 |
00 | A814 | 37 |
00 | A815 | C9 |
このように書き換えることでパソコンにあるメールの1通目の内容を書き換えることができます。このメールはIDくじの調整を行いたいソフトに送るためのメールとなります。クリスタルではこのメールを読む際にフリーズすることなくバンク00のアドレスAC90からAC92までの中身が 01 03 E9
になることを確かめてください。金・銀ではこのメールを読んでも何も起きません。
手順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 | 11 | 11 |
00 | A615 | 34 | 23 |
00 | A616 | 01 | A8 |
00 | A617 | C9 | 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で複製させておくと良いです。
アドレスに関する補足
ポケットモンスター 金・銀・クリスタルでは、メールは以下の場所に格納されます。
手持ちのポケモンのメール
- 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 | メール著者名 |
2 | メール著者のID |
1 | ポケモンの種類 |
1 | メールの種類 |
手順2: 実際のプレイ
- 通信交換で受け取ったメールを読んだ後にリセットをします。リセットをする前にセーブはしなくてもよいです。
- 「さいしょから はじめる」を選択し、ようびをにちようびにします。
- ようびが変わるまでにコガネシティに行き、オニスズメ(ひきゃく)を入手してからIDくじを引きます。
上記の手順でIDくじが01001となり、マスターボールを入手することができます。

注意
任意コード実行をしたら、しばらくはIDくじの番号が固定されます。具体的には、ひる10じからはじめる場合は任意コード実行後10時間以内に、ひる5じ50ふんからはじめる場合は任意コード実行後17時間50以内に「さいしょから はじめる」を選択して時間を設定する必要があります。しばらくはIDくじの番号が固定されるため、RTAのやり直し等でリセットする場合でもそのまま「さいしょから はじめる」を選択してやり直しをして大丈夫です。一定時間経過するとIDが固定されなくなるので、うまくいかないと思ったら任意コード実行を適宜行うようにしてください。
おまけ: 殿堂入り
ポケモンスタジアム金銀のGBビルを使った3倍速RTAでは、3倍速をするために殿堂入りしたソフトでプレイする必要があります。以下は任意コード実行で殿堂入りをするための方法となります。
IDくじ調整を行いたいソフトとは別のソフトを使います。メールを手持ちのポケモンの1匹目に持たせてください。メールの内容は何でも良いです。手持ちのポケモンの1匹目にメールを持たせた後バイナリエディタを使って特定のアドレスの中身を以下のように書き換えてください。
バンク | アドレス | 中身 |
---|---|---|
00 | A600 | A0 |
00 | A601 | 91 |
00 | A602 | 4F |
00 | A603 | 15 |
00 | A604 | 08 |
00 | A605 | 05 |
00 | A606 | C9 |
00 | A607 | 00 |
00 | A608 | 3E |
00 | A609 | 80 |
00 | A60A | E0 |
00 | A60B | A0 |
00 | A60C | 26 |
00 | A60D | D0 |
00 | A60E | 2E |
00 | A60F | 02 |
00 | A610 | CD |
00 | A611 | 99 |
00 | A612 | 31 |
00 | A613 | 11 |
00 | A614 | 34 |
00 | A615 | 01 |
00 | A616 | 37 |
00 | A617 | C9 |
このように書き換えることで手持ちのポケモンの1匹目に持たせたメールの内容を書き換えることができます。このメールを通信交換で輸送することでIDくじ調整を行いたいクリスタルのソフトでメールを読んでからメニューを閉じることで殿堂入りをすることができます。IDくじ調整を行いたいソフトとは別のソフトがクリスタルである場合は通信交換で輸送する前に殿堂入りすることができるか確認することができます。
技術的補足
IDくじの番号の仕組みについては以下で解説していますので省略します。
📄ポケットモンスター 金・銀・クリスタル IDくじ調整(任意コード実行)
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 [実行したいコード] 11 34 01 37 C9
各部分の詳細:
- 0x4F(改行制御文字)
- テキストを下の行に表示する制御文字
- カーソル位置を0xC5E1に固定する効果がある
- これにより後続の処理で使用されるアドレスが予測可能になる
- 0x15(モバイルスクリプトモード)
- テキストエンジンをモバイルスクリプトモードに切り替える
- 0x08(モバイル関数の呼び出し)
- この関数は次の2バイトを引数として受け取る
- 0x05 0xC9(引数)
- 0x08モバイル関数への引数
- 0x05は$CD48に、0xC9は$CD49に書き込まれる
- 0x05は表示する数字の桁数を指定(5桁)
- 0x00(グリッチトリガー)
- 本来は無効なモバイル関数番号
- $CD46へのジャンプを引き起こす
0x08モバイル関数の動作
0x08モバイル関数が実行されると以下の処理が行われます:
- MobilePrintNum関数を呼び出して数字を表示(5桁)
- カーソル位置が5文字分進む(0xC5E1 → 0xC5E6)
- 新しいカーソル位置0xC5E6を$CD52-$CD53にリトルエンディアンで格納
- $CD46 = 0xE6
- $CD47 = 0xC5
- 引数から受け取った値も近くのアドレスに配置される
- $CD48 = 0x05
- $CD49 = 0xC9
結果として、$CD46からのメモリは以下のようになります:
CD46: E6 C5 05 C9
グリッチ発生時の動作
0x00によってグリッチが発生すると、$CD46にジャンプして以下のコードが実行されます:
WRA0:CD46 E6 C5 and a,C5
WRA0:CD48 05 dec b
WRA0:CD49 C9 ret
これらの命令は「安全なスライド命令」として機能し、最終的にret命令によって0x00の直後のアドレス(つまり[実行したいコード]の部分)に制御が戻ります。
ペイロード実行後の処理
メインのコード実行後、最後の11 34 01 37 C9
が実行されます:
11 34 01 ; ld de,0134
37 ; scf (キャリーフラグをセット)
C9 ; ret
この処理により、モバイルスクリプトモードのメインループに戻り、キャリーフラグがセットされているため正常終了として扱われます。またテキストコマンドの処理の関係でプログラムを終了する前にdeレジスタの中身を50にする必要があるため、ret命令で終了する前にdeレジスタを0134にして中身を50にしています。