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 15
00 A7FA 0A
00 A7FB C9
00 A7FC 00
00 A7FD CD
00 A7FE 7E
00 A7FF 06
00 A800 CD
00 A801 9D
00 A802 2F
00 A803 26
00 A804 AC
00 A805 2E
00 A806 90
00 A807 3C
00 A808 22
00 A809 D6
00 A80A FE
00 A80B 22
00 A80C 36
00 A80D E9
00 A80E 26
00 A80F D8
00 A810 2E
00 A811 3F
00 A812 CB
00 A813 F6
00 A814 11
00 A815 A5
00 A816 13
00 A817 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 15
00 A601 CD 0A
00 A602 9D C9
00 A603 30 00
00 A604 3E AF
00 A605 0A CD
00 A606 26 9D
00 A607 A7 2F
00 A608 2E 3E
00 A609 F8 0A
00 A60A 22 26
00 A60B 01 A7
00 A60C 7A 2E
00 A60D 01 F8
00 A60E 11 22
00 A60F 23 01
00 A610 A8 7A
00 A611 CD 01
00 A612 D6 11
00 A613 30 23
00 A614 C9 A8
00 A615 CD
00 A616 F2
00 A617 2F
00 A618 11
00 A619 A5
00 A61A 13
00 A61B 37
00 A61C C9

このように書き換えることで手持ちのポケモンの1匹目に持たせたメールの内容を書き換えることができます。金・銀ではこのメールを読んでからバイナリエディタを開いてアドレスCF21を実行することでメール1通目の内容を10通に複製することができます。クリスタルではこのメールを読むことでパソコンにあるメールの1通目の内容を10通に複製することができます。

手順1-3: メールの輸送

手順1-1で作成したメールをポケモンに持たせて通信交換を行いIDくじの調整を行いたいソフトに移動させます。この手順1-1で作成したメールは今後も使うことになるので手順1-2で複製させておくと良いです。

手順2: 実際のプレイ

  1. 通信交換で受け取ったメールを読んだ後にリセットをします。リセットをする前にセーブはしなくてもよいです。
  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 15
00 A601 0A
00 A602 C9
00 A603 00
00 A604 3E
00 A605 03
00 A606 01
00 A607 BA
00 A608 00
00 A609 11
00 A60A 00
00 A60B C8
00 A60C 26
00 A60D AF
00 A60E 2E
00 A60F DE
00 A610 CD
00 A611 9D
00 A612 2F
00 A613 CD
00 A614 F2
00 A615 2F
00 A616 CD
00 A617 8A
00 A618 05
00 A619 CD
00 A61A 00
00 A61B C8
00 A61C 11
00 A61D A5
00 A61E 13
00 A61F 37
00 A620 C9

このように書き換えることで手持ちのポケモンの1匹目に持たせたメールの内容を書き換えることができます。このメールを読むことでバイナリエディタを起動することができます。ただし上記のバイナリエディタを導入しているセーブデータで実行するようにしてください。

Image in a image block

技術的補足

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」として紹介されている方法に手を加えたものです。この手法の特徴は、文字列内に0x15と0x00を配置するだけでなく、その間に特定のバイト列を挟むことで、任意コード実行の準備と実行を一つの文字列で完結させることができる点です。

構造

本記事で使用しているメールコードは、すべて以下の構造に従っています。

15 0A C9 00 [実行したいコード]

なお実行したいコードはdeレジスタの中身を50にし、キャリーフラグを立てた状態でret命令を実行する必要があります。

以下のような記述がありますが 0A を使う方は特に問題なく動きます。 0B を使うsecond setupの方が動きません。

The first setup might not work on Japanese versions, due to the behavior of mobile function 0x0A being different.

各部分の詳細:

  • 15(モバイルスクリプトモード)
    • テキストエンジンをモバイルスクリプトモードに切り替える
  • 0A(モバイル関数の呼び出し)
    • この関数は次の1バイトを引数として受け取る
  • C9(引数)
    • 0Aモバイル関数への引数
    • C9はアドレスCD49に書き込まれる
    • C9と0Fとの論理積の結果09がアドレスCD48に書き込まれる
  • 00(バグトリガー)
    • 本来は無効なモバイル関数番号
    • アドレスCD46へのジャンプを引き起こす
