How to port more complex codes with non standard porting - Printable Version +- Mario Kart Wii Gecko Codes, Cheats, & Hacks (https://mariokartwii.com) +-- Forum: Guides/Tutorials/How-To's (https://mariokartwii.com/forumdisplay.php?fid=45) +--- Forum: Coding (Non-ASM) and Dolphin (https://mariokartwii.com/forumdisplay.php?fid=47) +--- Thread: How to port more complex codes with non standard porting (/showthread.php?tid=2226) |
How to port more complex codes with non standard porting - Unnamed - 08-28-2024 How to port more complex codes with non standard porting
NOTE: This Tutorial is for intermediate to advanced coders. Beginners should view THIS Tutorial first. Introduction When porting more complex codes with auto porters, it can happen that the finished codes do not work or crash the game. Then this code will almost certainly need non-standard porting. Non-standard porting is when not only the hook address has to be ported, but there are also addresses in the (ASM) code that have to be ported. These can be pointers or in-game functions, for example. Non-standard porting is more time-consuming, as it is more difficult to find the ported address. Especially if it is in an environment that also contains function addresses or pointers. This tutorial will show you some attempts how to port such codes. What you will need: -This Forum -Hex Editor (I will choose online hex Editor HexEd.it) -Decent knowledge about ASM (some instructions, see THIS tutorial how to learn ASM) -RAM Dumps (you neet at least the RAM Dump of the region the code is from and the region you want to port to, see THIS tutorial how to get RAM Dumps) -Disassembler (I will use online Disassembler disasm pro) -{Optional} Hex Calculator Chapter 1: The Code we want to port For our test I have chosen a code that is not finished porting yet, it is called "Item Effect Randomizer" by TheLordScruffy. The code is given in PAL region and we want to port it to NTSC-U. Here is our code in PAL: Code: C257276C 00000024 Chapter 2: Finding Location of the Hook adress in RAM What we want to do is find the Code's RAM Address (offset & column location) within the RAM Dump. To figure this out, simply remove the first 2 digits off the first line (the C2, 06 or 04 line) of the code. If you did the conversion correctly, you should come up with a value of "57276C". Now open HexEdIt and open your PAL RAM dump with the option "open file". On the right you find "go to". Click on the box and type in the adress with "0x" as prefix. Click Enter. You should navigate to the adress now, that means the cursor should be at this adress. Chapter 3, Section 1: Decide which bytes to search for To find the correct adress on other region RAMs, you need to decide for what bytes you want to search for. Some good instructions are cmpwi, li, stw, sth, mulli or also mr. Bad instructions to search for are bl (function calls), lwz (sometimes, not always), lis. The reason why this instruction are bad to search for is that they vary in different ports and you will not be able to find the correct adress. So before we continue, let's disassemble the environment of this adress. I will choose the bytes from 0x572740 to 0x57279F. The 4 bytes at our adress are 4BAAECE5. This is a bl instruction, which means that is likely to be a function call. So this is not a good instruction to search for. But we have some mulli and mr instructions in a row, so lets take the three instructions mr r3, r16 mr r4, r31 mulli r0, r0, 0xc to search for, in bytes that would be 7E0383787FE4FB781C00000C starting at adress 0x0057275C. That will be our bytes to search for. Chapter 3, Section 2: Searching the bytes Now we search this bytes in the NTSC-U RAM Dump. Open this Dump. On the right of HexEdIt you will see a "search for" box, type* this bytes with spaces in. Then make sure only "Hexadecimal Values" is checked on Data Types and "List all occurences" is also checked. Finally click on "Search now" - You should find one adress. 0x0056D90C *NOTE: Seems like HexEd.it has no copy Function, so you have to type the bytes, but that shouldn't be a problem at all. That means we found one adress matching with our bytes. Now we want to get our ported adress, for this, we need first the difference of our search start adress and our adress we want to port. The adress we want to port is 0x0057276C, and our search start adress was 0x0057275C, means that our port adress is 0x10 bytes after the search start adress. Now we have found the adress matching with our bytes. To get our ported adress (which is 0x10 after the adress of our bytes), we add the difference of 0x10 and find our adress: 0x0056D91C Navigate to this adress in HexEd.it. You will see the Bytes 4BAB2FD5. This is a bl instruction and means that we probably found the correct adress. I will tell you that this is our hook adress ported to NTSC-U! Chapter 4: Find addresses contained in the ASM code We already have our hook adress ported. Now we want to port the adresses in the ASM code. Before we can do this, we have to find them before. For this, we need to disassemble our code. Code: mftb r12, 0x10c Most ASM or string write codes that will load adresses (of functions or pointers) that need to be ported have the following structure: lis rX, 0x80GG lwz rY, 0xSIMM(rX) or lis rX, 0x80GG ori rY, rX, 0xUIMM where GG can be from 02 to 9C, rX and rY arbitary GPR. That means a lis instruction followed by a lwz or an ori instruction mostly indicates function calls or the use of pointers. If we search for these in our disassembled code, we find 5 occurences: 1. lis r5, 0x809C lwz r5, -0x28D8(r5) 2. lis r8, 0x809C ori r8, r8, 0x36B8 3. lis r8, 0x808B ori r8, r8, 0x5468 4. lis r5, 0x8002 ori r5, r5, 0x1450 5. lis r4, 0x809C lwz r4, 0x3618(r4) That means these five adresses needs to be ported now. 0x809BD728 0x809C36B8 0x808B5468 0x80021450 0x809C3618 Chapter 5. Using the Forum as help If you are lucky, some of the codes of the forum have already used (and ported) adresses. For example, if you use the forum search for "D728", you will look at the sources of other codes that this pointer is called "race_data". Indeed, the first two adresses and the last adress were already used by other codes. We can extract these adresses e.g. from my "Call Item Function Anytime" code. The NTSC-U adresses are: PAL --> NTSC-U 0x809BD728 --> 809B8F68 (race_data) 0x809C36B8 --> 809BEEB0 (item_functions) 0x809C3618 --> 809BEE20 (player_holder) Chapter 6. Porting the rest Two adresses are missing, and we need to port them manually. The adress 808B5468 is harder to port. If you go to this adress you will see the bytes 00000000, but also surrounding values starting with 0x80. That means these are most likely function adresses, and a search with these values on other RAM Dumps will not work. Also, there is no ASM code in environment. So what you can do is to scroll up or down a bit, to find either assembly or some text. If you scroll down a bit you will notice some text appearing, starting with "FSqrt: Input is..." Ok, we have a string at starting adress 0x808B56D0 we can search for. Do a search for at least 6 of the bytes on the NTSC-U RAM Dump, so we do a search for "46537172743a". If you do this you should come up with 13 occurences. Obviously, if there is more than one occurence, it will be hard to find the correct one. To do so, run the search on the PAL RAM Dump too. The occurences are listed in order, so take a look at the position of your adress. You will notice: On PAL, the first occurence holds the bytes you use to search. That means: On NTSCU Dump, also the first adress 0x008B0F98 is the one we want to look at. Now to get our ported adress, we need to calculate the difference of our search start adress and our adress we want to port, like in Chapter 3 again. This is a bit harder, you might need a hex calculator for this. You will find the difference of -0x268. If we now add this to our found adress 0x008B0F98, we get the result 0x008B0D30, so 808B0D30 is our ported adress. To check it, open NTSC-U dump and look at the adress 0x008B0D30, you will find 00000000 as bytes after a bunch of 0x80 adresses, so chances are high that this is the correct adress. The adress 80021450 is easier to port, so you might try this one alone. HINT: Use the 12 bytes at adress 0x002145C in PAL dump as search bytes. If you have done all correctly, you must find 800208F0 as the correct adress. Chapter 7: Setup the Ported code So we have all adresses ported now. 0x8057276C --> 0x8056D91C (hook adress) 0x809BD728 --> 0x809B8F68 (race_data) 0x809C36B8 --> 0x809BEEB0 (item_functions) 0x808B5468 --> 0x808B0D30 0x80021450 --> 0x800208F0 0x809C3618 --> 0x809BEE20 (player_holder) To setup the new ported code, replace all the old adresses with the new adresses, be careful to also replace the lis-instructions. Chapter 8: Testing Now test the code on console and on dolphin to make sure it works. If the code isn't working or crashing, you have either made a mistake when porting or you have overlooked an address that needs to be ported. Then look at the code again and check whether you may have made a mistake or overlooked something. Conclusion Two main problems occur with porting more complex codes: 1. Find the instructions that will need porting 2. When attempting to port, choose the correct bytes to search for I hope this tutorial helps you to figure these two things out in future and with that to port more complex code to other regions, as auto porters do not support (yet) non standard porting. Happy Coding! Tutorial written by: Unnamed; Credits: Vega for further tutorials |