In the followup video "Cool Zelda Glitch", I show a technique developed by natalyahasdied to corrupt the initial RAM address, as well as show off some of the things that human-viable total control lets us do. There was still a catch though, in that this method requires the player to get the joystick into a unit-accurate position, which is hardly consistent unless they exploit an input display.
Since then, myself and a few others developed the Kokiri Forest Credits Warp, which allows the player to get from a completely fresh save file to executing (a very small amount of) arbitrary code in under 15 minutes. This technique involves executing the player name as code, which unfortunately can't fit enough code in it to corrupt the RAM address that enables large ACE payloads.
However, by executing three DIFFERENT filenames as code within a single play session, all without resetting the game, the combined effect of their code is enough to enable total control. Because each file takes only fifteen minutes to setup, doing it this way is entirely reasonable. The filenames in question are these three:
03E40008 3C1C800C
03E40008 379C61E4
03E40008 A79C7F0E
(see for a tool to convert these)
On Jan 23, speedrunner ZFG asked about these filenames, and whether it would be simple to write an ACE payload for spawning arwings. I'd been looking into this earlier, so I already knew a fairly small payload was enough to patch the "spawn doors and room transitions" function in the game to spawn arwings instead, and sent this to him:
Soon afterwards, a short twitch clip from the stream went viral out of context, and received news coverage that provided no more information than "speedrunner spawns Arwing for the first time". So consider this to be the missing context.
0:00 - 1:12 The first of three filenames is executed using the same Kokiri Forest ACE that allows for the credits warp in any% speedruns.
1:12 - 2:11 The second filename payload is executed. These first two don't really have a meaningful effect in themselves, but they prepare a normally-unused register for use in the third filename payload.
2:11 - 3:15 The third filename is executed. This writes the value 61E4 to 800CE0F2, which corrupts the game's routine that is responsible for dynamically loading in other code. Specifically, it corrupts it in such a way that any subsequent code that loads will have one code instruction corrupted in a way that prevents it from executing. We do this so that once the file select code loads, the instruction that prevents you from scrolling to the right beyond the usual length of a filename can no longer execute.
3:19 I delete the first and third files because both are needed for setting up and running the final payload and running it. Note that a couple extra steps are needed to prevent a softlock later. If we ever enter the copy or erase menu, we need to 1) make sure that the last file selected to copy or erase from is File 1, and 2) briefly enter the options menu once we're done in the copy/erase menu.
3:25 I enter the two pointers 803B2FA0 801DD068 into File 1. Later on, these will eventually get used as pointers to code, with the latter pointing to the payload that we will write.
3:38 - 3:44 By entering a few specific characters "out of bounds", I manipulate some internal variables of the file select screen in a way that allows us to enter a large payload in an unused region of memory.
3:44 - 4:38 Enter the payload. This could be absolutely anything, but this was a small one suitable for the first on-cartridge test of this total control method. All it does is revert the corruption to the code-loading routine I mentioned earlier, for stability purposes, and then patch the game's "load doors and room transitions" routine to load Arwings instead. (Believe it or not, this was the simplest possible way I could find to spawn them). As a bonus, because it doesn't increase to the payload length, I also make it load the title screen debug file to give more items to fight with.
4:39 - 5:00 Again, I enter specific characters out of bounds to manipulate internal file select variables. This time, it triggers a glitched file copy, from File 1 over File 0xC6C2. This causes the filename we wrote earlier in File 1's name to get copied over a certain part of RAM that contains code pointers. The overall effect of this is that whenever we load a file, the game will execute the payload from the previous step as code.
5:01 : Load file, shenanigans happen.
0 Comments