Type 0xD0 move glitch: Difference between revisions

Jump to navigation Jump to search
Content added Content deleted
m (Text replacement - "http://forums.glitchcity.info" to "https://forums.glitchcity.info")
No edit summary
Line 46: Line 46:


==Technical information==
==Technical information==

When viewing the party screen or the move screen, the game displays small pokémon icons and animates them based on their current hit point values and status. While it is doing this, the game stores the animation data in a structure starting from address $C51C, which lies right beyond the end of screen tile data at $C508. The game can store and animate up to 10 sprites this way.

When viewing the list of moves, the game places the current pokémon's icon in the top left of the screen and animates it, storing the current animation type in address $C51E. This is used to index a jumptable that is used to control the behavior of the animation. By overwriting this address with an invalid value, we can index this table out of bounds, potentially triggering arbitrary code execution.


Move 0x00 has a glitch type, specifically glitch type 0xD0. The source of its glitch type is 0x8350 in VRAM, hence what is or what was on the screen will affect what the game brings up as a type name; possibly with what's on the Pokémon menu affecting 0x8350{{fact}}, as 0x8350 may be written to if you have enough Pokémon menu sprites and/or held items in the party.
Move 0x00 has a glitch type, specifically glitch type 0xD0. The source of its glitch type is 0x8350 in VRAM, hence what is or what was on the screen will affect what the game brings up as a type name; possibly with what's on the Pokémon menu affecting 0x8350{{fact}}, as 0x8350 may be written to if you have enough Pokémon menu sprites and/or held items in the party.


When we have 'good' data at 0x8350 the name of the glitch type causes memory corruption, and by making the specific movements in Cherrygrove City/meeting the party requirements the game may start to execute arbitrary code on attempts, seemingly at random.
When we have 'good' data at 0x8350 the name of the glitch type causes text to print beyond the end of screen tile data, reaching far enough to corrupt address $C51E, wSpriteAnim1AnimSeqID. Depending on the text character written into this fiels, this indexes the animation jumptable out of bounds, potentially triggering ACE.

Due to the structure of the code located right after the jumptable, a reasonable amount of pointers will land in the vicinity of either the $C9xx region or the $E9xx region (echo RAM for the $C9xx region). For smaller maps, execution will safely slide until it reaches three regions:
* $CC20 contains wBGMapBuffer, which temporarily buffers newly inserted tile IDs.
* $CC48 contains wBGMapPalBuffer, which temporarily buffers newly inserted tile palettes.
* $CC70 contains wBGMapBufferPointers, which temporarily buffers VRAM addresses of newly inserted tiles.

All three of these are affected by the movement pattern of the player. wBGMapBuffer and wBGMapPalBuffer do not contain much useful data, but can fairly easily be manipulated to allow execution to safely slide through, while wBGMapBufferPointers can be directly manipulated to jump to a small selection of possible addresses.


If by chance the game executes E9F0 (Echo RAM for C9F0) then it will eventually come across jr c, EC68 (@EC2D) and jp c, FA9B (@EC70), which causes the game to execute FA9B (DA9B).
Due to the specific movement pattern used, wBGMapBufferPointers starts with the byte sequence of DA 9B FA (jp c, FA9B, at $EC70), which causes the game to execute $FA9B (echo RAM for $DA9B).


As DA9B is Pokémon 3's Speed DVs, we can make the data slide over to Pokémon 4. Using Quagsire, the code can be redirected to somewhere else (such as box names or stored items) where we can spell out code.
As $DA9B is Pokémon 3's Speed DVs, we can make the data slide over to Pokémon 4. Using Quagsire, the code can be redirected to somewhere else (such as box names or stored items) where we can spell out code.


Here is the assembly code for the box name code to obtain Celebi:
Here is the assembly code for the box name code to obtain Celebi: