Permanently Hex-Edit ASM Codes onto an ISO/WBFS
This guide will teach you how to perma-edit your ISO/WBFS file with ASM code(s).
This guide is directed towards Linux users. If you are an experienced Wiimm's Tool User on Windows, you should be able to 'convert' the WIT commands to work on your Windows machine.
Chapter 1. Requirements
Basically, you need to be a veteran ASM code creator already. This tutorial will not baby step the 'noobs'. You must already know how to perma edit '04/single line' code types into an ISO already. Thread for that is HERE.
Other requirements:
Have Wiimm Tools installed and know how to run basic wit/szs commands
Have a Hex editor installed (I recommend running HxD via Wine emulation) and know how to use it.
Chapter 2. ISO/WBFS Extraction
Make a copy of your iso/wbfs. Let's assume your copy is at your main user account directory. Also for this guide, we will be using the NTSC-U/RMCE01 game (wbfs file type).
First, extract the ISO/WBFS..
wit extract nameofyourgame.wbfs /home/yourusername/newfolder
NOTE: Don't create the 'newfolder' directory beforehand. Wit tools will create it for you.
Chapter 3. Overview Of What Actions Will Be Done
For this tutorial we will use just one ASM code. Keep in mind, doing this sort of ISO/WBFS editing is very tedious. The more ASM codes you add, the longer and more tedious this will be. For every ASM code you have, you will have to make a separate branch. These branches will branch to a empty spot in RAM (on the main.dol). The actual assembly instructions of your code(s) will be there. After the ASM instructions are executed, there will be more branches to branch back to where you started. Basically, you create your own subroutine via hex edits.
With this method, there's no need for code handlers. You are adding new ASM instructions to the game manually. By the way, using codes with activators and deactivators will be even more tedious to do. First you need to reconfigure your current ASM code(s) to have full ASM act/deacts (no gecko 2833/2834 type stuff). Then you need a code such as THIS to hold 'status' numbers. Obviously, this code to set these 'status numbers' must be able to set a Breakpoint anywhere at any time in the game. This will add more and more branches/subroutines to add after all the other branches that already exist. Once again, this is tedious as f**k..
Chapter 4. Finding The Spot In Main.dol and/or StaticR.rel Where Our Code is
Our first code we want to 'hex edit' in is my first ever revision of my original version of the Air-O-Meter code (NTSC-U version).
Code we will be working with (NTSC-U):
C2576FBC 00000003
8003001C 3D808053
3D6038A0 7D6B0214
916C10A0 00000000
If you are using your own ASM Code, you will want to view this thread . This thread HERE will let you know (via your Code's address) whether or not your code is at the main.dol or StaticR.rel. If its not in either of them, then you cannot use that code for this tutorial unfortunately.
Back to the Air-O-Meter code... It's code address is 0x80576FBC, so it resides in the StaticR.rel. You will also need are RAM Dumps of MKWii. If you have Dolphin Emulator, look at this thread HERE. If not, run this code HERE on your Wii.
Open up your Hex Editor. Open the NTSC-U RAM dump. Press CTRL+G and enter in 576FBC. The word (default ASM hex value) at the address will be 8003001C. Copy the first 3 words (12 bytes) starting at the address. (80 03 00 1C 90 1D 02 18 7F A3 EB 78). In a new tab on your Hex editor, open up the StaticR.rel file of your extracted ISO/wbfs.
If your iso/wbfs is not scrubbed, it will be in the /home/yourusername/newfolder/DATA/files/rel/
If your iso/wbfs is scrubbed, it will be in /home/yourusername/newfolder/files/rel
Now on the StaticR.rel file within your Hex editor. Press CTRL+F. In the Search For field, paste in the string of bytes you copied. Change Datatype is Hex. Change Search Direction to 'All'. Run the search.
Keep in mind you may get no results for the codes you are using. But you should already know this is a possibility. If needed, edit your search string accordingly so you can get some results to work with.
So for the Air-O-Meter code, our string is found on the StaticR.rel at first attempt. The address on the StaticR.rel is 0x0006B05C.
Chapter 5. Finding Empty Spot in Main.dol for ASM Functions to reside in
Alright what we want to do is have an empty unused spot in the Main.dol where we will branch too and hex edit in our assembly instructions. This will be sort of hard to figure out what the corresponding live RAM address will be... Open up the iso's main.dol on another tab on your Hex Editor.
At main.dol's address 0x00000100 we see the ascii text for the Metroworks signature. Let's copy the first 4 words (16 bytes). The string will be (4D 65 74 72 6F 77 65 72 6B 73 20 54 61 72 67 65).
Go back to the tab where your NTSC-U RAM Dump is. Press CTRL+F and run a search for the new copied string. Use the same settings as in the 1st search we did from previous chapter.
You will find the string at address 0x00004000. This is where the Metrowerks signature of the main.dol starts on the game's RAM. Let's say we want to use the empty space at 0x00004260. Keep in mind that the further down you go to find an empty space, the more the chances increase of that space actually not being empty and will be used by the game for various functions later on... Be sure your empty space is actually never used by the game!!!
Obviously using search strings for a bunch of zeros to find our empty space is not very practical. For the empty space we are using in this guide, we will do a simple Hex equation to find its spot in main.dol. 0x4260 minus 0x4000 is 0x0260. Go back to your main.dol...
So we know the Metroworks sig starts at 0x00000100 (which is 0x00004000 in the RAM dump). Now just add 0x260 to 0x100. Our spot in main.dol is address 0x00000360. If you compare the main.dol location and RAM location, you can see we found the right corresponding spots.
Chapter 6. Setting our branch (jumping backwards in memory)
Alright, now we need to write a basic branch. We will need to jump from the StaticR.rel RAM location to the RAM location of our empty space on the main.dol. So take the normal code address for NTSC-U Air-O-Meter (576FBC) and subtract is by our empty space RAM location (4260). Use any handy hex calculator.
576FBC - 4260
The result will be 572D5C. Now do a simple minus one..
Now the result will be 572D5B. Going back to your hex calculator, do this equation...
FFFFFFFF - 572D5B
Now the result will be FFA8D2A4. We now have our branch ASM function to first branch from the StaticR to our empty RAM space. Just add the branch ASM function and use our finalized result as the hex amount for the branch. Like this...
b 0xFFA8D2A4
Open up any ASM compiler. Simply use that instruction and compile it. If you using Python compiler, you can select the RAW ASM option so the basic hex byte instruction gets compiled (not as a whole code). On something like WiiRD GUI. You get a whole (2 line) code compiled. Just grab the hex-byte code of the compiled branch instruction.
The compiled byte code of the branch function is 4BA8D2A4.
Go to the address on the StaticR.rel that we found way back earlier. (0x0006B05C). Replace the word at that address (8003001C) with our new compiled branch word (4BA8D2A4). Save the file. You can close the tab of the StaticR.rel on the Hex Editor, we no longer need it. Nice work, we've created the branch to our empty space. I told you this would be tedious. Onto next chapter...
Chapter 7. Plugging in ASM instructions at Empty Space
Let's take a quick look at the NTSC-U Air-O-Meter code
C2576FBC 00000003
8003001C 3D808053
3D6038A0 7D6B0214
916C10A0 00000000
We don't need to do any decompiling. What we do is just take the compiled hex-byte ASM instructions and plug them in order on our empty space.
NOTE: You don't need to include the '00000000' at the end of the code. In fact, if you do, you will cause the game to freeze. So yea, don't include it.
Another NOTE: If you are using an ASM that ends in a nop (60000000 00000000). You do NOT need the nop, and you obviously don't need the '00000000' after the nop. The nop is there only for Gecko code handler reasons.
Alright on the main.dol file, at the address 0x0360, we will write in the word 8003001C. The next address 0x364, will be written with 3D808053. Just repeat this til you have done all the compiled byte code of the ASM code. Here's an overview of what our empty space within the main.dol...
Address ByteCode:
0x360 8003001C
0x364 3D808053
0x368 3D6038A0
0x36C 7D6B0214
0x370 916C10A0
Alrighty nice work. We got our ASM instructions filled in for our made up subroutine. All we need do now is branch back....
Chapter 8. Branching back (jumping forward in memory)
The formula to calculate the branch back will be similar to how we did the first branch.
So if we look back at the list of our newly written empty space, we see our last instruction was main.dol's address of 0x0370 (which would be the RAM's address of 0x4270). If we were to continue stepping thru the game, the next address (in RAM) will be 0x4274. That spot will contain the next compiled byte code of the branch back ASM.
For branching back after our code is done executing, we do NOT want to branch back to our exact starting address (0x80576FBC). If we do that, the game will result in an infinite loop (game will freeze). We need to branch just one step after that. That RAM Address will be 0x80576FC0. Let's do the formula..
Take the value 576FC0 and subtract is by the value 4274...
The result will be 572D4C. Do the minus one...
Now the result will be 572D4B.
FFFFFFFF - 572D4B is FFA8D2B4.
Alright now the difference here is that when we write the branch instruction for compiling, we put our result as a NEGATIVE number. Like this...
b -0xFFA8D2B4
That is our ASM function to branch back. Put that into your compiler, and the compiled byte code is...
48572D4C
As you can see, you actually don't need this formula for the branch back. Just take your initial result when you first subbed the two address values and add a '48' in front of the result. Simple.
Ok, now going back to your main.dol file on the Hex Editor. Now just write in the value 48572D4C at address 0x0374.
Nice job. You did it! Save the changes. Close your Hex Editor.
Chapter 9. Rebuilding ISO & Testing
First, there are .bak extensions of the main.dol and StaticR that are in their respective directories. Move them to a safe place for backup. After testing, you can delete them if you want.
Open a terminal in your main user directory. run this command...
wit copy ./newfolder nameofNEWgame.wbfs
Command will take about 5 minutes or so...
WBFS/ISO is now rebuilt with the Air-O-Meter! Plug in the WBFS/ISO on USB for the Wii. Test your ISO. If you did everything correctly, the Air-O-Meter code will be working. Keep in mind this version of Air-O-Meter only works for Solo Racing in TT mode.
Side NOTE: This version of Air-O-Meter code doesn't work on Dolphin.
Chapter 10. Troubleshooting
Even if you used a code for this guide that doesn't work in Dolphin, you can still run it in Dolphin to see if your branches are correct.
Apply the cheat to your Dolphin (however you prefer to do it). Set an Instruction Breakpoint with the Memory Address of your Code. Once the Breakpoint 'break's, bring up your Code view tab. Use the "Step" function (while looking at the Code view), and step thru the game one ASM function at a time.
You should first navigate to the RAM address 0x4260. After the ASM functions are executed, you will hit another branch function and branch to right after your Code's address (0x4 beyond).
Chapter 11. Conclusion
I told you this would be tedious. It's a lot of work. Especially dealing with more than one ASM code. And it's insanely tedious if you are working with codes that are using activators + de-activators.