Jump to content

X / Y Save File Research


Kaphotics

Recommended Posts

Damn, I wish I had a 3ds, that powersave tool to dump a save and I'd be sitting here on my windbg all day working on poke-edits for you weather it's messing with the powersave app or the actual save file

I used to play gen5 on dsmume and use their wifi and have an old brick DS + old fake flash cart

Link to comment
Share on other sites

  • Replies 213
  • Created
  • Last Reply

Top Posters In This Topic

There are a few barriers --

a) there is a checksum in the header that Datel adds to the save file. If the checksum fails to match the data, Powersaves will not recognize it. I haven't gotten around to figuring out how the checksum is calculated, but I've been able to get around it by using Cheat Engine to edit the loaded save file in RAM, and having Powersaves write the "backup" to a file with the correct checksum.

b) data in the save file is hashed with SHA-256, if the hash doesn't match the data the game will not load it. If the game can't load it, Datel's servers can't edit it. If we had a completely decrypted save file, we *might* be able to figure it out, but we don't. We only have partially decrypted data - but not the constants in the save file.

c) Save files are signed with an AES-256 MAC at the very start of the save file, using a key hidden in the 3DS (in a write-only register, cannot be read). Datel's servers uses modded 3DSes to sign save files. The good news here is that if you have a save file that isn't signed properly and ask Datel's servers to apply cheats, they will send you a save file with a fixed signature - but ONLY if the hashes in b) are correct. They need to be able to load the save files to apply the RAM edits for cheats.

d) Without having a fully decrypted save file, we don't have the encryption keystream on top of the hashes and the AES MAC.

Well if you can spoof that checksum with CE, and you can let Datel handle the MAC, that leaves just the hashes, right? Well wouldnt you just need to get the keystream from the full file?.. I'm guessing redNAND and such doesnt give you the old save structure? because then you could make use of the repeating key to full decrypt it.

Link to comment
Share on other sites

Well if you can spoof that checksum with CE, and you can let Datel handle the MAC, that leaves just the hashes, right? Well wouldnt you just need to get the keystream from the full file?.. I'm guessing redNAND and such doesnt give you the old save structure? because then you could make use of the repeating key to full decrypt it.

4.1-4.5 -> emulated NAND doesn't give you the repeating ctr fail method for X/Y.

Since the XORpad is also applied over the hashes, there's no way to get the original hash value without decrypting the entire savegame first.

Link to comment
Share on other sites

4.1-4.5 -> emulated NAND doesn't give you the repeating ctr fail method for X/Y.

Since the XORpad is also applied over the hashes, there's no way to get the original hash value without decrypting the entire savegame first.

windbg > cheat engine

windbg is harder to use though, but reading dump files yeilds better results if you dump the process at the right time (eg while decrypting)

edit: put better windbg link

http://ravibayyana.blogspot.com/2011/01/installing-windbg.html

ollydbg is also another amazing tool, cheat engine is considered an infant toy when you match them with these bad boys.

http://www.ollydbg.de/

I still suggest windbg though with dump files, to create a dump file go to task manager, right click process, and create dump

KrgYgxT.png

Don't just create the dump at a random time; dump it when the program is performing the process you want to examine.

Then use windbg to analyze the dump, I can help out if needed (note: i don't own a 3ds, pokemon game, or powersave) but i'm willing to do all I can

Link to comment
Share on other sites

Again, all they do is take your encrypted save and send it to their server. There is no decrypting done on your computer.

Pursuing anything with PowerSaves will get you nowhere.

Where you the one that deleted my thread v-v I was gonna use it for other places and it's NOT just useful for powersave fyi

If you can, PM me the text back if it was only a soft delete please :) I'll use it elsewhere

Link to comment
Share on other sites

  • 2 weeks later...

Hey...

I recently got an AR Powersaves Pro for my birthday, and by now I know how to dump PKX files from my save, as well as obtaining Egg Shiny Values using KeySAV.

But I've been wondering: how close might we be to being able to apply/insert edited PKX/EKX Pokemon into a save file? I would love to be able to have custom names for Eggs, if possible, considering that different-language Eggs can have different names like Œuf, and labeling Eggs with their SV's would be really cool.

Link to comment
Share on other sites

Assuming egg names work like they do in previous generations, you should be able to nickname it with hacking- there were plenty of "named" eggs on Pokecheck, and if I recall they retained their names on being sent to a game. That being said, I have no idea if Datel's device allows you to modify eggs like that, or even if it lets you change a Pokemon's nickname.

Link to comment
Share on other sites

