The Wind Waker
Fountain Idol Manipulation
Description
If you place a Fountain Idol at a pedestal, then remove it and immediately replace it, the game can crash. This happens because when replacing the Fountain Idol, the game looks for data that was in the same location than the previously placed Fountain Idol in the GAME heap. So if the heap has shifted for any reason, for example because of the mapfish creating the water pillar actor, or because you pulled a bomb or shot an arrow, the game will instantly crash as you attempt to place the new Fountain Idol. As it turns out, this crash is highly abusable, and is exclusive to the Fountain Idol item.
Technical Explanation
Explanation by LagoLunatic
The fountain idol uses BCK animations. BCK animations are attached to joints (usually the root joint), which are part of the model data, and not the model itself. A model data is shared by all actors that use that model, since in theory it's supposed to just be the data loaded off the disk. But in practice animations attaching themselves to joints breaks this rule, meaning that any model data that has ever had a BCK animation attached to it has a pointer to that animation, even though the BCK animation is specific to the actor that last used it. This means that if any actor that used the model data attached a BCK to it, then that actor was deleted, and then a different actor uses the model data again, the model data now has a dangling pointer to the deleted BCK animation for the old actor.
Normally, the new actor would overwrite the dangling pointer with a pointer to its own new BCK animation. This is done by calling mBckAnm.entry(mpModel->getModelData());. as long as you call that before mpModel->calc(); gets called, the dangling pointer is usually not used, thus why this quirk of the animation system doesn't matter for 99% of actors. Alternatively, calling mBckAnm.remove(mpModel->getModelData()); after mpModel->calc() would also avoid all issues. Pedestal items correctly call entry before calc in the draw function, but the CreateInit function is a different story. The pinwheel and the fountain idol have their own special init code that calls calc, but they never called entry first. The bug doesn't happen for pinwheels because they don't use any BCK animation to begin with, so the pointer to the BCK is correctly null for all instances of pinwheel models, but it does occur with Fountain Idols.
The crash occurs inside J3DJoint::calcIn. It is caused by a stale pointer: this->mpMtxCalc in J3DJoint::calcIn(J3DJoint *this). Its exact address will be somewhere inside the memory the Fountain Idol object (Fobj00) takes up in the Game heap the first time we place the fountain idol, either at offset 0x6E8 or at offset 0x6D8, depending on padding.
This glitch is thus a use-after-free exploit, and it can thus be used for very powerful exploits, including Arbitrary Code Execution.
Function Pointer Manipulation (FPM)
Description
Discovered by LegendofLinkk, explained by ShadowQCD
One application of this glitch is to use this stale pointer to perform a jump to code that already exists within the game and make the game run that function. If we call the word that lives at that stale pointer address A, and A is a valid address in RAM, the game will read the word that lives at that address + an offset of 0x14, let's call this word B. If B is also a valid address, the game will jump there and attempt to execute whatever bytes are there as code. This will generally crash the game unless this is carefully manipulated. The crash can be avoided if the following statements are true:
- A is a valid address (it starts with 0x8 or 0xC)
- The word B found at A+0x14 is also a valid address
- Address B contains code that:
- Ideally performs some useful action (otherwise this glitch is useless)
- Can handle the current register values without crashing (r3 holds the address mpMtxCalc, r4 is 0)
- Returns to the address in the link register (LR) when done
To avoid a crash, we essentially just need to branch somewhere that handles the link register properly, so jumping to the start of basically any function that doesn't take inputs should work (some functions that take inputs can also work, but if a function incorrectly expects an input register pointing to a specific data structure, odds are pretty high that it'll crash trying to navigate the structure).
Item Functions
The main use for Function Pointer Manipulation is to simply write an address A so that A+0x14 contains the pointer to a get item function. Every item in the game has both such a function and a corresponding pointer to it, thus this glitch can be used to obtain any item in the game. The following table shows the address needed to reach each of these functions:
For example, in order to obtain the hookshot (item ID 0x2F) on the japanese version with this glitch, you want to write 0x8037BE10 at the address the stale pointer from the Fountain Idol points to. If you can do this, the game will jump execution to 0x8037BE10 + 0x14 which is address 0x8037BE24, which corresponds to the pointer to item_func_hookshot as seen in the table above. The game will then proceed to execute the hookshot get item function, giving you the hookshot.
Instead of writing 0x8037BE10 at the required address, you can also use the uncached MEM1 space adress, so writing 0xC037BE10 instead also works. This is a much easier number to write using floats, so it is quite useful and is pretty much always the used method.
Notes:
- On some emulators, 0xC2xxxxxx, 0xC4xxxxxx, and 0xC6xxxxxx also map to uncached MEM1 spaces and thus also work as target addresses to branch to. These do not exist on console however, and the game will crash there if used.
- The Japanese Switch 2 version of the game is a new build of the game, which means the standard JP addresses don't work for it. The get item function addresses for the JP NSO version are currently unknown.
Other Uses
Other functions can also be interesting to branch to.
gameStart
The first one is the following function:
| Function Name | JP Address | US Address | PAL Address |
|---|---|---|---|
| d_com_inf_game::dComIfGs_gameStart | 0x800533C8 | 0x80054C70 | 0x80058A50 |
This function triggers a load back to your save location, just like if you started your file from the file selection screen. This is useful because it allows you to save in any stage, then by performing Fountain Idol Manipulation to trigger this function you can instantly warp back to the stage you last saved in, which in use is very similar to a Farore's Wind warp in Ocarina of Time.
onEventBit
The next useful functions are the following pair, which do the same thing (so you can pick whichever is more convenient):
| Function Name | JP Address | US Address | PAL Address |
|---|---|---|---|
| d_com_inf_game::dComIfGs_onEventBit | 0x800EDDA4 | 0x800F0DF4 | 0x800F4B34 |
| d_lib::dLib_setFirstMsg | 0x80055CB8 | 0x80057EC0 | 0x8005BCA0 |
Both of these functions set event flags depending on what is found in r3, which will always be the fountain idol stale pointer address with this glitch. Thus, if the stale pointer lives at address 0x8xxxYYZZ, branching to one of these functions will set event flag 0xYYZZ, which are actually all the event bits contained in 0xZZ at offset 0xYY in the event flag array. Eventhough in theory branching to these functions could potentially allow us to write any event bit we want, in practice this isn't the case. This is because the game does some padding in the heap for everything to stay 0x20 aligned, and thus the stale pointer won't be able to reach every possible memory address. Only event bits that end with 0x80, 0x40, 0x20 or 0x08 are accessible with this method. This still allows raising the Tower of the Gods, beating Forsaken Fortress 1, and opening up the light portal to Hyrule 3 in the TotG sector early.
Letter send, stock, read
Another set of useful functions is the following:
| Function Name | JP Address | US Address | PAL Address |
|---|---|---|---|
| d_letter::dLetter_send | 0x801959F0 | 0x80199108 | 0x8019F62C |
| d_letter::dLetter_stock | 0x80195A64 | 0x8019917C | 0x8019F6A0 |
| d_letter::dLetter_read | 0x80195AD8 | 0x801991F0 | 0x8019F714 |
These functions also set event flags according to where the stale pointer is in memory. If the stale pointer lives at address 0x8xxxYYxx, branching to these functions would set event flags 0xYY0Z, where Z is 1 for send, 2 for stock, and 3 for read. This allows reaching event flags that end with 0x01 or 0x02. This is useful to set Animation Set 2, to set the Ganondorf Cutscene as watched, to open the dark portal to Ganon's Tower, or to open the 2nd warp pots early inside dungeons for example.
Miscellaneous
The following functions are not particularly useful but they do have some fun effects.
- d_save::dSv_info_c::reinit sets all the flags that a NG+ save would, without deleting any of your progress. It will grant you the deluxe pictobox, some progress related to the Nintendo Gallery, and completes the quest to become Lenzo's assistant. It basically turns your file into a NG+ file on the spot.
- d_save::dSv_player_item_record_c::resetTimer pauses the forest water timer until you reload the area.
- d_kankyo::dKy_instant_timechg changes the current time of day according to some unrelated data from the placed fountain idol. You can make time of day turn negative, which has a very drastic impact on the colour palette.
- d_kankyo::dKy_instant_rainchg starts a rain event, which will quickly stop.
- d_a_tag_island::daTag_Island_c::demoInitProc can set some specific event flags if manipulated correctly on Windfall Island, such as putting Makar or Medli inside Gale or Headstone Island. This is really difficult to make work due to requiring a specific heap setup, and also being a function inside a REL meaning it is dynamically loaded. There are also other easier methods to do the same thing.
- d_a_player_bow::daPy_lk_c::makeArrow creates an arrow stuck to Link's hand, similarly to what the arrow duping glitch does.
- m_Do_graphic::mDoGph_gInf_c::onMonotone will set the black and white graphical filter effect from Hyrule 1.
Complications
In practice, branching to functions such as these is more difficult than to item functions as there is no pointer to them by default anywhere in RAM. This means you must first write that pointer with data you control, then write the pointer to that other pointer at the address of the fountain idol stale pointer itself. Thus this generally requires two position setups instead of one. Also, the heap setups will often need to be exact (as in, you need full control over everything that is currently loaded) because the constructed pointer will often end up in dynamic memory. With item functions, the heap setup is relative (what has already loaded before is not important because the function pointer is a static).
Partial Function Calls (PFC)
Discovered by ShadowQCD
A Partial Function Call is branching directly into the middle of functions, instead of branching to the start of one. This can allow bypassing "if" statements that exist within a function, or using instructions within a function to perform something specific, disregarding the overall function structure, for example in order to perform arbitrary writes in memory (by skipping the game setting offsets correctly). This is a much more broken use of the stale pointer.
In order for a PFC not to crash, you need the function to have the following instruction ending pattern in order not to mangle the stack:
lwz r0, 0x0014 (sp)
mtlr r0
addi sp, sp, 16
blr
Even when this pattern is correct, the game might still crash if the function expects specific register values, or if it modifies important register values on the way.
PFC in the Wind Waker has a couple known uses. It can be used to write the stale pointer address anywhere in memory, leading to applications such as Credits Warp or overwriting Link's HIO data (increasing his max swimming speed, increasing jump height etc...) among many other things. If we call the address where the fountain idol stale pointer is address A, and the word contained within A is a valid address in RAM, the game will jump to the address contained within A + an offset of 0x14 and read the word found there, let's call this word B. Furthermore, let's have the word contained at address A + an offset of 0x440 be manipulated to a word that's also another valid address, let's call that word C. On the japanese version, if B is set to 0x80292198 and you perform the fountain idol manipulation glitch, you will branch in the middle of JAInter::SeMgr::releaseSeParameterPointer. Due to the instructions found within this function this will cause address A to get written at C+0x43C, which could be anywhere you want in memory if C is manipulated correctly.
Arbitrary writes has an endless amount of possibilities. Here are some funny things to do with it:
- Overwriting the word at 0x8023226C on the japanese version will remove the "if" instruction that checks if the credits should play, which will lead to a credits warp when entering a loading zone.
- Overwriting the float found at 0x80350AD0 on the japanese version will change Link's max swimming speed, allowing superswimming anywhere by just swimming normally.
- Overwriting the word at 0x800000F8 will modify the clock speed. This will make the game run slower of faster depending on the value of address A. The smaller the word found at this clock speed address is, the faster the game will run. It's also possible to make the game send an error message if this value is too small. Ideally, only the first byte is modified and set to 0x00.
Heap Setups
Important Information
Heap Parity
Before explaining the heap setups, it is important to know about a quirk of the Wind Waker heap management. The actor heap sizes may seem inconsistent at first glance, but this is because the game does some padding to make sure everything stays 0x20 aligned. We say that the heap is "even" if the first free byte in the GAME heap is 0x8xxxxxY0 with Y even, and that the heap is "odd" if the first free byte is 0x8xxxxxY0 with Y odd. Many actors will have a different size in the heap depending on if it loads when the heap is even or odd (they will differ either by 16 bytes or 32 bytes).
Thus, if the actor sizes don't seem to be the ones you were expecting, then you may need to first flip the heap "parity" by either placing an extra town flower, or creating an odd amount of footprints in the sand first. These actions flip the heap parity, then you can proceed with the heap setup normally. Some actors also guarantee a specific parity, for example pulling a bomb will always guarantee an odd heap afterwards. Most setups only work with a specific heap parity in mind.
Mapfish and Lightning
There are two possible actors that can make heap setups more complicated, especially outside.
The first one is the mapfish. The mapfish jumping creates a water pillar actor in the GAME heap which makes controlling it for a heap setup much more difficult. It is generally best to completely avoid having to deal with this by making sure the mapfish is not spawned yet onto the overworld. The trigger to spawn the mapfish is meeting KoRL (after beating FF1) + spawning the warp portal after defeating Gohma in DRC.
Lightning also load in the GAME heap. While random thunderstrikes shouldn't happen, during endless night they will always occur. The amount of created lightning instances and how often they are created is mostly random. Whether they produce sound is also rng. However, after a series of lightning has occured, you have about 2 second where a new series of thunderstrikes cannot happen, as there is a cooldown timer before the randomness checks start again. Thus, one way to deal with thunderstrikes is to wait for a thunder to occur and end between each step. To make this easier, it is generally recommended to get Nayru's Pearl quickly to get rid of endless night.
Setup 1 - With a Sea Flower
Discovered by ShadowQCD
This first setup has the amazing upside that it doesn't require any item you wouldn't already have by the point you obtain the Fountain Idol. It will have the stale pointer pointing to the X coordinate of a demo item (an item held over Link's head). Thus by standing at a float perfect position and pulling out a town flower or the sail, you can perform a Stale Pointer Manipulation to jump anywhere you want in memory.
It requires having one Town Flower, one Sea Flower and one Fountain Idol in your inventory, and the setup must be performed at Windfall Island so that you have access to the beach in order to load footprints. The steps are the following:
- Start with the heap "odd".
- Place a Sea Flower (size 1872).
- Place a Town Flower (size 2000).
- Place the Fountain Idol (size 1872).
- Remove all 3 pedestal items.
- Make exactly 2 footprints (size 1712 x2)
- Perform the position setup to jump to the wanted function.
- Pull a Town Flower or the Sail over Link's head so that its X coordinate maps to the address you want.
- Place the Fountain Idol again.
Setup 2 - With a Bomb
Setup by minimini352
This setup will also have the stale pointer pointing to the X coordinate of a demo item (an item held over Link's head). This method is fast and uses one bomb. It can also be performed inside buildings by using Item Swap. Note that instead of the bomb, a tingle bomb can also be used.
The setup is the following:
- Start with the heap "even".
- Place down a Bomb (size 2448).
- Use the R button. Do not throw it onto ground, which creates a dust particle actor and messes up the heap setup. Alternatively, you can throw the bomb towards water or use a tingle bomb instead.
- Place the Fountain Idol (size 1872).
- Wait for the Bomb to unload.
- If you threw the Bomb into water to make it unload faster, you have to wait a second for the sploosh/water pillar to unload here.
- Remove the Fountain Idol.
- Place a Town Flower (size 2000).
- If you had to place a Town Flower to make the heap even, you can pick it up now (you might need it later).
- Perform the position setup to jump to the wanted function.
- Pull a Town Flower or the Sail over Link's head so that its X coordinate maps to the address you want.
- Place the Fountain Idol again.
Setup 3 - With Bow & Grappling Hook
Discovered by LegendofLinkk
For this setup, start by shooting 5 arrows then place the Fountain Idol and take it back. By pulling out the grappling hook, we will be able to make the game read some camera data related to the grappling hook as the pointer to jump instruction to. This setup is generally not used RTA.
Position Setups
Item Setups
Work in Progress
The table below contains position setups for the most interesting items. Setups are mostly for the japanese version. Click on the setup names to collapse them.
| Item ID | Item Name | Setups (click to collapse) |
|---|---|---|
| 25 | Grappling Hook |
» Sploosh Room (JP)Setup coming soon |
| 27 | Hero's Bow |
» Windfall (JP)Setup coming soon » Sploosh Room (JP)Target the pillar on the right side as you enter the room, then dry roll into the right corner and backflip for the initial position (X, Z, angle) = (209.62948608398438, 549.9795532226562, 7018). C Up Turn -36 (209.62948608398438, 549.9795532226562, 48974) Roll (119.64485168457031, 548.3228149414062, 48974) Roll R (27.845327377319336, 546.6326904296875, 48974) Roll R (-63.95418930053711, 544.9425659179688, 48974) Turnaround (-63.95418930053711, 544.9425659179688, 16221) C Up Turn -20 (-63.95418930053711, 544.9425659179688, 3121) Roll (-37.4325065612793, 630.9457397460938, 3121) Pull out overhead item |
| 28 | Power Bracelets | |
| 29 | Iron Boots | |
| 2D | Boomerang | |
| 2F | Hookshot | |
| 31 | Bombs | |
| 33 | Skull Hammer | |
| 34 | Deku Leaf | |
| 36 | Light Arrows | |
| 3A | Master Sword (Half Power) | |
| 3C | Mirror Shield | |
| 3E | Master Sword (Full Power) | |
| 55 | Grandma's Soup | |
| 61 | Triforce Shard 1 | |
| 62 | Triforce Shard 2 | |
| 63 | Triforce Shard 3 | |
| 64 | Triforce Shard 4 | |
| 65 | Triforce Shard 5 | |
| 66 | Triforce Shard 6 | |
| 67 | Triforce Shard 7 | |
| 68 | Triforce Shard 8 | |
| 69 | Nayru's Pearl | |
| 6A | Din's Pearl | |
| 6B | Farore's Pearl | |
| 6F | Command Melody | |
| 71 | Wind God's Aria | |
| 97 | Shop Guru Statue | |
| 99 | Note to Mom | |
| 9B | Moblin's Letter | |
| AB | 1000 Rupee Wallet | |
| B0 | 99 Arrow Quiver | |
| B8 | 500 Rupees (Ankle Reward) | |
| DB | Ghost Ship Chart |
