Arbitrary code execution in Gold/Silver UE using the Coin Case
Posted by: Sanqui
Date: 2013-07-10 07:46:32
So, this exploit allows you to execute arbitrary code (i.e., jailbreak) the English version of Pokémon Gold. Unfortunately, it is much more limited than the 8F item you have grown to like from Gen 1, but it's still pretty nifty, and might pave way to a better exploit!
Long explanation
To explain. You have probably heard of the coin case glitch, where if you speak to the Machop in Vermilion and open the coin case, the game crashes. But I haven't found anybody actually studying what the game does, so I traced it and figured out why it happens.
In short, I believe the translators messed up. The text script for the Coin Case ("Coins: 1234") ends in a $57, which while a valid text ending byte, is not a valid text script byte. (The correct one would've been $50.) Since after printing the number, the game is in text script mode, the game reads an invalid pointer and, surprise, jumps into memory at $e112 (since that's ECHO RAM, it's essentially $c112). This section of RAM is used by cries. Most of the time, it's filled by zeroes, and by sheer luck ends in a ret. But if you play a cry immediately before opening the Coin Case, the memory will be tainted.
Most cries don't do much, some return successfully, some mess with the text a bit. Machop's cry is special, because it happens to contain inc sp. This causes the ret to go elsewhere, specifically, $eb12, which contains some overworld stuff… Specifically, as you move around, it has tile attributes for the window tilemap. The contents are mostly unpredictable, but consistent if you move in a specific pattern, which will lead us, to $FA98 (again, ECHO RAM, so essentially $DA98). This is in the middle of the third party Pokémon's data, which is already something we can sanely work with! You could probably hunt a Pokémon with specific EVs and stats in order to construct some opcodes, but I opted for picking a Pokémon which's data doesn't do anything and slides through to the fourth Pokémon.
The first three bytes of a Pokémon are species, item and first move. Thus, we can construct a Pokémon which "jumps" somewhere useful. I picked the PC box for this purpose: $D61A, which si the second boxed item's amount.
So, now we can get the game to execute what we can control. Unfortunately, like I warned, this method is extremely limited. Since the arbitrary code on the way tampered with the stack and random memory, one would have to carefully reconstruct these in order to return control *back* to the game after opening the Coin Case. It should be possible, but I didn't explore this. So, for now, this is an one-way trip.
Preparation
Get a Quagsire with HP Up and Sleep Talk as the first move. Put it fourth in party.
Put a valid slide Pokémon in slot 3. A low-level freshly caught or hatched Pokémon should work. (The Pokémon's data CANNOT have code which changes code flow, such as jumps, calls or rets.)
Build the code you want to execute in the PC, starting from the second item's count.
Exploit
You MUST move in specific ways, though there may be other methods.
0. Prepare everything.
1. Save & Restart, or step through a warp.
2. Take a step down and four steps right. (Three to the left might work, too?)
For example, if you were performing this trick from Elm's lab (the traditional method), you'd be standing here:
[img]http://sanqui.sweb.cz/screen/2013071014%3A44%3A34bgb-POKEMON_GLDAAUE-ab16.png[/img]
3. Listen to Machop's cry (I used the Pokédex, but party should work too)
4. Open the bag and change pockets at least once
5. Open the Coin Case
At this point, the game does a ton of wacky stuff and eventually jumps to $D61A, which should contain your code!
The state is (but it might depend on your slide Pokémon):
af=2800 bc=0f0f de=0600 hl=1c2f sp=dfbc pc=d61a rom=66
Interrupts DISABLED (?)
Final words
I don't believe this exploit works the Japanese version, but I haven't tested. It was definitely fixed in Crystal. It also may have been fixed in other language revisions.
I hope to see some cool stuff done with this, but I do realize that the set up is kind of annoying. Have fun, anyway.
Sanqui/Sanky
P.S.: As a bonus, have this nifty table! http://pastebin.com/raw.php?i=arPmsvYu
P.P.S.: Have you people really got no real IRC channel I could hang out in?