Assuming egg names work like they do in previous generations, you should be able to nickname it with hacking- there were plenty of "named" eggs on Pokecheck, and if I recall they retained their names on being sent to a game. That being said, I have no idea if Datel's device allows you to modify eggs like that, or even if it lets you change a Pokemon's nickname.

As far as I know, there isn't yet a code provided by Datel to do that (and there might never be one), so that's why I was asking about progress on sending PKX's back to the game.

Link to comment
Share on other sites

Updated the Wiki with checksum notes and a full block map of the save. All that's left to figure out is the hashing regions (which is much harder).

There are some errors:

0004	06800	00000038	6A83A	Trainer Stat Flags (Style) 

has a wrong size, in my save it is 0x150

0021	1D600	00000644	6A922	????
0022	1D800	000005C8	6A92A	Tournament Data 

1D600 + 00000644 = 1DC44 -> 1D800 should be 1DD00

0030	25400	00000C48	6A99A	Pokemon Bank Gifts
0031	26000	00000078	6A9A2	???? 

25400 + 00000C48 = 26048 -> 25400 should be 25200

I checked this with my (non-public) Save Editor and these values are correct, all checksums match after making these changes.

Well about the hash regions, as long as we can calculate them there should be no problem, except AES-MAC...

About the IVFC hash table, i tried to calculate them with sha256, but no success, i can't get a working xorpad,

is there anything i'm missing, like 0x00 values where it should be 0xFF ?

//edit

found my mistake, all hashs are now working, except 0x3000-53FF, but i haven't decrypted that part yet, so no problem...

also note: if the data contains only 0xFF, then the hash is empty (0x00)

Edited by Falo
Link to comment
Share on other sites

It's actually interesting to see that progress is coming along so well.. for the xorpads.. I've been thinking.. I know that people who have a digitial copy get a new xorpad if they reset their save (or reset the game? Not really sure). What I wonder: as Datel seems to use modified 3DS, am I correct that they probably have figured how the xorpad works? Maybe there's only a limited amount of possible xorpad combinations.. I'd happily provide 2 savegames of X to help out identify the available xorpads. Or has anyone by now figured a system how the xorpad is being generated?

Link to comment
Share on other sites

It's actually interesting to see that progress is coming along so well.. for the xorpads.. I've been thinking.. I know that people who have a digitial copy get a new xorpad if they reset their save (or reset the game? Not really sure). What I wonder: as Datel seems to use modified 3DS, am I correct that they probably have figured how the xorpad works? Maybe there's only a limited amount of possible xorpad combinations.. I'd happily provide 2 savegames of X to help out identify the available xorpads. Or has anyone by now figured a system how the xorpad is being generated?

There's way too many XORpads due to how the keyY and everything else is made. How the XORpad is created is already known (it uses keys which are currently unobtainable, so they just make the 3DS do it with cfw) - Read more at 3dbrew.

Link to comment
Share on other sites

There are some errors:

0004	06800	00000038	6A83A	Trainer Stat Flags (Style) 

has a wrong size, in my save it is 0x150

0021	1D600	00000644	6A922	????
0022	1D800	000005C8	6A92A	Tournament Data 

1D600 + 00000644 = 1DC44 -> 1D800 should be 1DD00

0030	25400	00000C48	6A99A	Pokemon Bank Gifts
0031	26000	00000078	6A9A2	???? 

25400 + 00000C48 = 26048 -> 25400 should be 25200

I checked this with my (non-public) Save Editor and these values are correct,

what non public sav editor
Link to comment
Share on other sites

Most likely he (or a group) created a save editor for private testing; not meant for public use.

Nuff said.

So you're saying he might know how to re-insert edited PKX data back into the game? If so, then that would be great, because (some day) I'd love to be able to have hacked nicknames / egg names (eggs that have their Shiny Values written on them, or maybe an egg nicknamed "Good Egg" that hatches into Xerneas).