0Aモバイル関数の動作

0Aモバイル関数が実行されると以下の処理が行われます:

  1. 引数から受け取った値をアドレスCD49に、引数から受け取った値と0Fとの論理積をアドレスCD48に配置する
    • [$CD48] = 0x09
    • [$CD49] = 0xC9
  2. カーソル位置アドレスC52EをアドレスCD46とCD47にリトルエンディアンで格納
    • [$CD46] = 0x2E
    • [$CD47] = 0xC5

結果として、アドレスCD46からのメモリは以下のようになります。

CD46:
2E C5 09 C9
バグ発生時の動作

00によってバグが発生すると、アドレスCD46にジャンプして以下のコードが実行されます。

WRA0:CD46 2E C5            ld   l,C5
WRA0:CD48 09               add  hl,bc
WRA0:CD49 C9               ret

これらの命令は安全な命令として機能し、最終的にret命令によって00の直後のアドレス(つまり[実行したいコード]の部分)を実行します。

IDくじ調整のプログラム

説明

アドレスD012の実行でキャリーフラグを立てて、アドレスD01Dの実行でdeアドレスの中身が50となるように調整を行っています。なおメール本文の 21 は通信交換をする際に FE に書き換えらえれるためメールに記述しないようにしています。

WRA1:D006 CD 7E 06         call 067E
WRA1:D009 CD 9D 2F         call 2F9D
WRA1:D00C 26 AC            ld   h,AC
WRA1:D00E 2E 90            ld   l,90
WRA1:D010 3C               inc  a
WRA1:D011 22               ldi  (hl),a
WRA1:D012 D6 FE            sub  a,FE
WRA1:D014 22               ldi  (hl),a
WRA1:D015 36 E9            ld   (hl),E9
WRA1:D017 26 D8            ld   h,D8
WRA1:D019 2E 3F            ld   l,3F
WRA1:D01B CB F6            set  6,(hl)
WRA1:D01D 11 A5 13         ld   de,13A5
WRA1:D020 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 A5 13 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

クリスタル

WRA1:D006 AF               xor  a
WRA1:D007 CD 9D 2F         call 2F9D
WRA1:D00A 3E 0A            ld   a,0A
WRA1:D00C 26 A7            ld   h,A7
WRA1:D00E 2E F8            ld   l,F8
WRA1:D010 22               ldi  (hl),a
WRA1:D011 01 7A 01         ld   bc,017A
WRA1:D014 11 23 A8         ld   de,A823
WRA1:D017 CD F2 2F         call 2FF2
WRA1:D01A 11 A5 13         ld   de,13A5
WRA1:D01D 37               scf  
WRA1:D01E 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 A5 13 37 C9

バイナリエディタ

説明

SRAMバンク03のアドレスAFDE以降の中身をアドレスC800以降へコピーをしてC800を実行するプログラムとなっています。なおメールを使ってバイナリエディタを起動する際にはアドレス058Aを実行してLCDを有効にする必要があります。

WRA1:D006 3E 03            ld   a,03
WRA1:D008 01 BA 00         ld   bc,00BA
WRA1:D00B 11 00 C8         ld   de,C800
WRA1:D00E 26 AF            ld   h,AF
WRA1:D010 2E DE            ld   l,DE
WRA1:D012 CD 9D 2F         call 2F9D
WRA1:D015 CD F2 2F         call 2FF2
WRA1:D018 CD 8A 05         call 058A
WRA1:D01B CD 00 C8         call C800
WRA1:D01E 11 A5 13         ld   de,13A5
WRA1:D021 37               scf  
WRA1:D022 C9               ret  
バイナリ
3E 03 01 BA 00 11 00 C8 26 AF 2E DE CD 9D 2F CD F2 2F CD 8A 05 CD 00 C8 11 A5 13 37 C9