Wonderland Seeker

スマホの子はTOPを見てね

【ポケモン】闇市の真相に迫る【てへ】

今回紹介するのは

 

てへというどうぐです。

 

赤だとてふという名称ですが効果は一緒です。

 

別にあざとい女の子がセルフで頭こつんってしてベロを出すアレではないです。
そういうキャラ好きですけどね。

f:id:Alice_Wreath:20191004192923j:plain

こいつはかわいいけどむかつく

どうぐの内部番号ページに青文字で書いてある重要・・・でもないですがなかなか癖の強い特殊な挙動を引き起こすどうぐです。

 

どうぐコードは7B(内部番号=0x7B)

効果は0xD806へジャンプするという代物。

D806とは現在マップの野生ポケモンとのエンカウント率や出現ポケモンの種類やレベルが記録されてある場所になります。

要するにエンカウントテーブルをプログラムとして読み込みます。

※例:D807:03 24はレベル3ポッポ、D809:04 A5はレベル4コラッタ

 

このまま使ってしまうとメインメモリを破壊してしまいフリーズしてしまいます。

この動き自体は、なかよしバッヂも同じですね。

 

 

 

 

なかよしバッヂと同じ・・・?

 

 

 

 

メインメモリにジャンプする・・・

ジャンプ先のエンカウントテーブルは書き換えられる場所・・・

自分でジャンプ先のメモリを調整できる場所をプログラムとして実行・・・

 

 

そうです、「てへ」も任意コード実行に使用できるどうぐなのです。

しかしエンカウントテーブルは現在居るマップによって変動し、そもそも固定されている場所でした(固定されないと1ばんどうろにピカチュウとか出ちゃう可能性が)

では任意コード実行のどうぐとして使えないのでは?

とお思いでしょう。


しかし、エンカウントテーブルを変更できるたったひとつの冴えたやり方があります

 

 

それは

 

ラララそれは~

 

 

 

お・じ・い・さ・ん♪

 

 

 

いえ決してふざけてませんよ?

ポケモン第一世代をプレイしたことがある方ならピンと来るはずでしょう

ポケモンベガのジムリーダー命中低い大技持ちほとんどピントレンズ持ってるのマジでやめろ

 

あのトキワシティよっぱっぱーだったおじいさんです。

おじいさんからビードル相手に捕まえ方をレクチャーしてもらうことで条件を満たせます。

 

おじいさんからレクチャーしてもらう最中、

『おじいさん は モンスターボール を つかった』と表記されますよね。

 

実はこのバトルの間だけ
本当に主人公の名前が【おじいさん】に上書きされています。

もちろんバトルが終了すると元に戻る(戻らないと困る)のですが。

 

 

ところで、主人公の名前はいったいどうやって元に戻ったのでしょうか?

実はD806の先に一時的にバックアップを取ります。

もちろん名前の文字コード+50hで記録されています。

 

この状態だとLv195のギャロップやLv210のたんパンこぞうとエンカウントするようになります。

まぁトキワシティに草むらがないので意味ないですし、そもそもマップが切り替わると元通りに戻ります。

 

おや・・・?

D806の先に主人公の名前が記録される・・・?

 

この状態で「てへ」を使うとどうなるでしょうか?

まずD806は00なので何もしないを実行します。

そしてD807には主人公の名前の2文字目をコードとして実行します。

 

もしこのコードが絶対ジャンプ命令のC3なら?
C3は文字コードだと【て】がありますから名前に入力できますね。

そして続く3文字目が【ウ】4文字目が【ん】と続くと?

 

【てウん】

 

そう、現在使っているボックスの6匹目のニックネームにプログラムが飛びます。

 

しかし任意コード実行として利用するには制約が厳しいです。

前述したようにマップが書き換わるとD806の先が正しい値に上書きされます。

そうなると再びレクチャーを受けなければいけません。

言ってしまえばトキワシティ(それも建物に入ってもいけない)専用となります。

 

また、0xD806にジャンプする前にこのどうぐは名前が長いどうぐなのです。

「てへ」をどうぐ欄に表示させると分かりやすいですが、

画面下部に豆腐が出ます。

f:id:Alice_Wreath:20191004203504p:plain

ネオ・グリーン様より転載

これはメッセージの改行を求める文字コードが入っているせいかと。

 

どういうことかと言うとフィールド画面の上1行目、左から6行目の範囲内に50のマップチップ(トキワシティなら池のあたりがセーフゾーン)がないと使った瞬間フリーズします。

