Site cover image

🐾 flag3

ポケットモンスター クリスタル IDくじ調整(0x1500制御コード任意コード実行)

ポケットモンスター クリスタルのRTAではラジオ塔のIDくじで1等に当選しマスターボールを入手するチャートが存在します。

上記の動画では「さいしょから はじめる」を押してタイマーを始める前に状況再現を行うことで、IDくじを01001になるように調整し、道中で入手するオニスズメ(ひきゃく)のおやのIDと一致させてマスターボールを入手しています。

本記事では状況再現を使わずに0x1500制御コードによる任意コード実行を用いてIDくじを01001にする方法について紹介します。

IDくじ調整手順

環境

ポケットモンスター クリスタルの日本語版のみに対応しています。ポケットモンスター 金・銀や日本語版以外のバージョンには対応していません。また、通信交換ができることを前提としています。ポケットモンスター 金・銀については以下の記事をご覧ください。

📄Arrow icon of a page linkポケットモンスター 金・銀・クリスタル 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: 実際のプレイ

  1. 通信交換で受け取ったメールを読んだ後にリセットをします。リセットをする前にセーブはしなくてもよいです。メールの下側に数字が出現するのは想定通りです。
    Image in a image block
  2. 「さいしょから はじめる」を選択し、ようびをにちようびにします。
  3. ようびが変わるまでにコガネシティに行き、オニスズメ(ひきゃく)を入手してからIDくじを引きます。

上記の手順でIDくじが01001となり、マスターボールを入手することができます。

Image in a image block

注意

任意コード実行をしたら、しばらくはIDくじの番号が固定されます。具体的には、ひる10じからはじめる場合は任意コード実行後10時間以内に、ひる5じ50ふんからはじめる場合は任意コード実行後17時間50以内に「さいしょから はじめる」を選択して時間を設定する必要があります。しばらくはIDくじの番号が固定されるため、RTAのやり直し等でリセットする場合でもそのまま「さいしょから はじめる」を選択してやり直しをして大丈夫です。一定時間経過するとIDが固定されなくなるので、うまくいかないと思ったら任意コード実行を適宜行うようにしてください。

おまけ1: ドードリオGBによる3倍速

ポケモンスタジアム金銀のドードリオGBを使った3倍速RTAでは、3倍速をするために殿堂入りしたソフトでプレイする必要があります。通信交換で受け取った手順1-1のメールを読んでセーブをしてからもう一度GBビルを始めることで3倍速をすることができるようになります。

おまけ2: バイナリエディタ

以下の手法で導入したバイナリエディタはわざマシン17を使うことで起動することができますが、ポケモンスタジアム金銀のGBビルで起動することはできません。

📄Arrow icon of a page linkポケットモンスター クリスタル バイナリエディタ

そこでメールを読むことでバイナリエディタを起動できるように調整を行います。メールを手持ちのポケモンの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くじの番号の仕組みについては以下で解説していますので省略します。

📄Arrow icon of a page linkポケットモンスター 金・銀・クリスタル 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モバイル関数が実行されると以下の処理が行われます:

  1. モバイルの数字を出力する関数を呼び出して数字を表示(5桁)
  2. カーソル位置が5文字分進む(C5E1→C5E6)
  3. 新しいカーソル位置アドレスC5E6をアドレスCD46とCD47にリトルエンディアンで格納
    • [$CD46] = 0xE6
    • [$CD47] = 0xC5
  4. 引数から受け取った値をその後のアドレスに配置される
    • [$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