Pokemon Platinum Hacking: Part 1

02 January 2024 #Pokemon Hacking #radare2

Pokemon Platinum


Happy new year everyone!
On this end of year I have been playing some Pokemon Platinum, you know, for old times' sake. While playing the game I became more and more curious about how the game works, and how to mess with it. This will be (hopefully) a little series of blog posts going over what I learned in the process.

Emulator Setup

Of course, I'm not playing on my old Nintendo DS (no clue where it is tbh). I'll be using DeSmuME as my DS emulator, and it should work well whether you are on Linux, MacOS or (god forbid) Windows.

Next we need the actual game. We are looking for a .nds file. There are plenty of places on the internet where you can find it, and of course we have a physical copy of the game so Nintendo won't be mad at us (:

Now we can open the .nds file with our emulator of choice and start playing.

Save File

So what happens when you save the game using the option in the main menu?

main menu

Well, in the case of DeSmuME (on Linux), it will write the save file in ~/.config/desmume:

$ ls -Alh ~/.config/desmume
total 524K
-rw-r--r--. 1 yep yep  126 Jan 14  2023  config
-rw-r--r--. 1 yep yep  699 Jan  1 00:29  config.cfg
-rw-r--r--. 1 yep yep 513K Jan  3 10:54 'Pokemon - Version Platine (3784) (FR).dsv'

The save file will have the same name as the .nds file you opened. Whenever you open the game again, it will look in this directory for the name of the .nds file and load the .dsv file if it finds it.

The .dsv format is specific to DeSmuME, but it is basically a .sav file with a DeSmuME specific footer. You can treat this like a .sav file.

However, if for some reason you really want a .sav file, you can get it (while playing the game) by going the menu bar -> File -> Export backup memory.

In the same fashion you can import a .sav file directly by using the Import backup memory option in the same menu. But keep in mind that this will overwrite the current .dsv file (learned this the hard way).

File Structure

Now let's take a look at what is stored in the save file. Luckily for us, the hard work has already been done so we can get the information we need here.

I'm going to use radare2 as a hex editor to view the file. After opening the file in r2, we can switch to Visual Mode by pressing V:

[0x00000000 [Xadvc]0 0% 704 Pokemon - Version Platine (3784) (FR).dsv]> xc
- offset -   0 1  2 3  4 5  6 7  8 9  A B  C D  E F  0123456789ABCDEF
0x00000000  0000 0000 0000 0000 0009 bf12 3456 0617  ............4V..
0x00000010  0100 0000 1700 0000 0c00 0000 1700 0000  ................
0x00000020  0600 0000 1200 0000 2d00 0000 1300 0000  ........-.......
0x00000030  3522 0000 52e3 0d2d 0000 0000 0000 0000  5"..R..-........
0x00000040  0000 0000 0000 0000 0000 0000 0000 0000  ................
0x00000050  0000 0000 0000 0000 0000 0000 0000 0000  ................
0x00000060  0000 0000 424c 0000 5d01 4901 5401 ffff  ....BL..].I.T...
0x00000070  0000 0000 0000 0000 d769 9d54 baf3 0300  .........i.T....
0x00000080  0003 7f46 0c00 0000 ff00 1800 0428 0000  ...F.........(..
0x00000090  0000 0000 0000 0000 0600 0000 0600 0000  ................
0x000000a0  be92 a910 0000 d759 fd2f 97e6 99f3 655a  .......Y./....eZ
0x000000b0  f885 5d6a 5992 eb1c 8ea9 dd9c 305f 84b5  ..]jY.......0_..
0x000000c0  c62f 5a0a 0e3c c977 e17c 5c85 734d ba54  ./Z..<.w.|\.sM.T
0x000000d0  805e bb2c 7d8e 2302 bbec 95e1 8336 09ce  .^.,}.#......6..
0x000000e0  88df f81b 1355 fd05 322a 5c5a 80e4 ff99  .....U..2*\Z....
0x000000f0  610f ef85 70c3 15ba da3d 6f62 8860 f2a0  a...p....=ob.`..

In Visual Mode, we can press g to enter an offset and jump to it. According to the article, the money of the player is stored at offset 0x7c - 0x7f (4 bytes). Let's see:

- offset -  7C7D 7E7F 8081 8283 8485 8687 8889 8A8B  CDEF0123456789AB
0x0000007c  baf3 0300 0003 7f46 0c00 0000 ff00 1800  .......F........

One important detail to note is that values are stored in Little-endian, meaning that the lower byte (0xba in this case) is at the leftmost position. For example, the amount of money in this save file is 0x0003f3ba (259 002).

Wouldn't it be nice to modify the amount of money we have? Of course, before doing anything with your save file, I recommend backing it up in case things go wrong (:

To write stuff in radare2, we first need to re-open the file in write-mode with oo+, and press i (while in Visual Mode), then we can overwrite the 4 bytes with arbitrary values (0x42 in this case):

- offset -  7C7D 7E7F 8081 8283 8485 8687 8889 8A8B  CDEF0123456789AB
0x0000007c  4242 4242 0003 7f46 0c00 0000 ff00 1800  BBBB...F........

Now let's launch the game and make use of our 1 111 638 594 poke-dollars!

However, shortly after launching the game, we get a BSOD-like error message:

corrupted save file

The message is in French, but it means "Corrupted save file, previous file will be loaded"...


In the next article, we will try to figure out why and how the save file is corrupted, and see if we can successfully alter the save file!