50のマップチップはトキワシティなら森のような木が該当します。

いあいぎりで切れない木がそれです。

 

フリーズするのは恐らく制御にも使われている50が必要だからでしょう(未検証)

 

そのため、任意コード実行はできるけど条件が厳しい上にフリーズ地帯があるとかいう非常に癖が強いどうぐということですね。

 

ここで終わりならわざわざ特設ページなど作りませんよ?

他にも使いにくすぎる任意コード実行どうぐがまだ3種もありますし。

 

むしろここからが「てへ」の真骨頂です。

 

先ほど、名前が長いどうぐでもあると述べましたよね。

 

一見どうぐ欄を見づらくしたりスクロールを面倒にさせるおじゃまぷよに思えますが、
こういったどうぐにしか出来ない裏技があるのです

 

話は変わりますが、

【闇ショップ】(【闇市】)という名称は聞いたことがありますか?

リアルの方ではありませんよ、初代ポケモンにおけるバグのひとつです。

 

聞いたことがないという方は普通のトレーナーです。


聞いたことがある、もしくはやったことがある方は、

密輸業者です、トレーナーという肩書きは剥奪されました。

 

ちなみに知らない人向けに闇ショップを出すとこうなる画像を用意しました。

f:id:Alice_Wreath:20191004205050p:plain

 

やったことがあっても、どうして発生するかまで知ってる方は少ないでしょう。

というわけでありすのパーフェクトしょっぷ教室を始めます。

 

最初にフレンドリィショップの仕組みについて解説します。

うりにきた を選択すると、どうぐ欄を開いて売る枠が描写されますね。

 

このプログラムは16E5hのメモリです。

コアとなる部分はサブルーチン385chでそのプログラムはCD68~CF45へコピーする処理を行います。

まずサブルーチン37A1hによって内部コードに対応する文字データからCD68へ20byteコピーされます、これは名前の長さに関係なく20byteコピーしていきます。

例:内部コード01なら【マスターボール終端】ではなく、
マスターボール終端ハイパーボール終端スーパー】までコピー。

 

そしてコアとなるサブルーチン385chでそのプログラムはCD65~CF45へコピーする処理を行います。
ただし通常のコピーと異なり50hがきたところでコピーを終了します。

 

ショップで売っているどうぐは店員に話しかけると内部RAM領域に保管されます。
CF62:売っているどうぐの数
CF63:売っているどうぐ1個目のコード
CF64:売っているどうぐ2個目のコード
CF65~:同様に売りもののコード
最後に売っている数+1個目にFF(やめる)を記録します、もしCF67のどうぐで終わりならCF68がFF(やめる)ですね。

 

しかし売却画面で闇市化するどうぐでAを押すとこの内部RAM領域の部分が書き換わるのです。

※当然、ふつうのどうぐなら書き換わらないのでバグらない。
※また、バグどうぐでも名前のbyte数が短ければバグらない。


これが販売されるどうぐがバグる原因となるわけですね。

 

 

・・・ついていけてますか?

んにゃぴ……となった方がほとんどだと思いますので、

ここから上記の説明で出現したプログラムの解説を交えながらお話します。

 

いきなりですが核心部分から突いていきましょう。

 

 

なぜ闇ショップ化するどうぐでAを押すと売り物がバグるのか

 

これについては、まずCD68~CF45へコピーするという処理について説明します。
CD68~とCF45~は、どちらも「名前のデータ」を格納する領域です。

上でも出てきた【マスターボール】が「名前のデータ」ですね。

 

そして解析中に「名前のデータ」のメモリ周辺を追いかけていたのですが、

そのROMの所々には
01 68 CD
01 45 CF
というコードが書いてありました。

 

文字コードに変換すると、
イ゛I へ
イ゛ぴ ま
という文字になります。

f:id:Alice_Wreath:20191004210042p:plainこのコードこそが「名前のデータ」を呼び出すスタックでした

CD68とCF45のメモリが文字コードにもあったので確実にこれでしょう

 

 

 

 

では、次に闇ショップ化に関係なくバグどうぐのデータ自体を見てみます。
本来それはどうぐとしてのデータの領域ではないのでメインメモリ等に直接ジャンプする処理を行うケースが多いです。
「なかよしバッヂ」もそのケースに当てはまります。

 

