Search the Community
Showing results for tags 'RAM'.
-
Version 20230705
1736 downloads
Pokémon main line and spin off series RAM dump Pokémon extractor, programmed in C#. This application extracts Pokémon from RAM dumps. The application supports gen 1-8 minus LGPE, BDSP, and PLA, as well as, the application supports Space World 97 demo, Colosseum, and XD. .NET 7 is needed to run the application. https://github.com/PokeJL/PKX-Extraction -
Pokémon Structure in RAM Due to a lack of documentation regarding how Pokémon are stored in RAM during battle of the generation 4 games I have taken it upon myself to document how they are structured and how to extract them. I've found that the Pokémon data is stored around the addresses 002C0BC2 to 002D5780 when a RAM dump is viewed in a hex editor. The length of the data is of 128 bytes (decimal value) or 80 bytes (hexadecimal value) per Pokémon. With that the following is the structure of Pokémon data in the RAM of generation 4 main line games if the relevant 128 bytes were extracted from the RAM; therefore, I'll be starting at address 0x00. Please note that for all values that use 2 or more bytes the values are stored in little-endian format. Offset Content 0x00-0x01 National Pokédex identification number. 0x02-0x0B 0x02-0x03 = Attack stat 0x04-0x05 = Defense stat 0x06-0x07 = Speed stat 0x08-0x09 = Special attack stat 0x0A-0x0B = Special defense stat 0x0C-0x13 The moves known by the Pokémon with every two bytes corresponding to the move index. 0x0C-0x0D = Move 1 0x0E-0x0F = Move 2 0x10-0x11 = Move 3 0x12-0x13 = Move 4 0x14-0x17 IVs, IsEgg Flag, IsNicknamed Flag. Same as in Block B of PKM Structure for Gen 4 found in the tech documents. 0x18-0x1F This set of bytes start at 06 and keeps track of the how the stats of the Pokémon have increased or decreased during the battle. Example 00 = a decrease in a stat by -6 stages and 0C = an increase in a stat by +6 stages. 0x20-0x21 These bytes are linked to the species of the Pokémon in some way. As such a byte combination of 70 0B will be set there if the opposing Pokémon is a Lugia. 0x22-0x23 Unused, in all tests. All bytes have been 00 and after many tests these bytes did not change. 0x24-0x25 These bytes are linked to the species of the Pokémon in some way. As such a byte combination of 0E 02 will be set there if the opposing Pokémon is a Lugia. 0x26 Pokémon form index. If the Pokémon does not have more than one form or the Pokémon is in its base form this value will be 00. Note form and evolution stage are different concepts. 0x27 Ability index 0x28 Unused, in all tests. All bytes have been 00 and after many tests these bytes did not change. 0x29 Appears to change if the Pokémon has a blanket ability activated. 00 = no blanket ability and 04 = the Pressure ability. It is unclear if this byte can have a value other than 00 or 04 depending on the ability. 0x2A-0x2B Unused, in all tests. All bytes have been 00 and after many tests these bytes did not change. 0x2C-0x2F Current Power Points of moves. 0x2C = Power Points Remaining for move 1 0x2D = Power Points Remaining for move 2 0x2E = Power Points Remaining for move 3 0x2F = Power Points Remaining for move 4 0x30-0x33 Number of PP UPs used for each move. 0x30 = Number of PP Ups used on move 1 0x31 = Number of PP Ups used on move 2 0x32 = Number of PP Ups used on move 3 0x33 = Number of PP Ups used on move 4 Values cannot exceed hexadecimal value 03. 0x34 Current level of Pokémon. Value cannot exceed hexadecimal value 64. 0x35 Happiness of Pokémon. 0x36-0x4B Pokémon nickname. If no nickname is set the Pokémon species name will be stored here with a terminating FF value. Note this is a character array; therefore, little-endian formatting does not apply here. 0x4C-0x4D The current Hit Point value of the Pokémon. 0x4E-0x4F Unused, in all tests. All bytes have been 00 and after many tests these bytes did not change. 0x50 The max Hit Point value of the Pokémon. 0x51-0x53 Unused, in all tests. All bytes have been 00 and after many tests these bytes did not change. 0x54-0x63 Original trainer (OT) name. If the Pokémon belongs to a non-playable character (NPC) all bytes will be 00 with a terminating FF. Note this is a character array; therefore, little-endian formatting does not apply here. 0x64-0x67 Current EXP. If the Pokémon belongs to a NPC all bytes will be 00. 0x68-0x6B Pokémon personality identification number (PID). 0x6C This byte gets set if the Pokémon is affected with a status condition that is not temporary such as burn or poison. 0x6D-0x73 Each byte correlates with a temporary status condition. For example the byte set for confusion is the counter for how many turns is remaining before the confusion status effect wears off. 0x74-0x75 Trainer identification number (ID). 0x76-0x77 Trainer secret identification number (SID). 0x78-0x79 The index of the item that the Pokémon is holding. 0x7A-0x7D Each byte correlates with a status condition that is not temporary. The byte set for sleep is the counter for how many turns is remaining before the wakes up. 0x7E This byte is the gender of the Pokémon. 00 = male, 01 = female, 02 = genderless. 0x7F This byte is the type of Poke Ball that the Pokémon is in. If it is in a special ball from Pokémon Heart Gold or Pokémon Soul Silver this byte will be 04 which is the same as the Poke Ball. --footer-- Pokémon Extraction In order to easily extract a Pokémon from RAM I recommend dumping the RAM as soon as the Pokémon that you want to extract is sent into battle. This is done so when viewing the RAM in a hex editor you can find a string of bytes that is both unique enough that it will not appear multiple times in the RAM and consistent with any Pokémon currently in the RAM. With that said the string of bytes that meets both of these conditions in most cases is the stat increase/decrease values with would be 06 06 06 06 06 06 06 06. Please note if an ability such as Intimidate or Download actives before dumping the RAM you will have to adjust the string of bytes accordingly. In a standard 1 vs 1 battle the first Pokémon that will appear in the RAM will be yours and the second one will be your opponents. From there follow how a Pokémon is stored in the save file in order to rearrange the data to create a valid PK4 file. Update: I have developed an application that can find and extract Pokémon from a generation 4 RAM dump file. Application can be downloaded from here Additional Reading
-
For the fifth generation of Pokémon games the RAM is actually very easy to read when compared to the fourth generation. This is largely due to the fact that when the RAM is opened in a simple text editor the headers in the RAM are in plain text. However, ripping Pokémon from RAM is both easier, but harder than generation four. In my pervious topic when I broke down the structure of Pokémon in generation four’s RAM I was able to locate all of the important information of the Pokémon, but with generation five important information that one would expect to find does not appear to be present at a first glance. Fortunately that is not where this topic ends; it turns out all Pokémon that are on the field as well as the entire party of all trainers are stored in the RAM in an encrypted format. It appears that the entire party block from the save is copied into the RAM and when a battle starts the other trainer’s Pokémon in loaded into the RAM using the exact same structure as the player’s party Pokémon. This allows for easy ripping of Pokémon at the cost of this topic appearing extremely underwhelming due to this outcome (sorry no table this time). How to Extract Pokémon from RAM Dumps During a Non Vs. Recorder Battle As stated earlier the RAM for generation 5 is very easy to read and this easiness to read makes it easy to rip Pokémon. In order to rip a Pokémon you will need to find it in the RAM and that is where the header N.pokeparty.c comes into play or its hex equivalent 4E 19 70 6F 6B 65 70 61 72 74 79 2E 63. In most cases there will be four instances of this header with the first one being the player’s party, the second one being the NPC’s party, the third one being the player’s party again, and the last one being the NPC’s party again (upon writing this I have realized that I did not test this with a multi-battle so the results my change for that). In some cases there may be an extra header before the first normal instance of it where different functionality such as Wi-Fi is mentioned. In order to start extracting a Pokémon you will need to start 20 bytes after the c in N.pokeparty.c, therefore the 21st byte onwards will be the start of the Pokémon data. Since it follows the same structure as party Pokémon in the save each Pokémon occupies 220 bytes so with some simple multiplication you can find the end of relevant data in the block. At this point I have covered general information and how to find the Pokémon, but now you probably want to know how to get a Pokémon from the RAM to the save even though the data is encrypted. 1. Locate the correct party block that has the Pokémon you want. 2. Copy the entire block or until the end of relevant data (if there is less than six Pokémon only copy up to the end of the last Pokémon). 3. Get a save file where the party Pokémon can be over written. 4. Copy the RAM block into the party block. 5. Open the save in PKHeX 6. Use PKHeX to update the checksum or remove the Pokémon from the same to your main save. For now this is the best method until an application is developed that can do this. How to Extract Pokémon from RAM Dumps During a Vs. Recorder Playback For these kind of RAM dumps the method above does not work as intended and the Pokémon will appear to have incorrect data if opened in PKHeX. The corruption occurs primarily with Pokémon obtained in a fifth generation game and is caused by the 0x5F byte which indicates which game the Pokémon was caught in being set to 00. In order to prevent this the Pokémon needs to be extracted from the RAM, decrypted without the use of PKHeX, opened in a hex editor, and manually change the 0x59 byte to either 14 for Pokémon White or 15 for Pokémon Black. This only needs to be done if the 0x59 byte is set to 00. Now just general remarks and interesting information from looking into this: In Pokémon Black2 and Pokémon White 2 there are NPCs that you can trade with and then have them challenge you to a battle with the traded Pokémon, but is it the same Pokémon? No, it is not the same Pokémon. In the end the Pokémon does maintain its PID, gender, nickname, ID, and SID, but its level is raised to the nearest 5th level, nature is changed, held item removed, met data wiped, IVs are changed to a predetermined set of IVs, EVs are set to 0, moves will reflect the four most recent moves that that species of Pokémon would know at the new level, and OT is wiped. As well, despite not usually being found in the RAM decrypted the Pokémon will have its name, ID, and SID decrypted in the RAM. Going back to generation four, Pokémon are also stored in the RAM encrypted, but it does not appear NPC Pokémon are always stored this way since 1 out of 5 attempts resulted in a good rip and not a glitch Pokémon. Therefore, keep using the information outlined in my earlier topic. For further reading please read my mapping of Pokémon in generation four RAM and generation five Pokémon structure in the technical documents. Special thanks to @BlackSharkfor providing some Pokémon White RAM dumps. Also here is an updated folder of some Pokémon that I dumped from popular NPC’s from Pokémon Black and Pokémon White (this time properly ripped and not using an AR code): Black White Special Trainers Updated.zip