0x1500 control code arbitrary code execution: Difference between revisions

Jump to navigation Jump to search
Content added Content deleted
No edit summary
(Added an explanation for pfero's first setup.)
Line 100: Line 100:


===Self-contained setup and bootstrap===
===Self-contained setup and bootstrap===
If the player has the ability to put arbitrary data in a string, then both the setup and the bootstrap can actually both be done from within the string itself:
If the player has the ability to put arbitrary data in a string, then both the setup and the bootstrap, and even potentially the entire payload, can actually be done from within the string itself:
* Instead of setting up "0x15 0x00" after the string buffer, 0x15 followed by 0x00 in the string itself could be used to trigger this glitch.
* Instead of setting up "0x15 0x00" after the string buffer, 0x15 followed by 0x00 in the string itself could be used to trigger this glitch.
* By putting carefully constructed byte sequences between 0x15 and 0x00, valid mobile functions can be triggered and modify the value at $CD52.
* By putting carefully constructed byte sequences between 0x15 and 0x00, valid mobile functions can be triggered and modify the value at $CD52.
* Due to how mobile functions use the stack, if the game encounters a <code>ret</code> instruction when executing code from $CD52, without other stack manipulation, the game will continue to run arbitrary code from the location following the 0x00 byte, which in this case would also be in the string itself.
This principle can be used after the player has already achieved ACE, to make subsequent execution of arbitrary code easier. Alternatively, they might be used to setup ACE by trading with another game, or with a [[game-altering device]].
This principle can be used after the player has already achieved ACE, to make subsequent execution of arbitrary code easier. Alternatively, they might be used to setup ACE by trading with another game, or with a [[game-altering device]].


Line 108: Line 109:
4F 15 08 05 C9 00 [code] 37 C9
4F 15 08 05 C9 00 [code] 37 C9
This works in any unverified string, notably including Pokémon nickname and mail messages. This means that it can be transferred from any Generation I game (with just enough space to jump to a more convenient location) or Generation II game (with more space to possibly write a "built-in" payload).
This works in any unverified string, notably including Pokémon nickname and mail messages. This means that it can be transferred from any Generation I game (with just enough space to jump to a more convenient location) or Generation II game (with more space to possibly write a "built-in" payload).
{| class="wikitable mw-collapsible mw-collapsed"
! Explanation
|-
|
* The first byte, 0x4F, is the <code><nowiki><LINE></nowiki></code> control character, which signifies that the following text is to be printed in the bottom line of the dialogue box (Generation II dialogue boxes only displays two lines of text at a time). This sets the "cursor location" (where the next character would be printed) to a fixed value<ref>[https://github.com/pret/pokecrystal/blob/8fd66c080f201c401419674229f2714853de008f/home/text.asm#L474-L478 The function <code>LineChar</code> that handles the <code><nowiki><LINE></nowiki></code> control character]</ref>, namely 0xC5E1, which is used as a baseline for subsequent setup.
* The second byte, 0x15, makes the text engine go into mobile script mode.
** The third byte, 0x08, is interpreted as the index of a mobile function, namely <code>Function17f2cb</code> in the disassembly<ref>[https://github.com/pret/pokecrystal/blob/8fd66c080f201c401419674229f2714853de008f/mobile/mobile_5f.asm#L4006-L4035 The function <code>Function17f2cb</code> in the disassembly]</ref>. This function takes the next two bytes in the input stream (here "05 C9") as input parameters, and writes them to $CD54 and $CD55 in this order. It then calls the function <code>MobilePrintNum</code> to print a number; the actual number printed is not as important as the number of digits it is printed in, which is controlled by the first input parameter, here 0x05. Afterwards, the new "cursor location", now 0xC5E6, is stored in $CD52–$CD53 in little endian (i.e. [$CD52] = 0xE6, [$CD53] = 0xC5).
** The sixth byte, 0x00, triggers the glitch, causing the game to jump to $CD52. The byte sequence that has been set there so far is "E6 C5 05 C9", which translates to:
<pre>
and 0xC5 ; E6 C5
dec b ; 05
ret ; C9
</pre>
:: The first two instructions are "safe" slide instructions, and the third causes the game to return to the location after the 0x00 byte, as mentioned at the beginning of this section.</li>
* The last two bytes, "37 C9", are executed after the main payload, and translates to <code>scf</code> then <code>ret</code>. This will set the carry flag and then return to the main loop for the mobile script mode<ref>[https://github.com/pret/pokecrystal/blob/8fd66c080f201c401419674229f2714853de008f/mobile/mobile_5f.asm#L3543-L3546 The main loop for the mobile script mode]</ref>, where a set carry flag will cause the mobile script mode to terminate normally.
|}
15 0A C0 00 [code] E1 C9
15 0A C0 00 [code] E1 C9
15 0B C0 00 [code] E1 C9
15 0B C0 00 [code] E1 C9
The first setup is specifically designed for mail messages, the second one might be useful elsewhere. The first one depends on the value of hl (the location where the current character in the string is being printed to) translating to valid instructions to slide for two bytes; the second one depends on hl+3 in the same way. The first setup might not work on Japanese versions, due to the behavior of mobile function 0x0A being different.
The first setup is specifically designed for mail messages, the second one might be useful elsewhere. The first one depends on the value of <code>hl</code> (the location where the current character in the string is being printed to) translating to valid instructions to slide for two bytes; the second one depends on <code>hl+3</code> in the same way. The first setup might not work on Japanese versions, due to the behavior of mobile function 0x0A being different.


==Technical details==
==Technical details==
Line 134: Line 151:
* Luckytyplosion offered [https://archives.glitchcity.info/forums/board-108/thread-7706/page-0.html#msg203310 an in-depth explanation] on the forums.
* Luckytyplosion offered [https://archives.glitchcity.info/forums/board-108/thread-7706/page-0.html#msg203310 an in-depth explanation] on the forums.
* Pfero introduced the idea of a self-contained setup, and did some preliminary research on the effects of valid mobile functions.
* Pfero introduced the idea of a self-contained setup, and did some preliminary research on the effects of valid mobile functions.
* TimoVM reverse engineered some of Pfero's setups, giving explanations on the purpose of each byte.

== References ==
<references />


[[Category:Arbitrary code execution]]
[[Category:Arbitrary code execution]]