となると、名前の20byte以内に50hがないことがあるケースもあります。

「てへ」がそのケースに当てはまります。

 

さて、売り物の名前は通常のコピーと異なり50hがきたところでコピーを終了すると上で書きましたね。

もしどうぐの名前の20byte以内に50hが見つからないとどうなるでしょうか?

 

50hを見つけるまでコピーを続けていきます
そのコピー範囲は21byte以降の名前でない場所までコピーし続けます

 

このコピー処理こそ闇ショップ化するトリガーなのです

 

50hを見つけるまで処理を続けるってまるでどこかしらドアに似てますね

 

結果としてCD7Ch以降が、CF59h以降にコピーされていきます。
ではコピーされたそのデータとはいったいどこなのか?

 

CD68~CD7Bまでの20byteが名前の格納領域というのは再三書きましたね。

その後ろのCD7Cにはサブルーチン372Chによって、ある情報が360byte分書き込まれいます。

 

CD7Cに書き込まれるのは、画面のタイル情報です

 

タイル情報っていうのは言葉だけで説明するより図を見たほうが早いです。

f:id:Alice_Wreath:20191004211555p:plain

上の使いまわし?メモリの容量節約です

上の図を見ましょう。

まず画面を8ドット*8ドットに区切り、この1ブロックの画像を「タイル」と呼びます。
もちろん画像にもそれぞれ内部コードが設定されています。


その値が左上から順に書き込まれており、

タイルは常に横20タイル*縦18タイルなので、計360byte分の情報が書き込まれるのです。

 

ちなみにタイル情報は、ことあるごとにコピーされています。

○メニューを開き、どれかで(どの項目でもOK)Aを押す
○バトル中、「ポケモン」または「どうぐ」でAを押す

このどちらかの行動を取るとCD7C~に書き込まれるようになっています。

 

なぜタイル情報がコピーされるのか?
画面をスムーズに元に戻すためです。

 

どうぐ欄を閉じて元のメニュー画面に戻るときにコピーしておいたデータを画面に書き込んでスムーズに元の状態に戻るようにしているんですね。

至るところにメモリの削減事情が伺えます。だからこそ脆弱なのですが

 

さて、もうお分かりですよね?

名前が20byte以上のどうぐを選択するとこの情報がコピーされるのです。

この選択というのは売却する場合に限った話じゃありません。

 

「てへ」で任意コード実行を行う解説の際に、

フィールド画面の上1行目、左から6行目の範囲内に50のマップチップがないとつかうを選択した瞬間にフリーズすると書いてますね。

これもタイル情報を参照しているのが原因、という訳でした。

 

長くなりましたが、結論を出すと

 

タイルの内部コードにも50hが入ってるので
名前が20byte以上のどうぐを売却した時にそのコードまでのコピーを行います

つまり、闇市の売り物は最後にCD7C~に書き込まれた画面のタイル情報がどうぐとしてコピーされたものが正体です

 

 

どうでしょう、これが「てへ」の効果です。

・任意コード実行だけなら、参照するメインメモリへのジャンプ値を変動できればOK

・闇ショップ化だけなら、名前が20byteを超えていればOK

 

しかし両方を兼ね備えたどうぐは255種類のどうぐの中でも「てへ」のみなのです。

 

あ、そうそう

エンカウントテーブルをプログラムとして実行するという性質も「てへ」特有ですが

その性質を利用した、ポケモンをよぶ笛あるいは密輸なる技もあるそうですけど
実用性に乏しいためこのブログでは紹介は省略させていただきます

⇒結局紹介しました。

 

代わりといってはなんですが

闇ショップのテクニック・任意どうぐ購入
(今名付けた)をお教えして〆ます

 

f:id:Alice_Wreath:20191004230345p:plain

このデータ「てへ」任意コードできないじゃん……

 

 

 

 

 

 

 

1.この場所でメニューを開きます

2.ほしいどうぐと同じ内部コードを持つわざを覚えているポケモンを「ポケモン」から確認します

3.ならびかえでFFよりも1つ上
要は1番下に並び替えてメニューを閉じます

4.闇ショップで36~39番目の売り物(わざの内部コードをコピーしている場所)が
一致するコードのどうぐになります
※例:わざの1番目がはたく(01)→36番目がマスターボール(01)

 

以上、「てへ」の解説ページおよびに闇ショップの原理についてでした

久しぶりに裏技サイトっぽいことしたな・・・

 

EXIT