Kodewerx https://www.kodewerx.org/forum/ |
|
NDS AR Code Type Information https://www.kodewerx.org/forum/viewtopic.php?f=11&t=98 |
Page 1 of 6 |
Author: | kenobi [ Fri Oct 13, 2006 11:59 am ] |
Post subject: | NDS AR Code Type Information |
Not sure if it belongs here or in the Extracurricular Hacking forum (or anywhere else), anyway... The following informations (and my english) might not be 100% accurate, don't blame me on that (but feel free to correct me). Also, they might (will) be updated with new AR hacks someday. Oh, and sorry about the green font color (it hurts my eyes... can it be changed ?), but I have to use the [code ] thingie to keep the cheap 'layout' :/ Code: AR NDS Codes Type Information By kenobi. Before starting : ================= Compared to other AR (like the NGC or GBA ones) the NDS AR code handler offers a lot of changes. * First, the NDS AR doesn't wait to encounter a '00000000 00000000' code to stop the code execution. It knows how much code have been entered and enabled, and only stops when all of them have been have been processed. * Second, the NDS AR uses temporary data. There are 3 kind of them : - The first one is what I'll call the offset, which is a 32-bits value usually added to the address of the code. - The second one are what I'll call the Dx registers. They are four 32-bits, stored before the code list, which is used by the AR to store/load data. I call them 'Dx repeat value', 'Dx next code to be executed', 'Dx code status' and 'Dx data'. - Finally, there is the 'code execution status', which is a 32bits value that tells the AR if a code can be executed, or can be skipped. This code execution status is changed by the 'if' codes. * Third, the NDS AR uses some kind of 'while... end' code type, which opens a lot of new ways to make codes. Official codes types : ====================== Most AR codes look like this : ZXXXXXXX YYYYYYY Z is the code type, XXXXXXX is the address, YYYYYYYY is the value. Note : everytime the code handler is called, it clears all the value it uses (ie. the offset, the code status, the Dx registers), and then executes all the codes 'at once'. RAM Write Codes : ----------------- Type 0 : 32 bits write (str) 0XXXXXXX YYYYYYYY : writes word YYYYYYYY to [XXXXXXXX+offset]. Type 1 : 16 bits write (strh) 1XXXXXXX 0000YYYY : writes halfword YYYY to [XXXXXXXX+offset]. Type 2 : 8 bits write (strb) 2XXXXXXX 000000YY : writes byte YY to [XXXXXXXX+offset]. If... Codes (32bits): --------------------- For all the If codes, if the check is false, execution status is stopped/turned off (ie. following codes are disabled). Also, these 'If...' codes don't support the offset :/... (but I made a hack for that, check the NDS AR HACK #1) Also, 'If...' codes can be 'stacked' (up to 32 'If...' codes can be used at the same time). Type 3 : 32 bits If (code value)>(data at address) (bhi, "unsigned higher") 3XXXXXXX YYYYYYYY : checks if YYYYYYYY > (word at [XXXXXXXX]). If not, the code(s) following this one are not executed (ie. execution status is set to false) until a code type D0 or D2 is encountered, or until the end of the code list is reached. Type 4 : 32 bits If (code value)<(data at address) (bcc, 'unsigned lower") 4XXXXXXX YYYYYYYY : checks if YYYYYYYY < (word at [XXXXXXXX]). If not, the code(s) following this one are not executed (ie. execution status is set to false) until a code type D0 or D2 is encountered, or until the end of the code list is reached. Type 5 : 32 bits If == 5XXXXXXX YYYYYYYY : checks if YYYYYYYY == (word at [XXXXXXXX]). If not, the code(s) following this one are not executed (ie. execution status is set to false) until a code type D0 or D2 is encountered, or until the end of the code list is reached. Type 6 : 32 bits If != 6XXXXXXX YYYYYYYY : checks if YYYYYYYY != (word at [XXXXXXXX]). If not, the code(s) following this one are not executed (ie. execution status is set to false) until a code type D0 or D2 is encountered, or until the end of the code list is reached. If... Codes (16bits+masking): ----------------------------- For all the If codes, if the check is false, execution status is stopped/turned off (ie. following codes are disabled). Also, these 'If...' codes don't support the offset :/... (but I made a hack for that, check the NDS AR HACK #1) Also, 'If...' codes can be 'stacked' (up to 32 'If...' codes can be used at the same time). Code 7, 8, 9, A are perfect for any 'joker' code (to check the pad status, try them on register 04000130). They should also be used for event flag check. Type 7 : 16 bits If (code value)>(mask & data at address) (unsigned) 7XXXXXXX ZZZZYYYY : checks if (YYYY) > (not (ZZZZ) & halfword at [XXXX]). If not, the code(s) following this one are not executed (ie. execution status is set to false) until a code type D0 or D2 is encountered, or until the end of the code list is reached. Type 8 : 16 bits if (code value)<(mask & data at address) (unsigned) 8XXXXXXX ZZZZYYYY : checks if (YYYY) < (not (ZZZZ) & halfword at [XXXX]). If not, the code(s) following this one are not executed (ie. execution status is set to false) until a code type D0 or D2 is encountered, or until the end of the code list is reached. Type 9 : 16 bits if (code value)==(mask & data at address) 9XXXXXXX ZZZZYYYY : checks if (YYYY) == (not (ZZZZ) & halfword at [XXXX]). If not, the code(s) following this one are not executed (ie. execution status is set to false) until a code type D0 or D2 is encountered, or until the end of the code list is reached. Type A : 16 bits if (code value)!=(mask & data at address) AXXXXXXX ZZZZYYYY : checks if (YYYY) != (not (ZZZZ) & halfword at [XXXX]). If not, the code(s) following this one are not executed (ie. execution status is set to false) until a code type D0 or D2 is encountered, or until the end of the code list is reached. Offset Load Code : ------------------ Type B : loads the 32bits value into the 'offset'. BXXXXXXXX 00000000 : offset = word at [0XXXXXXX + offset]. Loop Start Code : ----------------- Type C : defines the start of the loop code. C0000000 YYYYYYYY : set the 'Dx repeat value' to YYYYYYYY, saves the 'Dx next code to be executed' and the 'Dx execution status'. Repeat will be executed when a D1/D2 code is encountered. When repeat is executed, the AR reloads the 'next code to be executed' and the 'execution status' from the Dx registers. Special Codes : --------------- The D0->D2 code type are always executed (even if the 'execution status' is set off). Type D0 : 'endif'. D0000000 00000000 : loads the previous execution status (if none exists, the execution status stays at 'execute codes'). Type D1 : Used to execute the loop set by the code type C (executes the code(s) after the type C code n times (n being the 'Dx repeat value'), but does not clear the Dx registers upon finishing). D1000000 00000000 : if the 'Dx repeat value', set by code type C, is different than 0, it is decremented and then the AR loads the 'Dx next code to be executed' and the 'execution status' (=jumps back to the code following the type C code). When the repeat value is 0, this code will load the saved code status value. Type D2 : Used to apply the code type C setting (executes the code(s) after the type C code n times, n being the Dx repeat value). Also acts as a 'Full terminator' (clears all temporary data, ie. execution status, offsets, code C settings...). D2000000 00000000 : if the 'Dx repeat value', set by code type C, is different than 0, it is decremented and then the AR loads the 'Dx next code to be executed' and the 'execution status' (=jumps back to the code following the type C code). When the repeat value is 0, this code will clear the code status, the offset value, and the Dx data value (which can be set by codes DA, DB and DC). Offset Set Code : ----------------- Type D3 : set the 'offset' to the value of the code. D3000000 XXXXXXXX : set the offset value to XXXXXXXX. Add a value to the Dx Data Register : ------------------------------------- Type D4 : adds the value of the code to the data register used by D6~DB. D4000000 XXXXXXXX : adds XXXXXXXX to the 'Dx data'. More arithmetical/logical operations can be set using the 'NDS AR HACK #2'. Set the value of the Dx Data Register : --------------------------------------- Type D5 : sets the data register used by D6~D8 to the value of the code. D5000000 XXXXXXXX : sets the 'Dx data' to XXXXXXXX. Incrementive write of the Dx Data Register (32/16/8bits) : ---------------------------------------------------------- Type D6 : 32-bits incrementive write of the data register (str). D6000000 XXXXXXXX : writes the 'Dx data' word to [XXXXXXXX+offset], and increments the offset by 4. Type D7 : 16-bits incrementive write of the data register (strh). D7000000 XXXXXXXX : writes the 'Dx data' halfword to [XXXXXXXX+offset], and increments the offset by 2. Type D8 : 8-bits incrementive write of the data register (strb). D8000000 XXXXXXXX : writes the 'Dx data' byte to [XXXXXXXX+offset], and increments the offset by 1. Dx Data Register (32/16/8bits) Load Codes : ------------------------------------------- Type D9 : 32-bits read to the data register (ldr). D9000000 XXXXXXXX : loads the word at [XXXXXXXX+offset] and stores it in the 'Dx data'. Type DA : 16-bits read to the data register (ldrh). DA000000 XXXXXXXX : loads the halfword at [XXXXXXXX+offset] and stores it in the 'Dx data'. Type DB : 8-bits read to the data register (ldrb). DB000000 XXXXXXXX : loads the byte at [XXXXXXXX+offset] and stores it in the 'Dx data'. !!! This code is buggy. Check 'AR Hack #0' for the fix !!! Add to Offset Code : -------------------- Type DC : adds the offset 'data' to the current offset. (some kind of dual offset) DC000000 XXXXXXXX : offset = (offset + XXXXXXXX). Patch Code : ------------ Type E : 'patch' code. Copies YYYYYYYY bytes from (curent code location + 8) to [XXXXXXXX + offset]. EXXXXXXX YYYYYYYY ... exemple : EXXXXXXX 00000010 AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD writes AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD to XXXXXXXX If the execution status if set off, the AR skips all the line of the patch code (skips (YYYYYYYY+7)>>2 codes). Memory Copy Code : ------------------ Type F : memory copy code. It seems you have to use the code type D3, DC or B before, to set the offset (which is then an address). Then D2 should be needed to clear the offset (else it will affect all the next codes). D3000000 XXXXXXXX FYYYYYYY ZZZZZZZZ should copy ZZZZZZZZ bytes from offset (=XXXXXXXX in this case) to YYYYYYYY (YYYYYYYY if fixed, ie. no offset are added to it). * The E and F type work as follow : If the number of data to write/copy if >3, it is done with a ldr/str, and then 4 is removed from the number of data to copy. Else, if the number of data to copy if <3, it's done with a ldrb/strb and then 1 is removed from the number of data to copy. And it loops until the number of data to copy is eqal to zero. That means that the first address to write to must be aligned in case of the number of bytes to copy is superior to 3 (else there will be a 'bug' if the number of code to write is > 3 and not a multiple of 4), and that the number of bytes to write doesn't not have to be a multiple of 4 (can be any number). NDS AR HACKS : ============== The following codes modify the AR code handler. As they write to a fixed address, they are not compatible with any game that uses an 'm' code (as the 'm' code change the location of the code handler in the memory). NDS AR HACK #0 : DB Code type Fix : ----------------------------------- The DB code type is buggy. When executed, it reads the byte from [address] to the Dx data register, but it also adds the address to the offset, which screws up the offset if the address is not 0. I've 'reported' this bug to datel, not sure if anything will be done about it. This code will make the DB code type work properly (without 'side effects') : 023FE4D8 0A000003 NDS AR HACK #1 : If... Codes : ------------------------------ Here are some code that change the 'If...' code type so they can use the offset. I also precised the original code handler values in the 'No offset support' in case you need to disable these hacks for any reason. Used with the C code, theses codes could be useful to 'auto patch' some values in a memory region. Here are first the 'one by one' codes : Code Type 3 : Offset support : 023FE20C E5933000 No offset support 023FE20C E5903000 Code Type 4: Offset support : 023FE224 E5933000 No offset support : 023FE224 E5903000 Code Type 5: Offset support : 023FE23C E5933000 No offset support : 023FE23C E5903000 Code Type 6: Offset support : 023FE254 E5933000 Offset support : 023FE254 E5903000 Code Type 7 : Offset Support : 023FE26C E1D320B0 023FE270 E1E03004 No offset support : 023FE26C E1E03004 023FE270 E1D020B0 Code Type 8 : Offset Support : 023FE290 E1D320B0 023FE294 E1E03004 No offset support : 023FE290 E1E03004 023FE294 E1D020B0 Code Type 9 : Offset Support : 023FE2B4 E1D320B0 023FE2B8 E1E03004 No offset support : 023FE2B4 E1E03004 023FE2B8 E1D020B0 Code Type A : Offset Support : 023FE2D8 E1D320B0 023FE2DC E1E03004 No offset support : 023FE2D8 E1E03004 023FE2DC E1D020B0 And here are some codes that modifies all the 'If...' code type at once : Code Type 3->6 : Offset Support : C0000000 00000003 023FE20C E5933000 DC000000 00000018 D2000000 00000000 No offset support : C0000000 00000003 023FE20C E5903000 DC000000 00000018 D2000000 00000000 Code Type 7->A : Offset Support : C0000000 00000003 023FE26C E1D320B0 023FE270 E1E03004 DC000000 00000024 D2000000 00000000 No offset Support : C0000000 00000003 023FE26C E1E03004 023FE270 E1D020B0 DC000000 00000024 D2000000 00000000 NDS AR HACK #2 : ORR/AND/ADD Codes : ------------------------------------ These codes changes the behaviour of the D4 code type. This could be useful to trigger an event bit on/off. Makes the D4 code type execute a 'ORR' instruction. 023FE424 E1833004 Makes the D4 code type execute a 'AND' instruction. 023FE424 E0033004 Makes the D4 code type execute a 'ADD' instruction. 023FE424 E0833004 NDS AR HACK #3 : Add Dx Data to Offset Code : --------------------------------------------- This code changes the D4 code type to make it add the Dx Data to the offset. 023FE424 E08AA003 Could be useful if the game's pointer's offset change. NDS AR HACK #4 : Execute custom asm routine : --------------------------------------------- This code changes the E code type to make it execute the data you entered. 023FE074 012FFF11 And to 'revert' to the normal effect of the E code type, use this one : 023FE074 E3520003 exemple : 023FE074 012FFF11 EXXXXXXX 00000010 AAAAAAAA BBBBBBBB CCCCCCCC E12FFF1E When the E code type will be encountered, the code handler will jump to and execute (ie. bx to) the AAAAAAAA, BBBBBBBB, CCCCCCCC and E12FFF1E instructions (means the instructions must be in ARM, and not THUMB). All the custom routines you make must end with E12FFF1E (bx r14). Also, you must not touch the following registers (or you must push/pop them), unless you know exactly what you are doing : r4 (holds the number of bytes of data you entered in the E code type) r5 ((holds the position of the data of the E code type from the start of the code list) >> 2) r7 (holds the 'execution status' data) r9 (holds the starting address of the AR codes list) r10 (holds the offset) r11 (holds the total number of codes enabled in the AR) r13 (SP) r14 (LR) On a side note, here is what the other register hold : r0 holds the address of the E code type plus the offset (0XXXXXXX + offset) r1 holds the starting address of the E code type data (what I used for the bx) r2 holds a copy of the data of the E code type (00000010 in the exemple) r3 is the same than r0 r6 holds what the next 'execution status' data would look when set to true r8 holds what the next 'execution status' data would look when set to false r12 holds the 'full' data of the E code type (EXXXXXXXX) Update : ARv1.54 Registers : These ones can be used freely : r0 = holds the address of the E code type plus the offset (0XXXXXXX + offset) r1 = holds the starting address of the E code type data (what I used for the bx) r2 = Data (holds the number of bytes of data you entered in the E code type) r3 = Code type (0x0000000E) r4 = Address (without code type), or offset if address=0). r5 = holds the address of the E code type plus the offset (0XXXXXXX + offset) r8 = holds what the next 'execution status' data would look when set to true r11 = holds what the next 'execution status' data would look when set to false r12 = Current execution status These ones shouldn't be changed, unless you know what you are doing : r6 = (holds the number of bytes of data you entered in the E code type) r7 = Holds the starting address of the E code type data r9 = Offset r10 = (holds the 'execution status' data) r13 = (SP) r14 = (LR) The advantages of this hack are : - you can execute whatever you want (custom codes, and why not a code searcher ?). - no need to find free space to store your asm routine. - you can manipulate the AR data (for exemple, calculate the offset in a complicated manner and store it in r10, or end the execution of code by setting r11 to 0). Only disadvantages : - also 'screw up' the F code type (so you have to disable the hack before using any F code type). - doesn't work with games that have an (m) code that relocates the AR code handler. NDS AR HACK #5 : Change the F code type source/dest : ----------------------------------------------------- For the F code type you have Source = fixed address, Dest = offset address. If the length of the data to copy is a multiple of 4 Dest to Source 023FE07C E4903004 023FE080 E4813004 Source to Dest 023FE07C E4913004 023FE080 E4803004 If the length of the data to copy is less than 4 Dest to Source 023FE09C E4D03001 023FE0A0 E4C13001 Source to Dest 023FE09C E4D13001 023FE0A0 E4C03001 And if data to copy is >4 and not a multiple of 4, use both codes. If you want to fill an area with a value, and that a) the value is 32-bits aligned and b) is is at least 5 bytes long, use this : Dest = Offset +4 023FE520 E2801004 Dest = Fixed address 023FE520 E1A0100A Code: Trainer Toolkit Infos : ======================= The TT use the same code type than the AR, with the following differences : The code type DB has been fixed. If the address of a code is equal to 0, the offset will be used (yes, that applies to If... codes). The following codes types have been added : Set the offset to the address of the code in the code list : ------------------------------------------------------------ Type C4 Exemple : C4000000 XXXXXXXX DC000000 00000004 Then, writing to the offset will overwrite the XXXXXXXX value which means : 00000000 12345678 will transform C4000000 XXXXXXXX into C4000000 12345678 In short, it gives you a secure place to store data. It can also be used to change the code on the fly ! TT's internal counter check (if... code) : ------------------------------------------ Type C5 C5000000 XXXXYYYY if (timer and YYYY)==XXXX There is a 16-bits 'timer' (well, might be more some kind of counter) running, inside the TT (at a fixed address : 0x088002E8). Not sure how it is incremented (I don't see any access to that address in the TT?...), but I guess it is each time the code handler is executed. C5 let you compare the timer value with your own value. If acts like a regular 'if...' code : If the check is true, nothing happens. If the check is false, it sets the execution status to 'disable'. Stores the offset at... : ------------------------- Type C6 C6000000 YYYYYYYY Will store the offset at [YYYYYYYY]. Trainer Toolkit Hacks : ======================= These are ports of the AR Hacks I made : NDS TT HACK #1 : If... Codes : ------------------------------ The TT allows either the address or the offset to be used, but not the sum of both. Here are some code that change the 'If...' code type so they can use the address+offset. I also precised the original code handler values in the 'No address+offset support' in case you need to disable these hacks for any reason. Used with the C code, theses codes could be useful to 'auto patch' some values in a memory region. Here are first the 'one by one' codes : Code Type 3 : Offset support : 08800460 E5953000 No offset support 08800460 E59E3000 Code Type 4: Offset support : 08800478 E5953000 No offset support 08800478 E59E3000 Code Type 5: Offset support : 08800490 E5953000 No offset support 08800490 E59E3000 Code Type 6: Offset support : 088004A8 E5953000 No offset support 088004A8 E59E3000 Code Type 7 : Offset Support : 088004C4 E1D520B0 No offset support : 088004C4 E1DE20B0 Code Type 8 : Offset Support : 088004E8 E1D520B0 No offset support : 088004E8 E1DE20B0 Code Type 9 : Offset Support : 0880050C E1D520B0 No offset support : 0880050C E1DE20B0 Code Type A : Offset Support : 08800530 E1D520B0 No offset support : 08800530 E1DE20B0 And here are some codes that modifies all the 'If...' code type at once : Code Type 3->6 : Offset Support : C0000000 00000003 08800460 E5953000 DC000000 00000018 D2000000 00000000 No offset support : C0000000 00000003 08800460 E59E3000 DC000000 00000018 D2000000 00000000 Code Type 7->A : Offset Support : C0000000 00000003 088004C4 E1D520B0 DC000000 00000024 D2000000 00000000 No offset Support : C0000000 00000003 088004C4 E1DE20B0 DC000000 00000024 D2000000 00000000 NDS TT HACK #2 : ORR/AND/ADD Codes : ------------------------------------ These codes changes the behaviour of the D4 code type. This could be useful to trigger an event bit on/off. Makes the D4 code type execute a 'ORR' instruction. 088006F0 E1833004 Makes the D4 code type execute a 'AND' instruction. 088006F0 E0033004 Makes the D4 code type execute a 'ADD' instruction. 088006F0 E0833004 NDS TT HACK #3 : Add Dx Data to Offset Code : --------------------------------------------- This code changes the D4 code type to make it add the Dx Data to the offset. 088006F0 E0899003 Could be useful if the game's pointer's offset change. NDS TT HACK #4 : Execute custom asm routine : --------------------------------------------- This code changes the E code type to make it execute the data you entered. 088002A4 012FFF11 And to 'revert' to the normal effect of the E code type, use this one : 088002A4 E3520003 exemple : 088002A4 012FFF11 EXXXXXXX 00000010 AAAAAAAA BBBBBBBB CCCCCCCC E12FFF1E When the E code type will be encountered, the code handler will jump to and execute (ie. bx to) the AAAAAAAA, BBBBBBBB, CCCCCCCC and E12FFF1E instructions (means the instructions must be in ARM, and not THUMB). All the custom routines you make must end with E12FFF1E (bx r14). Also, you must not touch the following registers (or you must push/pop them), unless you know exactly what you are doing (the registers used are different from the AR, be aware of that when testing codes that will be used for the AR) : r6 (holds the number of bytes of data you entered in the E code type) r7 ((holds the position of the data of the E code type from the start of the code list) >> 2) r9 (holds the offset) r10 (holds the 'execution status' data) r13 (SP) r14 (LR) On a side note, here is what the other register hold : r0 holds the address of the E code type plus the offset (0XXXXXXX + offset) r1 holds the starting address of the E code type data (what I used for the bx) r2 holds a copy of r6 r3 holds the 'full' data of the E code type (EXXXXXXXX) r4 (current execution status) r5 holds the address of the E code type plus the offset (0XXXXXXX + offset) r8 holds what the next 'execution status' data would look when set to true r11 holds what the next 'execution status' data would look when set to false NDS TT HACK #5 : Change the F code type source/dest : ----------------------------------------------------- If the length of the data to copy is a multiple of 4 Fixed to Offset 088002AC E4903004 088002B0 E4813004 Offset to fixed 088002AC E4913004 088002B0 E4803004 If the length of the data to copy is less than 4 Fixed to Offset 088002C8 E4D03001 088002CC E4C13001 Offset to fixed 088002C8 E4D13001 088002CC E4C03001 And if data to copy is >4 and not a multiple of 4, use both codes. Trainer Toolkit Custom Codes : ============================== Use custom (m) code (thanks to FNG for the info) : -------------------------------------------------- 01. Insert the ActionReplay DS & Trainer Toolkit dev board into your DS. 02. Connect USB cable to Dev board & PC. 03. Turn on your Nintendo DS. 04. Open the Trainer Toolkit PC software. 05. Verify communication between the DS &PC. ( Tools --> Show Hex View ) 06. Insert Animal Crossing Wild World into the DS. 07. Open 'runlist' window in the Trainer Toolkit software. ( Tools --> Show Runlist ) 08. Paste the following code into the runlist window. 023e0000 30425044 023e0004 023f0000 023e0008 00000001 023e000c 00000000 023e0010 00000000 023e0014 00000000 023e0018 023ff090 023e001c 00000000 023e0020 00000000 023e0024 00000001 023e0028 00000000 023e002c 00000200 09. Click Upload. 10. Tap screen to begin game. Press L to freeze the game : ---------------------------- 08800268 E12FFF1E 94000130 FDFF0000 08800268 EAFFFF64 D2000000 00000000 This will 'freeze' the game, making the TT code handler loop on itself while L is pressed (there is a small delay between the time you start pressing the key and the freeze happens - might be due to some instruction caching or some sort of write delay). This will prevent the game from running while the code search is happening, as long as you keep the key pressed (can be useful for a moonjump or a timer code search, in case the game doesn't offer a pause button/menu). Remove the TT's freeze code --------------------------- 523FE054 0AFFFFFC 023FE054 EA100000 D2000000 00000000 And it seems that when the TT is running, you can press L+R (and only L+R) to freeze the game. However this will be some kind of infinite loop on itself, ie. the code handler will not be executed (loop : ldrh r3,[0x04000130] ; cmp r3,0xff ; beq loop). In case anyone is annoyed with it, here is a code to disable that. Press/release R to freeze/unfreeze the game. Press/release L to advance the game. --------------------------------------------------------------------------------- 88860000 03FF0000 08860000 00000000 08860004 00000000 08860008 00000000 0886000C 00000000 D0000000 00000000 94000130 FEFF0000 88860000 FEFF0000 D9000000 08860004 D4000000 00000001 D6000000 08860004 D2000000 00000000 94000130 FDFF0000 88860000 FDFF0000 08860008 00000001 D2000000 00000000 D3000000 04000130 F8860000 00000004 D2000000 00000000 08800268 E12FFF1E 98860004 FFFE0001 08800268 EAFFFF64 5886000C 00000004 08860008 00000000 0886000C 00000000 D0000000 00000000 98860008 00000001 D9000000 0886000C D4000000 00000001 D6000000 0886000C 6886000C 00000000 08800264 E12FFF1E D2000000 00000000 If you want to change the activators, it's there : (button(s) used to freeze/unfreeze the game) 94000130 FEFF0000 // R = FEFF 88860000 FEFF0000 // R = FEFF and here (button(s) used to advance the game) 94000130 FDFF0000 // L = FDFF 88860000 FDFF0000 // L = FDFF Then, you can select at which 'speed' the game advance when you press L (or whichever button you choosed) : 98860004 FFFE0001 08800268 EAFFFF64 5886000C 00000004 <- 4 = wait for 4 ar code handler execution before freezing the game again. I advise you try the lowest working number. For exemple, I tried 3 in Hotel Dusk, and it wasn't working (after pushin L some dozen of times, the game never unfroze), while using 4 worked better (the game advanced slowly while I was pressing the L button numerous times). However, one could also set this number to 0x10, 0x50... What could this code be good for ? Well, for finding/hacking counters that decrease/increase way too fast I guess... And maybe others unknown purposes... Note that code might now work properly for all games (like the other 'freeze game' code I made). Code: AR (m) codes decrypted ! 1 : 00000000 023F0000 2 : 00000000 02380868 3 : 00000000 037F8700 4 : 00000000 00000001 5 : 00000000 E51DE004 6 : 00000000 023FD000 7 : 00000000 023FE000 8 : 00000000 023FF000 9 : 00000000 00000001 This (m) code has been made for and tested on SM64 v1.01 US. Line #1 : Used prior to launching game. --------------------------------------- Might be used to put some routines that clean the ram and softresets the NDS to actually launch the game (at least there is the reset subroutine at address+0x1314 to address+0x136C, which also means there must be some free space at that address). If no (m) codes are used, it'll be set to the 0x0232.... area. Else, it an (m) code is used, it MUST be set (to something different than 0x0232...). Line #2 : address to write the hook at (inside the ARM7 executable). -------------------------------------------------------------------- If line #4 is set to 0 (or if no (m) code is used), it is used for the autohook creation (see below). Else, it'll hold the address to set the hook at. Line #3 : hook final address. ----------------------------- If line #4 is set to 0 (or if no (m) code is used), it is used for the autohook creation (see below). If line #4 is set to 2, it's the address at which the hook, ie. the BL instruction, will be executed. So this address is used by the AR to actually create the BL instruction (the AR doesn't write anything there). Else, if line #4 is set to 1, it's not used. Line #4 : Hook mode selection. ------------------------------- 0 : automatic hooking (also used if no (m) code is used). 1 : loads the hooked instruction and writes BL at the same address, ie. line #3's address. (means the instruction should not be moved at all by the game, else it'll crash) 2 : load the hook from line #3's address, and write the BL at line #4's address. Line #5 : if <>0, this will be the ARM instruction that replaces the hooked one. -------------------------------------------------------------------------------- Replace, as in 'the original instruction is destroyed, and this one is executed instead'. Can be used to hook a bx r14 that is after a pop {..r14}. Set that instruction to E51DE004 in that case. But as this intruction (or the original instruction, if line #5 is 0ed), is executed before the code handler, it seems a bit limited (ie. you can't hook a bx r2, unless you destroy r14 by moving r2 to r14 (E1A0E002), as bx r14 will be the instruction that will jump back to the game). Might be useful for other things I guess... Line #6 : address to store important stuff (hooking and hook execution routine). -------------------------------------------------------------------------------- If 0ed (or if no (m) code is used), 0x023FE000 will be used by default. Total size is 0x74 bytes. The BL of the hook will point to address + 0x38. There you have the hooked instruction (or line #5's intruction), then a nop (?), then a BL to the code handler. For the TT, the size is 0x98. The added stuff is a routine that checks if L+R is pressed, and one that will check if the ARM7 has the right to access the GBA slot.And it'll jump to the TT's program (at 0x08800000). The hook's BL still points at address+0x38. Line #7 : address to store the code handler. -------------------------------------------- If 0ed (or if no (m) code is used) it'll be put right after the routines written at the address of line #6 (if 0ed = 0x023FE074). Total size is 0x4F0 bytes. Knowing this, porting the ar hacks while the code handler is moved is just an easy operation. Works the same for the TT, however, the code handler that is at this is a copy of the AR code handler (!= TT code handler) which will NOT be executed, the routines at line #6 jumping directly to the TT's program... So it's just wasted space. Line #8 : address to store the code list. ----------------------------------------- If 0ed (or if no (m) code is used) it'll be put right after the routines written at the address of line #7 (ie. default = 0x023FE564). It begins with the ((size of the code list in bytes) >> 2) (=# of codes' lines * 2). Then follow all the codes that have been entered. For the TT the code list will be copied there during game bootup, but it'll not be actually used, the code list inside the TT will is actually used. So it's just wasted space. Line # 9 : Must be 1. --------------------- If not set to 1 the (m) code will not be recognized as an (m) code (and will not be 'executed'). Automatic Hooking informations : -------------------------------- This mode is set when line #4 = 0, or when no (m) code is used. The AR then will create a BL to a part of the code handler (address+0x38) based on the informations of lines #2 and #3. Line #3 will then hold the 32-bits value to look for. Once the value has been found in the ARM7 executable, the AR will scan backward for a bx r14, will backup the instruction just before it (usually it's a POP) and will overwrite it with the BL. By default (if line #3=0, or if no (m) codes are used), the AR will use 0x0380FFF8. Line #2 will hold the number of times the AR will have to REscan for the value at line #3. If no (m) codes are used, this value is set to 1 (which mean the AR will look for the 2nd 0x0380FFF8 it finds in the ARM7 executable). Pad Status informations can be found here. I also made some small tools : Pointer codes Tool (previously named 'Stander to Pointer code tool'), which 'converts' normal codes to pointer codes, given that your enter the correct informations (ie. the location of the pointer in the 'Pointer Address Location', and its value in 'Pointer Address Value'). It also search pointers for you (if you can provide ram dumps and codes addresses). Check this thread. ASM to ARDS, which converts asm into codes (using the nds ar hack #4 I made). It uses the GNU assembler, which needed files are provided in the archive (must be extracted with the ASM to ARDS program), to assemble the asm. And thanks for Para for the infos/help ! Attachment: Edit : Thanks Viper. Update : Erm not quite sure about the ASM hack instruction anymore... Might be 012FFF11 instead of 012FFF31 to avoid any side effect. I'll investigate it later... Update2 : Both 012FFF11 and 012FFF31 work. Also I've corrected the AND/ADD instructions for the AR Hack #2. Edit : updated the B code type and the E code type. They actually use the offset. Didnt noticed it before... Update4 : added informations about the custom (m) codes. |
Author: | Parasyte [ Fri Oct 13, 2006 12:43 pm ] |
Post subject: | |
This looks a lot better than the original doc, even though I've only briefly scanned over it. Thanks. |
Author: | Viper [ Fri Oct 13, 2006 1:57 pm ] |
Post subject: | Re: NDS AR Code Type Information |
kenobi wrote: Type 9 : 16 bits if (code value)==(mask & data at address)
9XXXXXXX ZZZZYYYY : checks if (YYYY) == (not (ZZZZ) & halfword at [XXXX]). If not, the code(s) following this one are not executed (ie. execution status is set to false) until a code type D0 or D2 is encountered, or until the end of the code list is reached. Type A : 16 bits if (code value)!=(mask & data at address) 9XXXXXXX ZZZZYYYY : checks if (YYYY) != (not (ZZZZ) & halfword at [XXXX]). If not, the code(s) following this one are not executed (ie. execution status is set to false) until a code type D0 or D2 is encountered, or until the end of the code list is reached. |
Author: | kenobi [ Tue Oct 17, 2006 5:55 pm ] |
Post subject: | |
Just posted NDS AR HACK #4 : Execute custom asm routine. Here is a concrete exemple on how it works, tested on the real HW, for Super Mario 64 DS (ASMEN1J12 / 1J22) : 023FE074 E3520003 // first part E2098930 00000004 00000001 00000000 94000130 FCFF0000 // second part 023FE074 012FFF31 E0000000 00000014 E59F0008 E3A02063 E5802000 E12FFF1E 02098930 00000000 D2000000 00000000 The first part of this code is the 'normal' E code type, that will copy 00000001 to the address where the lives are stored. So you get one life. The second part of the code uses the hack I made. When L+R are pressed, it will execute the following ASM code : E59F0008 // ldr r0,=02098930h E3A02063 // mov r2,63h E5802000 // str r2,[r0] E12FFF1E // bx r14 02098930 // (data used by the first instruction) which gives you 99 (63h) lives. |
Author: | dlong [ Tue Oct 17, 2006 6:00 pm ] |
Post subject: | |
Nice to see Kenobi's sticking with the good guys. He truely is a wise Jedi/Frenchie. |
Author: | James0x57 [ Thu Oct 19, 2006 8:01 pm ] |
Post subject: | |
lol@dlong I'm just glad he got the docs back. Thank you for the work, Kenobi. |
Author: | Nick [ Thu Nov 09, 2006 1:53 pm ] |
Post subject: | |
Wow, nice breakdown. |
Author: | donny2112 [ Mon Nov 13, 2006 10:52 pm ] |
Post subject: | |
Very nice, kenobi! ![]() |
Author: | dlong [ Tue Nov 14, 2006 9:04 am ] |
Post subject: | |
We got donny! More points for us, GSC still has no one! |
Author: | Parasyte [ Mon Jan 08, 2007 5:33 pm ] |
Post subject: | |
Here are some universal Activator codes which will work on all games: Activator 1 (GBA buttons): 94000130 xxxx0000 For xxxx: FFFE: A FFFD: B FFFB: Select FFF7: Start FFEF: Right FFDF: Left FFBF: Up FF7F: Down FEFF: R FDFF: L Activator 2 (NDS buttons): 927FFFA8 xxxx0000 For xxxx: FBFF: X F7FF: Y DFFF: Debug Button (not available on commercial NDS) 7FFF: NDS not folded To combine one or more buttons together, use bitwise AND: (A & B) = (FFFE & FFFD) = FFFC |
Author: | Kyle [ Mon Jan 08, 2007 5:39 pm ] |
Post subject: | |
Thanks Para. I'll use them in my next MPH subscription. ![]() |
Author: | Parasyte [ Mon Jan 08, 2007 5:42 pm ] |
Post subject: | |
You're welcome. I just added a few more button masks, as well. |
Author: | Kyle [ Mon Jan 08, 2007 6:13 pm ] |
Post subject: | |
Heh, Folded DS... What should I do with that... XD |
Author: | James0x57 [ Mon Jan 08, 2007 6:17 pm ] |
Post subject: | |
Whoa, that's awesome! ![]() Is that AR specific or does it also work for CB? You could do, If folded, then is debug button. hehe |
Author: | Parasyte [ Mon Jan 08, 2007 8:33 pm ] |
Post subject: | |
Only the code type is specific to AR. This code uses masking, which I'm not sure if CB has. The bitwise AND code type on CB may work, though. For something really interesting, try setting the Debug Button bit in that address using a 16-bit constant OR code type. ![]() |
Author: | kenobi [ Mon Jan 08, 2007 8:55 pm ] |
Post subject: | |
Parasyte wrote: For something really interesting, try setting the Debug Button bit in that address using a 16-bit constant OR code type.
![]() Lol sound very interessing ! (erm wouldn't it be a constant AND write ? So set off the bit ? I mean... It works the same than 04000130 (0 = pushed, 1 = released), or the opposite ? (0 = released, 1 = pressed)) |
Author: | Parasyte [ Mon Jan 08, 2007 9:09 pm ] |
Post subject: | |
Oh yes, you are right. Constant AND write. Thanks for the correction. |
Author: | James0x57 [ Mon Jan 08, 2007 9:28 pm ] |
Post subject: | |
Cool! I still haven't opened the CB from CMX because I've been so bussy with Twilight Princess but that's definatly some neat info. ![]() |
Author: | kenobi [ Mon Jan 08, 2007 9:43 pm ] |
Post subject: | |
@Para : Tested the universal Activator code on super mario 64 v1.1 (ASMEN1J22), and it's not working ![]() 927FFFA8 FCFF0000 makes the codes always enabled (and 94000130 FCFF0000 works properly) Edit : However something happens there... I ADDed 027FFFA8 with 0x8000 (=ds closed), and the game kept shutting off the light (and bringing it back). So... It appears afterall that 1 = pushed, 0 = released (as writing 0x8000 simulates the closed ds) ? |
Author: | Parasyte [ Mon Jan 08, 2007 10:09 pm ] |
Post subject: | |
Oh, I see what is going on. That's the buffer for X/Y/Debug buttons only. (And the fold switch.) For other buttons, you have to use 94000130 |
Author: | kenobi [ Mon Jan 08, 2007 10:22 pm ] |
Post subject: | |
Ok ![]() I was affraid to have made some mistakes doing my tests ! Good, can go to work now xD |
Author: | Parasyte [ Mon Jan 08, 2007 11:12 pm ] |
Post subject: | |
All of the buttons are 1 = released (open switch), 0 = pressed (closed switch) except the fold bit. For fold, it is 0 = open NDS (open switch), 1 = closed NDS (closed switch) So the way to test for a closed NDS is with 927FFFA8 7FFF8000 |
Author: | Baphomet [ Wed Jan 10, 2007 8:47 am ] |
Post subject: | |
Para I think you can use 923fffa8 for DS activator too. I have and it works fine. |
Author: | Parasyte [ Wed Jan 10, 2007 2:29 pm ] |
Post subject: | |
0923FFFA8 = 0927FFFA8 The only difference is the second one also works on all incarnations of NDS, including the development kit hardware and emulators with support for 8MB RAM. The first one will only work on commercial NDS and emulators supporting 4MB RAM. Clearly, the second option is the better choice. |
Author: | kickenchicken57 [ Tue Feb 06, 2007 12:47 pm ] |
Post subject: | |
kenobi wrote: Patch Code :
------------ Type E : 'patch' code. Copies YYYYYYYY bytes from (curent code location + 8) to XXXXXXXX. EXXXXXXX YYYYYYYY ... exemple : EXXXXXXX 00000010 AAAAAAAA BBBBBBBB CCCCCCCC DDDDDDDD writes AAAAAAAABBBBBBBBCCCCCCCCDDDDDDDD to XXXXXXXX (XXXXXXXX is fixed, ie. no offset are added to it). If the execution status if set off, the AR skips all the line of the patch code (skips (YYYYYYYY+7)>>2 codes). Memory Copy Code : ------------------ Type F : memory copy code. It seems you have to use the code type D3, DC or B before, to set the offset (which is then an address). Then D2 should be needed to clear the offset (else it will affect all the next codes). D3000000 XXXXXXXX FYYYYYYY ZZZZZZZZ should copy ZZZZZZZZ bytes from offset (=XXXXXXXX in this case) to YYYYYYYY (YYYYYYYY if fixed, ie. no offset are added to it). * The E and F type work as follow : If the number of data to write/copy if >3, it is done with a ldr/str, and then 4 is removed from the number of data to copy. Else, if the number of data to copy if <3, it's done with a ldrb/strb and then 1 is removed from the number of data to copy. And it loops until the number of data to copy is eqal to zero. That means that the first address to write to must be aligned in case of the number of bytes to copy is superior to 3 (else there will be a 'bug' if the number of code to write is > 3 and not a multiple of 4), and that the number of bytes to write doesn't not have to be a multiple of 4 (can be any number). Can you explain how to calculate the YYYYYYYY in the E type code a little better? and what do you mean by "the first address to write to must be aligned" I am trying to figure out exactly how to use this 'E' code for part of my AR Workshop program but I am a little confused |
Author: | kenobi [ Tue Feb 06, 2007 2:34 pm ] |
Post subject: | |
Yeah, I should have detailled it a bit more (but I tried to explain how the AR was doing the copy, so people could get a grip on what was going on). I meant : - YYYYYYYY is the destination starting address. - It is fixed, ie. the data will always copied starting at YYYYYYYY, whatever the offset is. - It must be aligned, which actually meant must be 32-bits aligned unless you copy a multiple of 4 bytes data. And actually, both the source and destination addresses must be aligned. If they are not 'aligned', problems will arise : For exemple, you want to copy 5 bytes, 11 22 33 44 55, from 02040000 to 02000001 (non-aligned destination address ; concerns the E and F codes type). The AR will start by doing an incremental ldr/str. It'll load the 32-bits at 02040000, will write them to 02000001 (which will actually write the data to 02000000), and it increments both addresses by 4. 02040000 ->02040004, and 02000001 -> 02000005. Then, as the number of bytes to copy is not a multiple of 4, it will do ldrb/strb to finish the copying. It'll load one byte, at 02040004, but it'll write it to 02000005 (and not 02000004). So, in the end, you'll have readen 02040000 : 11 22 33 44 55, but you'll have written 11 22 33 44 XX 55 to 02000000 (XX being whatever the value of the byte at 02000004 was - it is unchanged, as the AR doesn't overwrite it). So using an unaligned destination address and a number of bytes to copy that is not a multiple of 4 make the AR 'jump' for n bytes when writing the last bytes (n being (destination address & 3)). For exemple, you want to copy 5 bytes, 11 22 33 44 55, from 02040001 to 02000000 (non-aligned source address ; only concerns the F code type). The AR will start by doing an incremental ldr/str. It'll load the 32-bits at 02040001 (which will actually read the data from 02040000), will write them to 02000000, and it increments both addresses by 4. 02040001 ->02040005, and 02000000 -> 02000004. Then, as number of bytes to copy is not a multiple of 4, it will do ldrb/strb to finish the copying. It will load one byte, at 02040005 (and not 02040004), but it'll write it to 02000004. So, in the end, you'll have readen 02040000 : 11 22 33 44 55 XX, and you'll have written 11 22 33 44 XX to 02000000 (XX being whatever the value of the byte at 02040005 was). So using an unaligned source address and a number of bytes to copy that is not a multiple of 4 makes the AR 'jump' n bytes when reading the last bytes (n being source (address & 3)). Now I might add the the info I'm giving here might not be 100% accurate, dealing with unaligned addresses might give strange results. But what is certain is that the copying will be corrupted, and could lead to unwanted side effects : glitches/crashes/loss of save data/nds explosion... So it should be avoided by all means. |
Author: | kickenchicken57 [ Tue Feb 06, 2007 4:57 pm ] |
Post subject: | |
kenobi wrote: Yeah, I should have detailled it a bit more (but I tried to explain how the AR was doing the copy, so people could get a grip on what was going on). I meant : - YYYYYYYY is the destination starting address. - It is fixed, ie. the data will always copied starting at YYYYYYYY, whatever the offset is. kenobi wrote: For exemple, you want to copy 5 bytes, 11 22 33 44 55, from 02040000 to 02000001 (non-aligned destination address ; concerns the E and F codes type).
Forgive me if I am wrong, but is most of this concerning the 'F' code type? If I am correct the F code copies values from one or more address[s] to another. What I wanted to know is how exactly the 'E' code is created. I am trying to figure out how it works by looking at this code for MPH: /root Board (hold L+R while loading Wifi) 920de4ee 00000100 e20eae04 00000044 000f02ee 00001D00 00001DCF 00000000 00000000 00055EBB 0002F1AD 0004D444 00000000 00000000 00000000 00000000 00000028 0000086A 00000000 00000000 000f00F9 00000000 d3000000 020eae04 f225e864 00000044 D0000000 00000000 Again, Please correct me if I am wrong: From what I understand the 'E' code should start at the address 020eae04 and copy the values following the code to 020eae04 and increment the address by 8 each time right? but what is the YYYYYYYY for and how is it calculated? in this case YYYYYYYY is 44. I thought at first that the YYYYYYYY had to do with how many values are written the the address at XXXXXXXX but Im not quite sure right now. Also is the 'E' code used as a Rom Patch type of code or can this be used on Ram Codes? Once again, thanks for taking the time to explain this to me. It is very much appreciated and you have already been added to the credits in AR Workshop. If it wasnt for this topic I probably couldnt have created half of what I have planned for my app. Also, I would like to add all of the AR Code type documentation into the helpfile for AR Workshop. This would be (hopefully) in the first "official" release and of course be credited to you if that is alright. |
Author: | Parasyte [ Tue Feb 06, 2007 6:19 pm ] |
Post subject: | |
ACK! (Nitpick time: Please use capital letters and some form of hexadecimal notation where applicable. Thanks!) 'E' code type, 'patch code' example: E20EAE04 00000044 This will copy the following 0x44 bytes to address 0x020EAE04. The bytes copied in this example are as follows: 000F02EE 00001D00 00001DCF 00000000 00000000 00055EBB 0002F1AD 0004D444 00000000 00000000 00000000 00000000 00000028 0000086A 00000000 00000000 000F00F9 00000000 <-- Note that the very last '00000000' (with the arrow) is unused, and only for padding the line to the proper 16-digit width. All 'E' codes will have to be padded like this if they are not writing exactly a multiple of 8 bytes. Think of the 'YYYYYYYY' as the number of bytes for it to copy, always pad your codes, and ONLY use 32-bit aligned addresses (address must end with one of: 0, 4, 8, C) unless you REALLY know what you are doing. FYI: ROM can NOT be patched on NDS, due to the data read protocol used. It's more like an SD card or CD-ROM drive than a GBA cart. ROM patches can be simulated with a little bit of card lib patching, however. (Patching parts of the executable in RAM that has to do with reading the NDS card.) But I doubt there is any real need for this. |
Author: | kickenchicken57 [ Wed Feb 07, 2007 6:41 am ] |
Post subject: | |
OK, DONT SHOOT I now realize that its 0x44 bytes to copy and not 44(dec) bytes to copy. hehe, guess we all have our moments. anyways thanks kenobi and Parasyte and also Parasyte wrote: (Nitpick time: Please use capital letters and some form of hexadecimal notation where applicable. Thanks!)
this is a good rule ![]() |
Author: | kickenchicken57 [ Mon Feb 12, 2007 10:44 am ] |
Post subject: | |
Parasyte wrote: Here are some universal Activator codes which will work on all games:
Activator 2 (NDS buttons): 927FFFA8 xxxx0000 For xxxx: FBFF: X F7FF: Y DFFF: Debug Button (not available on commercial NDS) 7FFF: NDS not folded Heres a question, is BFFF unused? I noticed that it comes in between Debug Button and NDS not folded so is there a reason the buttons skip one bit (maybe the light on or off?) or is it just unused? |
Page 1 of 6 | All times are UTC - 8 hours [ DST ] |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |