Jump to content

X / Y Save File Research


Kaphotics

Recommended Posts

General Research Thread.

Save1 Decryption method (can then be viewed with PKHeX).

Wiki - Updating periodically with our knowledge.

--

Have been doing a bunch of structure research with SciresM and Codemonkey85 on IRC; since we're able to decrypt the majority of save files now we're getting some meaningful data.

6th Gen Wondercard Structure Wiki

Edited by Kaphotics
Link to comment
Share on other sites

  • Replies 213
  • Created
  • Last Reply

Top Posters In This Topic

Just dumped the item numbers for most of the Key items and all of the new TMs:

Town map - 1BA - 442

Holo Caster - 281 - 641

Adventure Rules - 2BF - 703

Roller Skates - 283 - 643

Exp Share - 0D8 - 216

Sprinklotad - 2B1 - 689

Dowsing Machine - 1D7 - 471

Intriguing Stone - 2B9 - 697

Mega Ring - 2B8 - 696

Power Plant Pass - 2B7 - 695

Elevator Key - 2BC - 700

Honor of Kalos - 2BE - 702

TMV Pass - 2BD - 701

Vs Recorder - 1D1 - 465

Pokeradar - 1AF - 431

Bicycle - 1C2 - 450

Super Rod - 1BF - 447

Shiny Charm - 278 - 632

Oval Charm - 277 - 631

Lens Case - 2C1 - 705

Looker Ticket - 2C8 - 712

Prof's Letter - 282 - 642

--

TM100 - 2B6 - 694

TM99 - 2B5 - 693

TM98 - 2B4 - 692

TM97 - 2B3 - 691

TM96 - 2B2 - 690

Edit: Got Lens Case and Looker Ticket

Edit 2: Got Prof's Letter

Edited by SciresM
Link to comment
Share on other sites

Nope. We can get the encryption keys used for a single cartridge, but we do not know how the keys are generated.

I'm probably woefully ignorant of the facts here, so forgive me, but I asked because KeySAV is seemingly managing to decrypt the save files. What I was wondering is if there was any information available on how this is done (short of decompiling it).

Link to comment
Share on other sites

KeySAV doesn't need the key - it instead operates on a simple concept which involves rearranging slot data and knowing how save files are encrypted.

The trick which was used to reveal more contents of the save file didn't need a key either; it's essentially KeySAV's exploit pushed a little further in terms of rearranging data.

Link to comment
Share on other sites

KeySAV doesn't need the key - it instead operates on a simple concept which involves rearranging slot data and knowing how save files are encrypted.

The trick which was used to reveal more contents of the save file didn't need a key either; it's essentially KeySAV's exploit pushed a little further in terms of rearranging data.

News to me. Thanks. The whole thing makes a lot more sense now.

Link to comment
Share on other sites

I found, after much searching, where "Lumiose Style" is stored in the save. It's a single integer value ranging from 0-255. Buying something increases style by 2. Asking alexa to show you around increases style by 5. More values to come when I catalog them.

Discounts are as follows on the megastone in the stone emporium (Thanks, Kaphotics, for the chart):

Stage---Style--Price

0--------0-----1,000,000

1--------10----700,000

2--------25----300,000

3--------50----150,000

4--------90----100,000

5--------140---70,000

6--------190---50,000

7--------255---10,000

Edit: I got around to logging how much style everything in lumiose is worth: https://docs.google.com/spreadsheet/ccc?key=0AgF4wNipOQuCdC1obHRfU3JnUG5JZ0ZCNmRnMW1Xd1E

Edited by SciresM
Link to comment
Share on other sites

Thanks to theSLAYER, I was able to find the Bank Celebi data, which is treated kinda like a wondercard.

toyEu.jpg

Stored inside the Pokemon Bank block. There's data afterwards which I can't figure out, so I'm not gonna post an entire dump of his saveblock.

02CB = 715

0269 = 617

022F = 559

0072 = 114

9C54 = 40020

9C71 = 40049

and some japanese unicode (サトシ = Satoshi/Ash)

Link to comment
Share on other sites

If they're used, it's just a byte signaling that the card cannot be received in the future. All of the card data remains.

Just flip the bit if you've received it.

That's what I wanted to hear.

Now, all we have to do is to find people with other wondercards to share (Garchomps and stuff)

Anyway, is the "share wondercard" function still programmed in?

I think I last heard it it.. gen IV?

Link to comment
Share on other sites

  • 3 weeks later...

Might as well make a few comments:

Save file "decryption" and the process:

Gamesaves use a static XORpad which does not change after saving. Starting a new game on digital forces a new XORpad to be used.

The easiest way to "decrypt" a vast majority of your savefile is by using Powersaves.

  • Back up your save file.
  • Delete the save ingame, and start a new game. Save once early as possible. The new game's backup save will be essentially zeroed out (sans slots that store EKX files), then the game will apply the XOR. The result is (essentially) the XORpad.
  • Back up the new game.
  • By XORing these two savefiles together, a lot of plaintext and data will be revealed.

By using the Wiki's offsets, you can easily find the data for Wondercards, items, etc. We've mapped the offsets for pretty much everything! Since there is no way to recover hashes or offset tables (due to the XOR only abusing 00^XP), there's no way to alter your save file.

If you have a Digital Save File, you can extract a WonderCard's contents as follows:

  • Have a desired wondercard in the highest slot possible (not 1).
  • Backup save file 1.
  • Delete wondercard. The data is replaced by zeros.
  • Backup save file 2.
  • XOR the two together; the wondercard should be revealed in plaintext shortly after the wondercard offset in the save file.

Can also do a Before & After Receiving.

About KeySAV & Mass Dumper, and the trick that makes them work:

Save files have a main and backup, just like previous generation games. As previously mentioned, they just have a static pad that is XOR'd over top of the data.

The way the trick works is by knowing/guessing the contents of an Empty Box Slot.

Usually it's a PKX full of zeroes [0000000....0000] that are stored encrypted ("encrypted zeroes"). However, there is a problem. The game sometimes stores a "blank" egg - which is basically encrypted zeroes with the name "Egg" and Origin Data (E0-E4). With some clever manipulation, the Nickname and Origin Data can be obtained by using ingame mons.

  • (Empty Row^XORpad) ^ (Full Row^XORpad) = (Empty Row ^ Full Row). Easy canceling of the XORpad. But we need the empty slot's data!
  • To find the Origin Data, we must submit observe an EKX with the Origin Data obtained ingame. By feeding 6 (Full Row), we can obtain it.
  • Since the Origin Data for Empty Zeroes is stored in the 4th Block (00000000 shift value = 0 -> ABCD), we need one of our 6 to have the D block not in the 4th slot.
  • (1/4)^6 = 1:4096, should succeed. Encryption Constant for zeroes & blank is 0, so....
  • Due to the blank and encryptedzeroes not having any data at (0xE0-0xE4)-(n*56), we can XOR (Empty ^ Full) with EncryptedZeroes to obtain a "Polluted" EKX.
  • Decrypt the polluted EKX and see what the Origin Data is. Bingo, now we have our origin (and language) Data.
  • Create a blank EKX with Nickname = Egg(language), and the Origin Data obtained. Encrypt it!
  • With a given Empty Box, just XOR the entire box with the encrypted zeroes and you have your keystream.
  • When dumping data out, check the checksum. If it doesn't match, just XOR it with the obtained blank egg EKX and it should be fixed.

About KeyBV and the trick that makes it work:

Battle Videos are stored on the SD card; for a given battle video "slot" (the internal filename is stored as an 8 digit hex index number) they use different XORpads.

The downfall of using different XORpads is that the same slot will always have the same XORpad. By deleting videos and making the game save to that slot, we can force it to use the same XORpad.

Battle Videos for Singles store the entire EKX data in Party Format. The trick for "decryption" is as follows:

  • Create a battle video by participating with only 1 Pokemon. Slots 2-6 are empty.
  • Delete battle video so that the next one saves to the same slot.
  • Create a battle video by participating with 2 Pokemon, the 2nd being the one from the first (this is important).
  • At the party EKX offset, we know slots 2-6 are empty from video 1.
  • ((xorpad^emptyslot) ^ encryptedzeros) = xorpad, as the empty slot is just encrypted zeros!
  • This doesn't give us our slot 1 xorpad, so we need to obtain the slot's data from slot 2 of the other battle video.
  • Since we obtained our slot2 xorpad, ((xorpad2 ^ video2slot2) ^ xorpad2) = video2slot2 = video1slot1.
  • Now we just ((xorpad1 ^ video1slot1) ^ video1slot1) = xorpad1.
  • All 6 xorpads have been obtained; concatenate and export.
  • This xorpad can be applied to any future battle video in that slot to reveal its contents.
  • Verify the checksum, if it doesn't match then just xor by encryptedzeros (slot 6 can be uninitialized sometimes == 00000...).
  • Obtain data :)

By abusing the Force Save = Off, you can check shiny values by saving->hatching->battling->resetting.

Link to comment
Share on other sites

There is an error with your KeySAV / Mass Dumper, after several useless trys to make it work i found out that your blank.ekx is the mistake.

A real blank.ekx is only zeros + encryption, there is no "Egg" data in them, after generating a blank.ekx with just zeros i was able to

dump all of my boxes without a single checksum error.

The egg data is a error by xoring a new save against a old save, this only applies for box data & battle box data.

Also here the german torchic wondercard, only the text and 1 byte is different

72zc46mw.jpg

// edit:

Region & Country id's can be dumped through the passerby data

struct PASSERBY{
   struct PASSERBY_ENTRY entry[102]<optimize=false>;
   ubyte padding[0x50];
};

struct PASSERBY_ENTRY{
   uint unk1;
   uint unk2;
   wchar_t Name[13];
   wchar_t Message[17];
   ubyte unk3[0x12];
   ubyte region;
   ubyte country;
   ubyte unk4[0x44];
   ushort favoritePKM;
   ubyte unk5[7];
   byte stars;
   ubyte data[0x22];
   Printf("%s: %d, %d\n", Name, country, region);
};

some dumped country id's:

country, name
0, -
1, Japan
8, Anguilla
16, Brazil
18, Canada
49, USA
65, Australia
67, Belgium
77, France
78, Germany
83, Italy
98, Portugal
105, Spain
107, Sweden
110, United Kingdom
136, South Korea

country, region, country name, region name (sorry german)
1, 0, Japan, -
1, 2, Japan, Tokio
1, 3, Japan, Hokkaido
1, 4, Japan, Aomori
1, 10, Japan, Ibaraki
1, 13, Japan, Saitama
1, 15, Japan, Kanagawa
1, 22, Japan, Gifu
1, 23, Japan, Shizuoka
1, 24, Japan, Aichi
1, 26, Japan, Shiga
1, 28, Japan, Osaka
1, 29, Japan, Hyogo
1, 31, Japan, Wakayama
1, 39, Japan, Ehime
8, 0, Anguilla, -
8, 1, Anguilla, Anguilla
16, 0, Brazil, -
16, 24, Brazil, São Paulo
18, 0, Canada, -
18, 2, Canada, Ontario
18, 3, Canada, Alberta
18, 10, Canada, Québec
36, 0, Mexiko, -
36, 16, Mexiko, México
36, 27, Mexiko, Sonora
49, 0, USA, -
49, 6, USA, Arizona
49, 7, USA, Kalifornien
49, 11, USA, Florida
49, 16, USA, Illinois
49, 17, USA, Indiana
49, 19, USA, Kentucky
49, 21, USA, Massachusetts
49, 22, USA, Maryland
49, 24, USA, Michigan
49, 29, USA, North Carolina
49, 33, USA, New Jersey
49, 35, USA, Nevada
49, 36, USA, New York
49, 37, USA, Ohio
49, 38, USA, Oklahoma
49, 42, USA, South Carolina
49, 43, USA, South Dakota
49, 45, USA, Texas
49, 47, USA, Virginia
49, 49, USA, Washington
49, 50, USA, Wisconsin
65, 0, Australia, -
65, 8, Australia, Victoria
67, 0, Belgium, -
67, 3, Belgium, Flandern
77, 0, France, -
77, 2, France, Île-de-France
77, 13, France, Haute-Normandie
77, 14, France, Languedoc-Roussillon
77, 16, France, Lothringen
77, 18, France, Nord-Pas-de-Calais
77, 21, France, Poitou-Charentes
77, 22, France, Provence-Alpes-Côte d'Azur
77, 23, France, Rhône-Alpes
78, 0, Germany, -
78, 3, Germany, Hessen
78, 10, Germany, Niedersachsen
78, 11, Germany, Nordrhein-Westfalen
78, 15, Germany, Sachsen-Anhalt
83, 0, Italy, -
83, 8, Italy, Venetien
83, 9, Italy, Friaul-Julisch Venetien
98, 0, Portugal, -
98, 8, Portugal, Azoren
107, 0, Sweden, -
107, 19, Sweden, Kronobergs Iän
110, 0, England, -
110, 2, England, England
110, 4, England, Schottland