(Note: I don't intend on using hacked Pokemon to cheat in battles, scam people, etc.)

Link to comment
Share on other sites

Cant update the Wiki ("The action you have requested is limited to users in one of the groups: Bots, Administrators, Editors. "):

DISA hash:

Start: active DIFI partition offset - End: active DIFI partition offset+size (0x200 - 0x32B or 0x330 - 0x45B) - Offset: 0x16C

IVFC hash 0:

Start: 0x2000 - End: 0x201F - Offset: active DIFI partition offset + hash offset (= 0x30C or 0x43C)

IVFC hash 1:

Start: 0x2020 - End: 0x203F - Offset: 0x2000

IVFC hash 2:

Start: 0x2040 - End: 0x2FFF - Offset: 0x2020

To calculate them you must create a new byte array block with the size "1 << ivfc.levels[x].BlockSize" and fill it with 0x00, for hash 0 & 1 it is 512 (1 << 9), hash 2 is 4096 (1 << 12). To get these information, read the active DIFI partition and get these values from the IVFC part.

After making the byte array, memcpy the data into it and then calc sha256 over the whole array.

The only missing thing now is AES_MAC and the algo to generate the XorPad, can someone tell it to me?

http://www.3dbrew.org/wiki/Savegames is confusing to read...

Link to comment
Share on other sites

The AES MAC requires the keyscrambler and the AES Engine, which haven't been translated to code (because they rely on hardware not software). XORpad too.

What would it take to reverse-engineer the signing key from the hardware? I'm assuming whatever it is isn't very feasible but I'm still curious. Would the (failed) chip decapping fundraiser have been of any help in this?

Link to comment
Share on other sites

What would it take to reverse-engineer the signing key from the hardware? I'm assuming whatever it is isn't very feasible but I'm still curious. Would the (failed) chip decapping fundraiser have been of any help in this?

You'd need the entire bootrom to see how the keys are initialized, so yeah. The AES key registers are write only, so once they're put in by the bootrom there's no reading them out.

Link to comment
Share on other sites

You'd need the entire bootrom to see how the keys are initialized, so yeah. The AES key registers are write only, so once they're put in by the bootrom there's no reading them out.

how does that work? if they can't be read, how can they be used?

Link to comment
Share on other sites

I still need some static values.

Some work on the Powersaves CRC: (Powersaves 1.1.6)

00412CD3  /$  55            PUSH EBP
00412CD4  |.  8BEC          MOV EBP,ESP
00412CD6  |.  33C0          XOR EAX,EAX                             //uint crc32 = 0;
00412CD8  |.  33C9          XOR ECX,ECX                             //int i = 0;
00412CDA  |.  3945 0C       CMP DWORD PTR SS:[EBP+C],EAX            //
00412CDD  |.  7E 1F         JLE SHORT PowerSav.00412CFE             //
00412CDF  |>  8B55 08       /MOV EDX,DWORD PTR SS:[EBP+8]           //edx = &buffer;
00412CE2  |.  0FB61411      |MOVZX EDX,BYTE PTR DS:[ECX+EDX]        //edx = *(byte*)(buffer + i);
00412CE6  |.  33D0          |XOR EDX,EAX                            //edx ^= crc32;
00412CE8  |.  81E2 FF000000 |AND EDX,0FF                            //edx &= 0xFF;
00412CEE  |.  C1E8 08       |SHR EAX,8                              //crc32 >>= 8;
00412CF1  |.  330495 80C26D>|XOR EAX,DWORD PTR DS:[EDX*4+6DC280]    //crc32 ^= crctbl[edx];
00412CF8  |.  41            |INC ECX                                //i++;
00412CF9  |.  3B4D 0C       |CMP ECX,DWORD PTR SS:[EBP+C]           //
00412CFC  |.^ 7C E1         \JL SHORT PowerSav.00412CDF             //if(i < length) goto 00412CDF
00412CFE  |>  5D            POP EBP
00412CFF  \.  C3            RETN

Powersaves calculates 2 CRC's with this function:

First 0x18 byte from the powersave header (should match crc32 @ 0x14, but 0x14 is 0x00000000 in memory), then the save itself (should match crc32 @ 0x18).

Here the code translated to C# (don't know if it's the normal crc32 or not), tested and working:

        public static uint[] CRC32_TABLE = {
           0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, 
           0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 
           0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 
           0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 
           0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 
           0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 
           0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 
           0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 
           0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 
           0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 
           0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 
           0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, 
           0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 
           0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 
           0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, 
           0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, 
           0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 
           0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 
           0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, 
           0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 
           0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 
           0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 
           0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 
           0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 
           0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 
           0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 
           0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, 
           0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 
           0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 
           0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, 
           0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 
           0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
       };

       public static uint PowersaveCRC32(byte[] buffer)
       {
           uint crc32 = 0;
           for (int i = 0; i < buffer.Length; i++)
           {
               crc32 = (uint)(CRC32_TABLE[(buffer[i] ^ crc32) & 0xFF] ^ (crc32 >> 8));
           }
           return crc32;
       }

Edited by Bond697
Link to comment
Share on other sites

Guest
This topic is now closed to further replies.
×
×
  • Create New...