Hacking NDS

From Wiki - GameHacking.org
Jump to: navigation, search
EnHacklopedia >> {{ #ifeq: Hacking NDS | EnHacklopedia | Index | Hacking NDS }}


Action Replay DS

Action Replay for NDS

Description

The first commercial DS cheat code solution, this device was developed by Datel. It supports swapping out cartridges after loading the AR software. For updating, the user may either manually enter codes or use the included proprietary USB cable that comes with the device. The user has been able to manually update codes since firmware version 1.52.

Code Types

Type Description
Constant RAM Writes
Type 0x00
32-bit
0XXXXXXX YYYYYYYY
Writes word YYYYYYYY to [XXXXXXX+offset].
Type 0x01
16-bit
1XXXXXXX 0000YYYY
Writes halfword YYYY to [XXXXXXX+offset].
Type 0x02
8-bit
2XXXXXXX 000000YY
Writes byte YY to [XXXXXXX+offset].
Conditional 32-Bit Code Types
Type 0x03
Less Than
3XXXXXXX YYYYYYYY
Checks if YYYYYYYY < (word at [XXXXXXX])
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 0x04
Greater Than
4XXXXXXX YYYYYYYY
Checks if YYYYYYYY > (word at [XXXXXXX]).
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 0x05
Equal To
5XXXXXXX YYYYYYYY
Checks if YYYYYYYY == (word at [XXXXXXX]).
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 0x06
Not Equal To
6XXXXXXX YYYYYYYY
Checks if YYYYYYYY != (word at [XXXXXXX]).
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.
Conditional 16-Bit + Masking RAM Writes
Type 0x07
Less Than
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 0x08
Greater Than
8XXXXXXX ZZZZYYYY
Checks if (YYYY) > (not (ZZZZ) & halfword at [XXXXXXX]).
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 0x09
Equal To
9XXXXXXX ZZZZYYYY
Checks if (YYYY) == (not (ZZZZ) & halfword at [XXXXXXX]).
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 0x0A
Not Equal To
AXXXXXXX ZZZZYYYY
Checks if (YYYY) != (not (ZZZZ) & halfword at [XXXXXXX]).
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 Codes
Type 0x0B
Load offset
BXXXXXXX 00000000
Loads the 32-bit value into the 'offset'.
Offset = word at [0XXXXXXX + offset].
Type 0xD3
Set offset
D3000000 XXXXXXXX
Sets the offset value to XXXXXXXX.
Type 0xDC
Set offset
DC000000 XXXXXXXX
Adds an offset to the current offset. (Dual Offset)
Loop Code
Type 0x0C
C0000000 YYYYYYYY
This sets the 'Dx repeat value' to YYYYYYYY and 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
Type 0xD0
Terminator
D0000000 00000000
Loads the previous execution status. If none exists, the execution status stays at 'execute codes'.
Type 0xD1
Loop execute variant
D1000000 00000000
Executes the next block of codes 'n' times (specified by the 0x0C code type), but doesn't clear the Dx register upon completion.
Type 0xD2
Loop Execute Variant/ Full Terminator
D2000000 00000000
Executes the next block of codes 'n' times (specified by the 0x0C code type), and clears all temporary data. (i.e. execution status, offsets, code C settings, etc.)
This code can also be used as a full terminator, giving the same effects to any block of code.
Data Register Codes
Type 0xD4
Add Value
D4000000 XXXXXXXX
Adds 'XXXXXXXX' to the data register used by code types 0xD6 - 0xDB.
More arithmetical/logical operations can be set using the 'NDS AR HACK #2'.
Type 0xD5
Set Value
D5000000 XXXXXXXX
Set 'XXXXXXXX' to the data register used by code types 0xD6 - 0xD8.
Type 0xD6
32-Bit Incrementive Write
D6000000 XXXXXXXX
Writes the 'Dx data' word to [XXXXXXXX+offset], and increments the offset by 4.
Type 0xD7
16-Bit Incrementive Write
D7000000 XXXXXXXX
Writes the 'Dx data' halfword to [XXXXXXXX+offset], and increments the offset by 2.
Type 0xD8
8-Bit Incrementive Write
D8000000 XXXXXXXX
Writes the 'Dx data' byte to [XXXXXXXX+offset], and increments the offset by 1.
Type 0xD9
32-Bit Load
D9000000 XXXXXXXX
Loads the word at [XXXXXXXX+offset] and stores it in the'Dx data register'.
Type 0xDA
16-Bit Load
DA000000 XXXXXXXX
Loads the halfword at [XXXXXXXX+offset] and stores it in the'Dx data register'.
Type 0xDB
8-Bit Load
DB000000 XXXXXXXX
Loads the byte at [XXXXXXXX+offset] and stores it in the'Dx data register'.
This is a bugged code type. Check 'AR Hack #0' for the fix.
Miscellaneous Memory Manipulation Codes
Type 0x0E
Patch Code
EXXXXXXX YYYYYYYY
Copies YYYYYYYY bytes from (current code location + 8) to [XXXXXXXX + offset].
Type 0x0F
Memory Copy Code
FXXXXXXX YYYYYYYY
Use the code type D3, DC or B before to set the offset. D2 should be needed to clear the offset after the code.
D3000000 XXXXXXXX
FYYYYYYY ZZZZZZZZ
This should copy ZZZZZZZZ bytes from offset (=XXXXXXXX in this case) to YYYYYYYY. (YYYYYYYY if fixed, no offsets are added to it).

Code 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 (since the 'M' code changes the location of the code handler in memory).

Type Description
Hack #0
0xDB Code Type Fix
023FE4D8 0A000003
Fixes a bug in the Action Replay Code Handler.
Hack #1 - Offset Support for Conditionals
Offset support:
023FE20C E5933000
No offset support
023FE20C E5903000
For code type 0x03
Offset support:
023FE224 E5933000
No offset support:
023FE224 E5903000
For code type 0x04
Offset support:
023FE23C E5933000
No offset support:
023FE23C E5903000
For code type 0x05
Offset support:
023FE254 E5933000
No offset support:
023FE254 E5903000
For code type 0x06
Offset Support:
023FE26C E1D320B0
023FE270 E1E03004
No offset support:
023FE26C E1E03004
023FE270 E1D020B0
For code type 0x07
Offset Support:
023FE290 E1D320B0
023FE294 E1E03004
No offset support:
023FE290 E1E03004
023FE294 E1D020B0
For code type 0x08
Offset Support:
023FE2B4 E1D320B0
023FE2B8 E1E03004
No offset support:
023FE2B4 E1E03004
023FE2B8 E1D020B0
For code type 0x09
Offset Support:
023FE2D8 E1D320B0
023FE2DC E1E03004
No offset support:
023FE2D8 E1E03004
023FE2DC E1D020B0
For code type 0x0A
Offset Support:
C0000000 00000003
023FE20C E5933000
DC000000 00000018
D2000000 00000000
No offset support:
C0000000 00000003
023FE20C E5903000
DC000000 00000018
D2000000 00000000
For code types 0x03 - 0x06 all at once.
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
For code types 0x07 - 0x0A all at once.
Hack #2 - ORR/AND/ADD Codes
023FE424 E1833004 Makes the D4 code type execute a 'ORR' instruction.
023FE424 E0033004 Makes the D4 code type execute a 'AND' instruction.
023FE424 E0833004 Makes the D4 code type execute an 'ADD' instruction.
Hack #3 - Add Dx Data to Offset Codes
023FE424 E08AA003 This code changes the D4 code type to make it add the Dx Data to the offset.
It could be useful if the game's pointer's offset changes.
Hack #4 - Execute Custom ASM Routines
023FE074 012FFF11 This code changes the 0x0E code type to make it execute the data entered by the hacker.
023FE074 E3520003 Reverts code type 0x0E to normal
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).
To learn more read the ARM9 Assembly section.


Codebreaker DS

Front of the Codebreaker DSBack of the Codebreaker DS

Description

This is Pelican's entry into the DS cheat-device industry. It supports swapping out the cartridges and also gives the user the option of connecting another game card onto it. For updating, the user may either manually enter codes or use WiFi to connect to a computer running the Codebreaker software.

Code Types

Type Description
Auto-Game Recognizers
Type 0x00
With Encryption
0000YYYY XXXXXXXX
YYYY = Game's Header CRC16
XXXXXXXX = Game's Nintendo ID
Type 0x08
Without Encryption
8000YYYY XXXXXXXX
YYYY = Game's Header CRC16
XXXXXXXX = Game's Nintendo ID
Constant RAM-Write Codes
Type 0x00
8-Bit
0XXXXXXX 000000YY
XXXXXXX = Address to be written to
YY = Byte to be written
Type 0x10
16-Bit
1XXXXXXX 0000YYYY
XXXXXXX = Address to be written to
YYYY = Halfword to be written
Type 0x20
32-Bit
2XXXXXXX YYYYYYYY
XXXXXXX = Address to be written to
YYYYYYYY = Word to be written
Increment/Decrement Codes
Type 0x30
8/16-Bit
3XXXXXXX 000UYYYY
XXXXXXX = Address to be written to
U = Bit-type Write, 0 for 8-Bit and 1 for 16-Bit
YYYY = Halfword/Byte to be written
Type 0x38
32-Bit
3XXXXXXX YYYYYYYY
XXXXXXX = Address to be written to
YYYY = Word to be written
Serial Repeat Constant Write (Slider) Code
Type 0x40
Slider
4XXXXXXX TWWWZZZZ
YYYYYYYY VVVVVVVV
XXXXXXX = Address to be written to
T = Bit-type Write, 0 for 32-Bit, 1 for 16-Bit and 2 for 8-Bit
WWW = Number of times to repeat
ZZZZ = Increase Address by (Multiply by data size (1 << (2 - T)))
YYYY = Word to be written
VVVVVVVV = Increase Value by
Memory Copy Code
Type 0x50
Copy Bytes
5XXXXXXX YYYYYYYY
ZZZZZZZZ 00000000
XXXXXXX = Address to be copied to
YYYYYYYY = Number of Bytes to copy
ZZZZZZZZ = Address to copy from
Pointer
Type 0x60
Copy Bytes
6XXXXXXX YYYYYYYY
ZZZZZZZZ BCTUVVVV
XXXXXXX = Pointer Address
YYYYYYYY = Word/Halfword/Byte to be written
ZZZZZZZZ = Offset to add to the Pointer Address
B = Bit-type Write, 0 for 8-bit, 1 for 16-Bit, and 2 for 32-Bit
C = Condition Enabled, 0 for disabled, 1 for enabled
T = Condition type to check against VVVV [0 is ==, 1 is !=, 2 is <, 3 is>, 4 is == and == 0000, 4-7 follow the pattern set by 0-3]
U = Bit-type Load, 0 for 8-Bit, and 1 for 16-Bit
VVVV = Halfword/Byte to check against
8/16-Bit Special Bitwise Write
Type 0x70
7XXXXXXX 00TBYYYY
XXXXXXX = Address to be written to
YYYY = Halfword/Byte to be written
T = Operation type, 0 for OR, 1 for AND, 2 for XOR
B = Bit-type Write, 0 for 8-Bit, and 1 for 16-Bit
32-Bit Write On Bootup-Hooks
Type 0xA0
Hook 1
AXXXXXXX YYYYYYYY
XXXXXXX = Address to be written to
YYYY = Word to be written
Type 0xA8
Hook 2
AXXXXXXX YYYYYYYY
XXXXXXX = Address to be written to
YYYY = Word to be written
Conditional Codes
Type 0xD0
16-Bit
DXXXXXXX ZZTUYYYY
ZZ = Lines to skip, 00 means 01 by default XXXXXXX = Pointer Address
YYYY = Word/Halfword/Byte to be written
T = Condition type to check against VVVV [0 is ==, 1 is !=, 2 is <, 3 is>, 4 is == and == 0000, 4-7 follow the pattern set by 0-3]
U = Bit-type Load, 0 for 16-Bit, and 1 for 8-Bit
VVVV = Halfword/Byte to check against
Enable Code-Hooks
Type 0xF8
Hook 2
FXXXXXXX TYYYYYYY

XXXXXXX = Hook Address
T = Type of Hook to use. See the CBDS Master Code section for more info
YYYYYYY = Cheat Engine Address

Using CBDSCrypt

CBDSCrypt is a utility developed by kenobi. It is capable of both encrypting and decrypting codes for the Codebreaker DS, as well as creating master codes. A ROM of the game the codes are for is required in order to use this application. To use the program, simply run it, and then drag and drop the ROM image on top of the program. Paste the codes that are to be encrypted or decrypted into the left text area, and press the appropriate button "encrypt" or "decrypt" and the resulting codes will appear in the right text area.

Master codes can be generated by pressing the (M) button. This program uses two methods to generate potential master codes, Parasyte's method and kenobi's method. Parasyte's method entails finding the location of the following instructions in both of the ARM executables:

Inst Operands Comments
ldr r1, =intr_table @ 0xE59F1008
ldr r0, [r1,r0,LSL#2] @ 0xE7910100
ldr lr, =ret_loc @ 0xE59FE004
bx r0 @ 0xE12FFF10

They might not be found in the ARM9 executable because of decompression, but it will always be in plain sight in the ARM7. All that is necessary is to hook that =ret_loc, which is always 2 words after that bx r0. It is done the same way as hooking any other pointer. This is also how Kwurdi's automatic hook search has functioned for the last two and half years, and it hasn't failed yet.

Kenobi's method involves simulating the ARDS's automated (M) code finder. To start, search for the 32-bit value 0x0380FFF8, beginning at the ARM7 executable. After this is found, search for the following 0x0380FFF8. Following this, search backwards for the first bx r14 (0xE12FFF13). Subtract 4 from this address and then convert it to a RAM address. To convert it to a RAM address, take the address and subtract the 32-bit value that is located at 0x30 in the ROM; then add the 32-bit value that is located at 0x38 in the ROM. The (M) code is F2[ram address] 023FC000.

Nitro Hax

Nitro Hax in No$gba

Description

This a homebrewed alternative to the others written by DS Homebrewer Chishm. It runs off of a flash cart, from which it can parse official Action Replay subscriptions. This device supports all official Action Replay code types, using a custom cheat handler.

Code Types

Type Description
Constant RAM Writes
Type 0x00
32-bit
0XXXXXXX YYYYYYYY
Writes word YYYYYYYY to [XXXXXXX+offset].
Type 0x01
16-bit
1XXXXXXX 0000YYYY
Writes halfword YYYY to [XXXXXXX+offset].
Type 0x02
8-bit
2XXXXXXX 000000YY
Writes byte YY to [XXXXXXX+offset].
Conditional 32-Bit Code Types
Type 0x03
Greater Than
3XXXXXXX YYYYYYYY
Checks if YYYYYYYY> (word at [XXXXXXX])
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 thecode list is reached.
Type 0x04
Less Than
4XXXXXXX YYYYYYYY
Checks if YYYYYYYY < (word at [XXXXXXX]).
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 0x05
Equal To
5XXXXXXX YYYYYYYY
Checks if YYYYYYYY == (word at [XXXXXXX]).
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 0x06
Not Equal To
6XXXXXXX YYYYYYYY
Checks if YYYYYYYY != (word at [XXXXXXX]).
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.
Conditional 16-Bit + Masking RAM Writes
Type 0x07
Greater Than
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 0x08
Less Than
8XXXXXXX ZZZZYYYY
Checks if (YYYY) < (not (ZZZZ) & halfword at [XXXXXXX]).
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 0x09
Equal To
9XXXXXXX ZZZZYYYY
Checks if (YYYY) == (not (ZZZZ) & halfword at [XXXXXXX]).
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 0x0A
Not Equal To
AXXXXXXX ZZZZYYYY
Checks if (YYYY) != (not (ZZZZ) & halfword at [XXXXXXX]).
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 Codes
Type 0x0B
Load offset
BXXXXXXX 00000000
Loads the 32-bit value into the 'offset'.
Offset = word at [0XXXXXXX + offset].
Type 0xD3
Set offset
D3000000 XXXXXXXX
Sets the offset value to XXXXXXXX.
Type 0xDC
Set offset
DC000000 XXXXXXXX
Adds an offset to the current offset. (Dual Offset)
Loop Code
Type 0x0C
C0000000 YYYYYYYY
This sets the 'Dx repeat value' to YYYYYYYY and 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
Type 0xD0
Terminator
D0000000 00000000
Loads the previous execution status. If none exists, the execution status stays at 'execute codes'.
Type 0xD1
Loop execute variant
D1000000 00000000
Executes the next block of codes 'n' times (specified by the 0x0C code type), but doesn't clear the Dx register upon completion.
Type 0xD2
Loop Execute Variant/ Full Terminator
D2000000 00000000
Executes the next block of codes 'n' times (specified by the 0x0C code type), and clears all temporary data. (i.e. execution status, offsets, code C settings, etc.)
This code can also be used as a full terminator, giving the same effects to any block of code.
Data Register Codes
Type 0xD4
Add Value
D4000000 XXXXXXXX
Adds 'XXXXXXXX' to the data register used by code types 0xD6 - 0xDB.
More arithmetical/logical operations can be set using the 'NDS AR HACK #2'.
Type 0xD5
Set Value
D5000000 XXXXXXXX
Set 'XXXXXXXX' to the data register used by code types 0xD6 - 0xD8.
Type 0xD6
32-Bit Incrementive Write
D6000000 XXXXXXXX
Writes the 'Dx data' word to [XXXXXXXX+offset], and increments the offset by 4.
Type 0xD7
16-Bit Incrementive Write
D7000000 XXXXXXXX
Writes the 'Dx data' halfword to [XXXXXXXX+offset], and increments the offset by 2.
Type 0xD8
8-Bit Incrementive Write
D8000000 XXXXXXXX
Writes the 'Dx data' byte to [XXXXXXXX+offset], and increments the offset by 1.
Type 0xD9
32-Bit Load
D9000000 XXXXXXXX
Loads the word at [XXXXXXXX+offset] and stores it in the'Dx data register'.
Type 0xDA
16-Bit Load
DA000000 XXXXXXXX
Loads the halfword at [XXXXXXXX+offset] and stores it in the'Dx data register'.
Type 0xDB
8-Bit Load
DB000000 XXXXXXXX
Loads the byte at [XXXXXXXX+offset] and stores it in the'Dx data register'.
This is a bugged code type. Check 'AR Hack #0' for the fix.
Miscellaneous Memory Manipulation Codes
Type 0x0E
Patch Code
EXXXXXXX YYYYYYYY
Copies YYYYYYYY bytes from (current code location + 8) to [XXXXXXXX + offset].
Type 0x0F
Memory Copy Code
FXXXXXXX YYYYYYYY
Use the code type D3, DC or B before to set the offset. D2 should be needed to clear the offset after the code.
D3000000 XXXXXXXX
FYYYYYYY ZZZZZZZZ
This should copy ZZZZZZZZ bytes from offset (=XXXXXXXX in this case) to YYYYYYYY. (YYYYYYYY if fixed, no offsets are added to it).

Dipstar

Dipstar in No$gba

Description

The most unprofessional looking of the lot, this homebrew outdates all other cheat devices. This piece of software is the only one that can support ROMs, and will only run off certain flash carts.

Code Types

Ways to Hack

Without Real Hardware

There are several different ways to hack Nintendo DS codes without real hardware. Most of these methods entail the use of emulators and ROMs.

  • Renegade64 + No$gba This article assumes general usage knowledge of Renegade 64. After attaching Renegade 64 to No$gba, all that is needed to do is to bring up the cheat search window as normal. This is the recommended method.Tips for optimal No$gba usage:
    • Set "GBA Mode" To "VGA (Poppy Bright)".
    • The majority of games use "EEPROM 8Kbytes" and their NDS Cartridge Backup Media.
    • If the sound is crap, it is better to disable it to gain speed.
    • If games run slow, setting "Emulation Speed" to "Unlimited MHZ Disaster- 10%" may help.
  • HasteDS + Other Emulators HasteDS (unaffectionately called HateDS) is a less-powerful, somewhat buggy emulator hooker (Heh). While less powerful, it can hook a variety of other emulators.HasteDS
    Emulators HasteDS can hook:
    • No$gba.
    • DeSmuME.
    • iDeaS.
    • NeeDS

Using Datel's Trainer Toolkit

Starting Out

An Action Replay with firmware version 1.52 or higher is required to use the toolkit. An Action Replay is not included with the Toolkit.

To start Training, insert the Trainer Board into the GBA slot of your DS or DS Lite. Connect the supplied USB cable from the mini USB port on the left side of the Trainer Board to a spare USB port on a nearby computer. Next, insert the Action Replay DS into the DS slot of DS or DS Lite being used. It is not necessary to connect your AR to the computer to use the Toolkit. AFter starting up the DS or DS Lite, Windows will detect the Trainer Board. If the drivers for the Toolkit have not been installed, do so now by following the instructions in the manual. At the point the Action Replay logo appears on screen, remove your ARDS in insert the game to be trained. Tap the bottom screen to start.

Next the hacker must open up the Trainer software on the computer he is using. By default, it will start a new file. If there is an existing file, the hacker may open it via the "File" menu. To access the tools described below, click the "Tools" menu then click on the tool to be opened. An electronic version of the included manual can be accessed by clicking "Help".

TT Main Window

Hacking

Click "New Search". Then choose the data type. By default, the <acronym title="Trainer Toolkit">TT</acronym> will list 2 items under "Memory Ranges". The one called "Working RAM" may be removed. As the manual for the toolkit states, nothing of interest has ever been found here. If the hacker knows of a specific memory range they want to search in, then he may also remove the Main RAM, then click on "Add". The hacker will need to supply the range a name, a starting address, and an ending address. Remember to prefix with a "0x0". The ability to save and load ranges is included. Narrowing the range is useful, sometimes necessary, if the hacker needs to perform searches while connected to the Nintendo WiFi Connection as the time it takes to complete a full search of the Main RAM will take too long and the hacker will ping out.

To perform another search, choose the appropriate condition and click "Search Again". To search for a specific value in the RAM, select "Equal to" and uncheck "Previous Value". The value box will now be typed in. clicking the triangle next to the text box will allow the hacker to see previous values that have been entered. Remember to prefix the value with a 0x.

After the search is complete, the results will appear in the "Search Results" window. Each search appears next to its own purple square. Next to the square is the search number and the number of results. Clicking the "+" next to the purple square will show the individual memory ranges searched. To view the results for that memory range, double click the text next to the green square. A window will appear showing each address in numerical order and the value for the current and previous searches. The results window can display 1000 results maximum.

Toolkit: Watched Locations

The Trainer Toolkit software allows the hacker to monitor desired locations in the RAM within the "Watched Locations" window. To add a location to the "Watched Locations", right click anywhere in the "Watched Locations" window and choose "Add Location". Be sure to prefix the address with a 0x0. You also need to choose the data type. Notes are optional but they do help. You can also add locations from the any search result by right clicking on the address or value and choosing "Add to watch-list". By right clicking on items the "Watched Locations" window you can edit the information for that address and remove it.

The Run-list

The "Run-list" is an Action Replay that is updatable on-the-fly. Each code is separated by a blank line. The "Run-list" will accept all of the Action Replay code types along with some Trainer Toolkit-only code types. Each instruction may be placed on its own line or grouped together in one line with each instruction separated by a space. Stop the execution of a line of code is accomplished by commenting it out. Commenting can also be used to make notes in the "Run-list". The "Run-list" will accept double forward slashes (//) which will comment out the rest of the line following them. You may also use (/* ..... */) to comment out multiple lines. To upload the "Run-list" to the Trainer Toolkit for execution, click upload. Whenever changes are made to the "Run-List", it will be necessary to upload the list again.

Toolkit: Disassembly View

This window is not of use unless the hacker is familiar with Assembly. As the manual states, this is not a complete disassembler. An IDA Pro can be of use for disassembly if one is needed badly. By default, the disassembler will be in THUMB mode. To switch it into ARM, right click and choose "Switch to ARM". To go to a certain address, right click and choose "Goto address". Remember to prefix the address with a 0x0.

The Hex View Window

The Hex View window displays all the values in an area of memory. To go to a certain address, right click in the window and choose "Goto Address". From the right click menu the hacker can also refresh the view with the current values in memory or toggle Auto Refresh. Another useful feature within this window is the ability to export a full RAM dump. To do this, right click and choose "Save To File". A memory address range must be specified. The file browser will appear, giving the hacker the options of saving and naming the file. No extension is added to the RAM Export by default, although it is very easy to give it one. Note that when a RAM Export is performed, the Toolkit is exporting the values in the RAM as they are when "SAVE" was clicked, not as they appear in the hex view. Double clicking a value in the "Hex View" window will add it as a watched location.


Universal Activators

All commercial DS games share two universal activators, one used for handling all the buttons the GBA has and another used for the DS-unique buttons. The address for the GBA buttons is at 0x04000130, and the address for DS-specific button address is located at 0x027FFFA8. However, these activators are used differently depending on what cheat code device is being used.

Action Replay Specific

Action Replay code type 0x09 gives the hacker some nice flexibility with activators. This code type gives the hacker the option of executing code when a value is not equal to the value specified. Using this attribute we can make codes that can be activated when more than one button is being pressed. The following is a list of inverted values for DS key presses.

Value Button
GBA Activator Values
FFFE A
FFFD B
FFFB Select
FFF7 Start
FFEF Right
FFDF Left
FFBF Up
FF7F Down
FEFF Right Trigger
FDFF Left Trigger
NDS Activator Values
FBFF X
F7FF Y
DFFF Debug Button
7FFF NDS Not Folded

Bitwise AND is used to combine two or more buttons together. (A & B) = (FFFE & FFFD) = FFFC

Codebreaker Specific

The Codebreaker DS conditional code type cannot execute if !=. To use the activators with Codebreaker, a different set of activator values are needed.

Value Button
GBA Activator Values
0001 A
0002 B
0004 Select
0008 Start
0010 Right
0020 Left
0040 Up
0080 Down
0100 Right Trigger
0200 Left Trigger
NDS Activator Values
0400 X
0800 Y
2000 Debug Button
8000 NDS Not Folded

Bitwise OR is used to combine two or more buttons together. (A | B) = (0001 | 0002) = 0003


ARM9 Assembly

The NDS uses an ARM9 chip as its main processor. The ARM architecture provides two modes, ARM and THUMB, and well as 31 32-bit registers. Only 16 of these registers are visible at a time, with R13, R14, and R15 being for the Stack Pointer, the Link Register, and the Program Counter respectively. The ARM instruction set uses 32-bit operations, whereas the THUMB set uses 16-bit. THUMB is designed to produce smaller code with the same speed as ARM and much of the functionality. One major limitation of THUMB is that many instructions cannot access registers above R07. In ARM, 4 bits are set aside for a conditional. The operation is executed only if the current flags meet that condition. More information on ARM and THUMB can be found in the official ARM and THUMB manuals, as well as GBATek, all provided on the documents page. Compared to the GBA's ARM7 processor, the ARM9 is almost identical, with a few extra, rarely-used instructions.

Action Replay-Specific Assembly Hacking

32-Bit RAM Write

Here is an example ASM code that does the same thing as a 32-bit ram write code. This example will use the "See Though Walls" code for Metroid Prime: Hunters found in the Codejunkies code subscription.

AR Code
02046410 E3A0001E

All that is needed in ASM is to write this 32-bit value to the correct address. To do the equivalent of the code in ASM, the address and value for the code must both be loaded into a register. The next, and final, step is to store the value into the address.

opcode arguments comments
ldr r0, =0x02046410 ; Load the address to be written to into r0
ldr r1,=0xE3A0001E ; Load the value to be written into r1
str r1,[r0] ; Store the value in r1 to the address pointed to by r0
bx r14 ; End branch

The first line of the code sets r0 equal to 0x02046410 and the second line sets r1 equal to 0xE3A0001E. The next command str r1,[r0] stores the value of the first operand into the address pointed to by the second operand. This means that address 0x02046410 will now hold the value 0xE3A0001E which is all that is needed to accomplish a 32-bit ram write code. The last line bx r14 is an important one. This line is required at the end of all ASM codes for the AR to back to the code list and continue executing codes. Now the ASM is finished it must be converted into a code that can be entered into the AR. Using Kenobi's ASM to ARDS tool found in the tools section of this document, place the ASM code in the left window and click the convert button. The output should be:

AR Code
023FE074 012FFF11
E0000000 00000018
E59F0008 E59F1008
E5801000 E12FFF1E
02046410 E3A0001E
023FE074 E3520003

Add this code into the Action Replay and the effect should be the same as the original code. Of course this code is not very efficient as it takes up more space and was harder to create, but it is just an example. There are times when it is appropriate to use an ASM code and other times where it is better to use the built in code types. An example of a good use would be when a hacker needs to calculate a value for the offset in a complicated manner (Which will be covered in the next section).

Calculating the Action Replay Offset

An effective use of ASM is using it to calculate the Action Replay offset in a complicated manner that in unachievable through normal code types. Most codes for WiFi multiplayer on the Nintendo DS require a player check to make sure the code writes to the correct address for the respective players. For example the "Hold Y To Levitate" code for Metroid Prime: Hunters uses the player check to make sure only the player's character will levitate by writing the value to the correct address based upon the player number.

AR code
927FFFA8 F7FF0000
520D9CB8 00000000
020DA74C 00000400
D0000000 00000000
520D9CB8 00000001
020DB67C 00000400
D0000000 00000000
520D9CB8 00000002
020DC5AC 00000400
D0000000 00000000
520D9CB8 00000003
020DD4DC 00000400
D2000000 00000000

The second line of the code "520D9CB8 00000000" is an IF statement. It is a 32-bit check of the address 0x020d9CB8 to see if the value is 0x00000000. Metroid stores the player number - 1 at this address This means if the player is player 1, the address will hold 0x00000000 and if the player is playing as player 2 it will hold 0x00000001 and so forth. If the player is player 1 the AR writes the value 0x00000400 to the address 0x020DA74C (The levitation address). The address for player 2 to levitate would then be 0x020DB67C and so forth. Rather than write a check for each player and writing to the corresponding address, an ASM hack could be used to calculate an offset based upon the player number. The difference between each player's addresses in the case of this game is 0xF30 and is constant. To find the correct address to write to, multiply the player number by the offset. So if the player is currently player 4 then the equation would be:

(player number) * (Offset) =
3 * 0xF30 = 0x2D90

To accomplish this in ASM, the multiply command must be used. The multiply command takes 3 arguments:

opcode arguments comments
MUL{cond}{S} Rd,Rm,Rs ;multiply Rd = Rm*Rs

Rd will hold the value of (Rm*Rs). Now remember what the register r10 holds? r10 holds the AR offset and is listed in the 'Do not touch list'. But it's ok for us to touch in this case, because we know what we are doing now. Since this code should modify the AR offset, the result will be stored in r10. Here is what the ASM code should look like:

opcode arguments comments
ldr r0,=0x020D9CB8 ;r0 = 0x020D9CB8
ldr r0,[r0] ;r0 = value at 0x020D9CB8
ldr r1,=0x00000F30 ;r1 = 0xF30
mul r10,r0,r1 ;r10 (AR offset) = (player number) * (0xF30)
bx r14 ;required to jump back to code list

The first command 'ldr r0,=0x020D9CB8' will load the player address into r0. Then to load the value located at that address into r0 the command 'ldr r0,[r0]' is used. Next 0xF30 is loaded into r1 and finaly the new MUL command is used to calculate the offset 'mul r10,r0,r1'. r10 will hold r0 (player number) * r1 (0xF30). When the ASM is run through Kenobi's ASM to ARDS program we get the following output:

ASM to ARDS Output
023FE074 012FFF11
E0000000 00000018
E59F000C E5900000
E3A01EF3 E00A0190
E12FFF1E 020D9CB8
023FE074 E3520003

Now since r10 holds the value of the AR offset in this case, when the Action Replay returns from the ASM routine the AR offset will be set and all that is needed is one 32-bit constant RAM write code, '020DA74C 00000400'. The reason for this is because the RAM write codes use the offset, so the offset will be added to the address before writing the value. Also, it is wise to clear the offset at the end of the code so the other codes are not affected. Using the output from the ASM to ARDS program, the new code will look like this:

Hold Y To Levitate:
Code Comments
927FFFA8 F7FF0000 Activator
023FE074 012FFF11 Begin ASM
E0000000 00000018
E59F000C E5900000
E3A01EF3 E00A0190
E12FFF1E 020D9CB8
023FE074 E3520003 End ASM
020DA74C 00000400 Player 1 address + calculated offset
D2000000 00000000 End all and reset offset

This technique can be used for any game where an offset must be calculated before writing a value. Using ASM rather than multiple IF tests can save lines of unnecessary code. In this case, the assembly version of the code saves 4 lines. Other games, like Mario Kart (LAN multiplayer mode), have way more than 4 players online and can benefit greatly from using ASM in place of IF statements.

Metroid Prime Hunters Auto Kill

This example will explain how to create the auto kill code for Metroid Prime Hunters by KicKenchiKen57. The Auto Kill code requires some good knowledge of the game on the hacker's before it can be made. Before beginning, some memory addresses and values will need to be found.


Needed Addresses and Values
Code Comments
0x020D9CB8 Player number
0x020dab78 Player 1 buttons
0x00000c01 A+X+Y key value
0x00000F30 Player Offset
0x020da730 Player 1 X coordinate
0x020da734 Player 1 Y coordinate
0x020da738 Player 1 Z coordinate


The first address needed is the player number address. The need for this address has been addressed in the previous example. Next on the list is the player 1 button address. It is used because the auto kill code contains a hacker protection! Parasyte had mentioned that Metroid holds the buttons presses for each player on WiFi for all to see. Using this, it is possible to add in a hacker protection that works for anyone. What this protection will do is check each players buttons online. If any player is holding down a certain combination of buttons, it can be used to deactivate the auto kill code. In this case, the code is going to check for A+X+Y. If any player (with or without an Action Replay or any other cheat device) holds these buttons while a player is using the Auto Kill code, the code will be disabled until that user reboots. The last things to note are the player 1 X,Y,Z coordinate addresses. These addresses are used to warp a player to another player's location.


The Auto Kill routine works as follows. When a player has the Death Alt power up, any players that touch that player should die instantly, or take a hefty helping of damage. Assuming the user has the Death Alt code activated, all players could be killed by warping to their locations and moving on after they have died. Unfortunately, it is not enough to just check the health of each player and warp to the next when they are dead. There are other hackers and script kiddies out there who use Infinite Health cheats. This would stop the Auto Kill because the user would not move on to the next player if the hacker never died. Also, it is not desirable to warp to every player because the user controls one of those players. When the user warps to his/her own location, it basically looks like the user is not warping at all, and wastes valuable time. A timer can be used to increase the efficiency of this code. After a certain period of time elapses, the code should move on to the next player. This will prevent the code from sticking with someone who does not die. Since the code should not try to warp the hacker to a dead or inactive player, it should also check the player's health. If a player has no health, that player is either inactive (ex. player 4 in a 2 player game) or dead and should be skipped. This also allows the code to immediately switch to the next player as soon as the current player dies. The last check is the player number check. If the player number matches the player number of the code user it will be skipped. The code will also check the other players buttons to see if the defense mechanism is active.


Before writing any code, it would be wise (and necessary) to set up some variables.


Data Type Data Comments
player:
.word 0x020D9CB8 ;player now holds the value 0x020D9CB8


All variables should come at the end of the code after the 'bx r14'. It is also good practice to leave a space between the last line of code and the variable list for better readability. With this in mind, here is what the variable list will look like.


Data Type Data Comments
player:
.word 0x020D9CB8 ;address of the player number
offset:
.word 0x00000F30 ;offset between player data
data:
.word 0x020DA730 ;player 1 X coordinate
counter:
.word 0x00000000 ;counter set to 0
buttons:
.word 0x020DAB78 ;player 1 buttons held address
switch:
.word 0x00000000 ;switch to determine if code is disabled (0=enabled,1=disabled)
keys:
.word 0x00000C01 ;test for A+X+Y keys held


The variable list does not contain any other player data but player 1. It does not even contain the addresses for the Y or Z coordinates. That is because The ASM code is going to calculate these things on its own based upon the player number and offset to save space and to be more efficient. The next part of the code will check all players' buttons. Before the code is executed, the buttons of each player must be checked to determine if the defense mechanism is in place.


opcode arguments comments
mov r0,#0 ;clear r0 for the loop counter
ldr r1,offset ;r1 = offset
ldr r2,buttons ;r2 = player 1 button address
ldr r6,keys ;r6 = keys to test for
loop:   ;loop will check all players buttons
mla r3,r0,r1,r2 ;r3 = (player number * offset) + (button address)
ldr r3,[r3] ;r3 now holds the buttons that are held
and r3,r3,r6 ;r3 = r3 && r6
cmp r3,r6 ;if A+X+Y are held, r3 will == r6
streq r1,switch ;if so, stick the offset in the variable switch
cmp r0,#3 ;if we didnt loop 4 times (0-3)
add r0,#1 ;add 1 to loop counter
bne loop ;and loop again


The player 1 address for what buttons are being held is the "base address" in this code. The base address lets the assembly routine calculate the address needed for the other players' addresses. This is accomplished by multiplying the player number by the offset and adding the "base address" to it. Metroid Prime: Hunters keeps the player number's as follows:


MPH player number Actual player
0 1
1 2
2 3
3 4


The address holding the button presses for player two would then be 0x020DBAA8.


Finding the address
(player number) * (offset) + (base address)
(1) * (0xF30) + (0x020DAB78)
player 2 address = 0x020DBAA8


After checking for the A+X+Y button combination, the warp code should come next, followed by the list of variables. The finished routine is below:


Inst Operands Comments
mov r0,#0 ;clear r0 for the loop counter
ldr r1,offset ;r1 = offset
ldr r2,buttons ;r2 = player 1 button address
ldr r6,keys ;r6 = keys to test for
loop:   ;loop will check all players buttons
mla r3,r0,r1,r2 ;r3 = (player number * offset) + (button address)
ldr r3,[r3] ;r3 now holds the buttons that are held
and r3,r3,r6 ;r3 = r3 AND r6
cmp r3,r6 ;if A+X+Y are held, r3 will == r6
streq r1,switch ;if so, stick the offset in the variable switch
cmp r0,#3 ;if we didnt loop 4 times (0-3)
add r0,#1 ;add 1 to loop counter
bne loop ;and loop again
ldr r0,switch ;r0 holds the value of switch
cmp r0,#0 ;is the switch == 0?
bne quit ;if not, we want jump to the quit label
ldr r0,player ;r0 = player number address
ldr r0,[r0] ;r0 holds the player number
ldr r3,data ;r3 = player 1 X coordinate address
mla r2,r0,r1,r3 ;r2 = ([player number * offset)+(coordinate address)
ldr r6,counter ;r6 == counter variable
add r6,r6,#1 ;add 1 to the counter
mov r8,r6,lsr #0x6 ;r8 = counter>> 0x6
cmp r8,r0 ;does r8 == player number?
addeq r8,#0x01 ;if so, add 1 to skip the player
moveq r6,r8, lsl #0x06 ;r6 = r8 << 0x6 (and update r6 as well)
cmp r8,#0x4 ;did do all 4 players?
moveq r6,#0 ;if so reset r6
moveq r8,#0 ;and reset r8
ldr r12,data ;r12 = the player 1 x coordinate address
mla r3,r1,r8,r12 ;r3 = (player number * offset) + (player 1 x coordinate address)
ldr r12,[r3,#0xBE] ;r12 = the current players health (x coord address + 0xBE = health address)
cmp r12,#0x0 ;is player dead or not even in the game?
addeq r8,#0x01 ;if so, add 1 to r8 to skip that player
moveq r6,r8, lsl #0x06 ;r6 = r8 << 0x6 (and update r6 as well)
beq end ;and jump to the end label
ldr r12,[r3] ;player is not dead, so load x coordinate
str r12,[r2] ;and store it in the x coord address
ldr r12,[r3,#4] ;load y coordinate
str r12,[r2,#4] ;and store it in the y coord address
ldr r12,[r3,#8] ;load z coordinate
str r12,[r2,#8] ;and store it in the z coord address
end:
str r6,counter ;store r6 in the counter variable
quit:
bx r14 ;required
Variables
player:
.word 0x020D9CB8 ;address of the player number
offset:
.word 0x00000F30 ;offset between player data
data:
.word 0x020DA730 ;player 1 X coordinate
counter:
.word 0x00000000 ;counter set to 0
buttons:
.word 0x020DAB78 ;player 1 buttons held address
switch:
.word 0x00000000 ;switch to determine if code is disabled (0=enabled,1=disabled)
keys:
.word 0x00000C01 ;test for A+X+Y keys held


Now one part of the code should be very obvious.


opcode arguments comments
ldr r0,switch ;r0 holds the value of switch
cmp r0,#0 ;is the switch == 0?
bne quit ;if not, we want jump to the quit label


After checking the switch, if to does not equal '0' the entire section of code performing the auto kill should be skipped completely, so it branches to the label quit. After this first important check, the code then loads all of the necessary varaibles into the registers to begin looping through each player. In the loop, it uses r6 as a timer and r8 as the player number. By executing a mov r8,r6,lsr #0x6 the code does a logical right shift on r6 by 0x6 and stores it in r8. The higher the number used in the lsr, the faster r8 will change. In this case 0x6 was a good enough value to allow enough time when warping between players to kill them.

Converting Codes

There are two options here.

  • Use Dlong's app.
  • Convert by hand.

Before attempting this one should read up on Action Replay and Codebreaker code types. For example, Special Stage Ring Modifier hacked by DSman for Sonic Rush:

AR Code
22181F28 000000XX

This code happens to be a simple 8-bit write, or code type 2. The Codebreaker's 8-bit write code type is 0, so to get the Codebreaker version of this code all that is needed to do is to swap out the code type digit in the front of the code.

CB Code
02181F28 000000XX

Most codes can be ported this way. More complicated codes can be converted, but the hacker really needs to get familiar with the codes and code types of both systems to do this.

Here's a more complicated code: Moon Jump hacked by DSman for Yoshi's Island DS:

AR Code
94000130 FFFD0000
62105F88 00000000
B2105F88 00000000
20000055 00000099
D2000000 00000000

Let's break this down first.

AR Code
94000130 FFFD0000 A run-of-the-mill universal activator.
62105F88 00000000 Code type 6, or a 32-bit != code type, sort of part of the pointer. (Used for the conditional)
B2105F88 00000000 The next two lines start to get into pointers, which will be explained in detail.
20000055 00000099
D2000000 00000000 Code type D2, or the terminator.

Action Replay DS pointers are laid out so that the pointer address is temporarily loaded into the data register, and then a code is written using this offset as a baseline. The Codebreaker actually has a nice pointer code type, on the other hand.

CB Code
6XXXXXXX YYYYYYYY
ZZZZZZZZ BCTUVVVV
X The pointer's address. In this case it equals 02105F88.
Y The value to be written. Here is is 99.
Z The offset. The offset for this particular Moonjump address is 00000055.
B Bit-type Write, 0 for 8-bit, 1 for 16-Bit and 2 for 32-Bit. In this case B == 0.
C The Conditional used to replace the second line of the AR code. It should be equal to 1. (enabled)
T Conditional Type. Since line 2 of the AR is != to a 32-bit value of 0, T should equal 1 in this case.
U Bit count of the checked value. There is no 32-bit, so I guess 16 will have to suffice. (Or U = 1)
V What the conditional are checking against. (V = 0000)

The code, once converted, turns out to be:

CB Code
62105F88 00000099
00000055 01110000

It should be easy to convert most codes if proper documentation is kept handy. Code porting is a skill to be learned, and should not be treated as a set of steps to mechanically go through.


EnHacklopedia
Basics
Number and Data Encoding Formats - Generic Code Hacking
Individual Systems In Depth
Hacking Arcade - Hacking NES - Hacking SMS - Hacking SNES - Hacking Genesis - Hacking Saturn - Hacking PSX - Hacking N64 - Hacking DC - Hacking PS2 - Hacking GCN - Hacking Game Boy - Hacking Game Gear - Hacking Game Boy Advance - Hacking NDS -
Documents and References
Documents
Tools
Tools


Legal

Creative commons.png
All files (HTML, CSS, images) included in EnHacklopedia are licensed under the Creative Commons Attribution-ShareAlike 3.0 License. All authors contributing to EnHacklopedia should be made aware of the license before contributing. If the author does not agree to the licensing, his or her contributions will not be accepted into the project.