1501 - Torchic (GER).zip

1501 - Torchic (GER).zip

Edited by Bond697
Link to comment
Share on other sites

I followed Kaphotics decryption process to try to edit a french savefile. There are some things I must talk about.

Firstly, the offset on the Wiki are not exactly the same on my save. I found a gap of 9C between mines and yours for all of the Item Pockets. Is it relative to the language ?

Then, trying to modify the quantity of a berry, I turned back the savefile to its original file. But Powersaves software doesn't display the save anymore. Do you know anything about a checksum or something else that could block any kind of mods ?

Link to comment
Share on other sites

The gap of 0x9C is because you have the powersaves header. Strip it out and you'll have the actual offsets.

The save file must be valid for Datel to load it; they are running modified 3DSes to load,decrypt,edit,encrypt,save. There is no way to alter the savefile and have Datel fix it.

Link to comment
Share on other sites

So there's no way to restore a save file through Datel software ? Too bad...

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.

Link to comment
Share on other sites

This is likely a profoundly stupid question - apologies in advance, especially if this isn't the place for it.

Does Powersaves alter save games in any way when simply backing up or restoring data?

Come to think of it, do we know how Powersaves backs up/restores X/Y saves? I recall this being a problem not too long ago...

Link to comment
Share on other sites

This is likely a profoundly stupid question - apologies in advance, especially if this isn't the place for it.

Does Powersaves alter save games in any way when simply backing up or restoring data?

Come to think of it, do we know how Powersaves backs up/restores X/Y saves? I recall this being a problem not too long ago...

For detailed info about the savegames look here: http://www.3dbrew.org/wiki/Savegames

To dump and restore saves it reads the NCSD/NCCH header from the rom, this is where it gets the needed informations (NAND save/EPROM save/etc...).

The Pokemon X/Y save is missing the "Wear leveling" sector structs, (after the powersave header) it starts directly with the AES-MAC hash, then the DISA/DIFI/... stuff.

It's most likely that the save id (which should protect against save modding) is tricked by not modifing these structs and just copy/pasting the save data, but i don't know exactly how it works.

@OmegaDonut

I have my doubts about datel using a real 3DS and ram hacks to modify saves, datel has enough resources to break any encryption/private keys (they did prove this with the PSP AR), their setup modifies values where a real 3DS just writes 0xFF, this proves they calculate more than a real 3DS would do and it makes more sense then a 3DS farm.

Link to comment
Share on other sites

datel has enough resources to break any encryption/private keys (they did prove this with the PSP AR)

I don't know much about the history of the PSP AR, but from what I can tell the AR was broken several times by firmware updates, which indicates that Datel found ways to fool the PSP into loading unsigned code that were patched, not that they were able to break encryption keys. And by the end of the PSP's lifetime, the security had more holes than Swiss cheese anyway.

their setup modifies values where a real 3DS just writes 0xFF, this proves they calculate more than a real 3DS would do and it makes more sense then a 3DS farm.

Actually, it doesn't. I have a 3DS that can run unsigned code, and I can have it use its internal AES engine to encrypt\decrypt any data I want. I can even instruct it to use the same keys used in savefile encryption\decryption. But I can't ask it to tell me what the keys are, as they are in write-only registers, and initialized by the firmware at boot.

The most realistic possibility is Datel does not know the keys, and have to use the same AES engine to encrypt\decrypt savefiles. The fact that Datel chooses to encrypt regions never edited by the game is sloppiness on their part, not an indication of superior knowledge.

Link to comment
Share on other sites

They don't alter the gamesave at all.

Copy from cart to RAM -> checksum the save -> apply header with checksum -> store / send.

All edits are done server side on their 3DS farm which loads and decrypts, then applies the edits.

Let me know if I understood:

When you backup a gamesave using Powersaves, is the information going to Datel? (only for a backup, not editing or restoring information).

- Hide

Link to comment
Share on other sites

PGL Promotion Gifts:

@ 0x26200:

u32 flag == 1 --> delivery type (item)

u16 item

u16 quantity

4AXWe.jpg

@ 0x26394:

u32 flag == 1 --> deliver (0 no delivery)

afterwards is some date related stuff (and maybe PGL IDs) so I'm not posting a pic of this section.

thanks to TheSonAlsoRises for contributing save files (Discount Coupon).

Link to comment
Share on other sites

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