Site cover image

🐾 flag3

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

ポケッモンスター 金・銀・クリスタルで状況再現を使わずに任意コード実行を用いてIDくじを01001にする方法について紹介したことがありました。

📄Arrow icon of a page linkポケットモンスター 金・銀・クリスタル IDくじ調整(任意コード実行)

ただしこの手法ではRTAなどで周回をする際、毎回任意コード実行環境を整える必要があり手間がかかってしまいます。

本記事ではポケットモンスター クリスタルで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 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: 実際のプレイ

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

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

Image in a image block

注意

任意コード実行をしたら、しばらくは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くじの番号の仕組みについては以下で解説していますので省略します。

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

  1. MobilePrintNum関数を呼び出して数字を表示(5桁)
  2. カーソル位置が5文字分進む(0xC5E1 → 0xC5E6)
  3. 新しいカーソル位置0xC5E6を$CD52-$CD53にリトルエンディアンで格納
    • $CD46 = 0xE6
    • $CD47 = 0xC5
  4. 引数から受け取った値も近くのアドレスに配置される
    • $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にしています。