The World Ends With You - Final Remix - Gamesave reverse-engineering

Discussion in 'Switch - ROM Hacking, Saves, Translations & Tools' started by evilwombat, Oct 26, 2018.

  1. evilwombat
    OP

    evilwombat Member

    Newcomer
    1
    Sep 17, 2018
    United States
    Hello. To whomever is interested, I have began reverse-engineering the gamesave file for "The World Ends With You - Final Remix" on the Nintendo Switch.

    Using things like JKSV, it's possible to extract/inject the 'gamesave' file from the game, but editing it is another matter due to a hash check in place.

    I've managed to reverse-engineer the hash check, and I'm able to get the game to accept a re-hashed / injected save file with some trivial edits (like, lots of money).

    Is this the right forum to talk about stuff like this? Is anyone interested in more information?
     
  2. Arithmatics

    Arithmatics I'll be holding on to you. ;}

    Member
    6
    Jan 29, 2009
    Malaysia
    hi and welcome, yes it definitely is. You may very well be the first to break ground on this particular topic. although it's quite a small niche, don't stop and do report your findings!
     
    evilwombat likes this.
  3. evilwombat
    OP

    evilwombat Member

    Newcomer
    1
    Sep 17, 2018
    United States
    I'm cross-posting to/from Reddit (maybe we should consolidate)?

    Disclaimer: The following comes with absolutely no warranty, and is provided for informational purposes only. You take full responsibility for the consequences of any use of the following information.

    Okay, here's what I found. This applies to the Nintendo Switch version, but I have strong reason to believe the Android version will be very very similar, but all the offsets "might" be off by about 6 bytes(?). If someone sends me a game.dat from their phone, I could take a closer look as time permits, but for now, I'm sticking with the Nintendo Switch format.

    This assumes you can get your savegame to and from your Switch (using tools like JKSV and all that homebrew stuff) and that you accept the possible consequences of doing such things to your console. Anyway...

    The Switch save file looks something like this:

    [32 bytes of magic] (possibly less on Android)
    [32 bytes of checksum / hash] (the hash is computed from the start of the 'actual gamesave data' to the end of the file)
    [actual gamesave data]
    All numerical values are stored in Little-Endian format. Most values as 16-bit, that is, two bytes long (attack, defense, level, etc). Some are 32-bit (money, exp).

    The following are offsets for the basic player stats, starting from the *beginning of the file*:
    0x0040 - Current level (max = 100, or 0x64) (16-bit) (I only tested 99)
    0x0046 - Maximum level (max=100, or 0x64) (16-bit) (I only tested 99)
    0x0048 - Experience Points (32-bit)
    0x004C - Money (32-bit) (I only tested 99,999 because I haven't messed with wallets yet)
    0x0050 - Base level attack points (16-bit)
    0x0052 - Base level defense points (16-bit)
    0x0054 - "Luck" value (16-bit) ??
    0x0056 - "Brave" value (16-bit) (max = 999)

    That's all I've bothered to find so far. I'm probably going to get to the Noise Report stuff later, once I get to that part and it gets boring (I've only played through day 5).

    Now then, the checksum / hash... As I've mentioned before, the checksum is a hash of the actual savegame portion of the file (excluding the magic / hash portion). On the Switch, this starts from byte 64. The hash algorithm is SHA256, but the trick is that the resulting digest is *byte-reversed* (beginning to end) *and* all the bits are flipped.

    Here's a simple python script (attached) that will fix up the hash section of a modified gamesave file (yeah, there's probably a much shorter way to write this but I'm an embedded systems dude and I don't really "do" python often).

    Hopefully this helps someone. I'm currently fairly early on, but I'm running with level 99 and 256 attack/defense/luck/brave and it really helps cut down on the time spent in battles. I like to play these kinds of games for the story, and personally I find the fight sequences rather tedious. Don't judge me :)
     

    Attached Files:

    Last edited by evilwombat, Oct 27, 2018
    Arithmatics likes this.
  4. BlackwingAngelx

    BlackwingAngelx GBAtemp Advanced Fan

    Member
    6
    Dec 7, 2013
    United States
    Wow, very impressive. I was struggling to make save editing work. I found all of the values, but always corrupted. I'm not familiar with python however, would you be so kind as to explain exactly how you use the script you provided?

    Edit: I am trying to figure it out on my own, but it's not working so well. I put the script next to the gamesave and ran the CMD with "python.exe C:\Users\********\Downloads\twewy-nx-hash-fixup.py" But it just comes back and says there is no such file or folder as "gamesave", even though it's right there in the same folder as the script. Are there specific locations for these things? When I tried to run it from the checkpoint folder, it gave me a different error that said it couldn't open the folder because it didn't exist.

    This is the specific error when using the script.

    Traceback (most recent call last):
    File "C:\Users\********\Downloads\twewy-nx-hash-fixup.py", line 9, in <module>
    file = open(game_file, 'rb')
    FileNotFoundError: [Errno 2] No such file or directory: 'gamesave'
     
    Last edited by BlackwingAngelx, Nov 12, 2018
  5. abadidea

    abadidea Advanced Member

    Newcomer
    4
    Jul 18, 2018
    Canada
    its saying, it can't find the file "game_file"

    i assume the save file is called game_file, so put the script in the same folder as your save file, and rerun the python script.
     
  6. BlackwingAngelx

    BlackwingAngelx GBAtemp Advanced Fan

    Member
    6
    Dec 7, 2013
    United States
    No, the saves are called "gamesave", not "game_file". So I have to rename it, run the script and then rename it again?

    Edit: Nope, tested it. Same exact error after renaming. Word for word.
     
    Last edited by BlackwingAngelx, Nov 12, 2018
  7. abadidea

    abadidea Advanced Member

    Newcomer
    4
    Jul 18, 2018
    Canada
    i actually grabbed the python script..

    looks like.. it data is actually called "gamedata"

    3rd line - game_file = "gamesave"

    change that to

    game_file = "gamedata" or whatever the default name is (for me it was gamedata) just pulled it off my switch..and run in same folder..

    upload_2018-11-11_21-36-22.
     
  8. BlackwingAngelx

    BlackwingAngelx GBAtemp Advanced Fan

    Member
    6
    Dec 7, 2013
    United States
    Huh, weird. I pulled my save using checkpoint and it's called gamesave not gamedata. The script is set to gamesave. Changing the third line to gamedata gives the same error as well.

    Edit: My error is in line 9. It says no such file or folder as gamesave. But there is such thing..it's literally right there. I ran CMD as admin, the file is not read only, for whatever reason..it just can't find the file sitting right next to it. I've tried different drives and folders too. Always the same error.
     
    Last edited by BlackwingAngelx, Nov 12, 2018
  9. abadidea

    abadidea Advanced Member

    Newcomer
    4
    Jul 18, 2018
    Canada
    the 3rd line sets the "filename" to the variable, line 9 and 19 use that variable to read/write the file.

    you can set line 3 game_file = "C:\path\to\file\filename.ext" and try
     
  10. BlackwingAngelx

    BlackwingAngelx GBAtemp Advanced Fan

    Member
    6
    Dec 7, 2013
    United States
    That may have worked, testing it. It didn't give the error, but it also didn't say anything, just went to the next line. I'm assuming that's good?

    Edit: Nope. No good. The save still showed as corrupted. Was the CMD supposed to say something when I ran it? Because it didn't work.
     
    Last edited by BlackwingAngelx, Nov 12, 2018
  11. abadidea

    abadidea Advanced Member

    Newcomer
    4
    Jul 18, 2018
    Canada
    it shouldn't say anything, just run and go to command line prompt again.

    i just checked, looks like the script edits more than just the header, i didn't have a chance to read through what was required, wait till OP comes and says regarding the checksum.. but yes it edits more than the checksum based on my reference.
     
  12. BlackwingAngelx

    BlackwingAngelx GBAtemp Advanced Fan

    Member
    6
    Dec 7, 2013
    United States
    Yeah, I'm stumped. All I did was change my money to the max. No other weird edits. Using the script as is errors and can't find the save and using it with the direct path seems to work, but doesn't actually fix the checksum and still comes out corrupt. That about sums it up. Hopefully OP can help now. I'm going to stop messing with this for now.
     
  13. abadidea

    abadidea Advanced Member

    Newcomer
    4
    Jul 18, 2018
    Canada
  14. BlackwingAngelx

    BlackwingAngelx GBAtemp Advanced Fan

    Member
    6
    Dec 7, 2013
    United States
  15. evilwombat
    OP

    evilwombat Member

    Newcomer
    1
    Sep 17, 2018
    United States
    Sorry dude, I've been away for a while.
    "gamesave" is actually the filename of the file that comes off the Switch. So, what you have should be correct. I am using the NSP version of the game, and I'm using JKSV to pull the save off the Switch. And, JKSV shows a single file in the game's save directory, and that file is named simply "gamesave" (no extension or anything).

    From your error, it looks like the script isn't able to find 'gamesave'. You are putting the python script and the 'gamesave' file in the same directory, but it's the *current directory* of the CMD terminal that matters. So, after you open CMD, you must first "cd" into the directory where 'gamesave' and the Python script are located, and THEN run Python. Then, the script should work.

    Upon successful modification of the checksum, the script will exit without producing any output on the console (as is customary on Unix - silence means success). The result will be directly written back to the original "gamesave" file that was loaded.

    I'm running this on Linux, but the procedure should be the same:
    1. Grab "gamesave" off the Switch
    2. Copy this to some directory
    3. Copy the python script to that same directory
    4. Open a command prompt
    5. cd /path/to/where/everything/is
    6. python <script file>.py
    7. Copy "gamesave" back to sdcard and re-inject it back on the Switch.
    8. Skip all the annoying grinding battles :)

    As for the "gamedata" file - I am not sure what this is. I've never seen it before - for me, the game is called "gamesave". Maybe there are multiple versions of the game? Maybe you are on the cartridge version, and that uses a different save filename? If you send me your "gamedata" file, perhaps I could take a look. I would expect the checksum to be very similar (they even re-used a very similar mechanism on the Android version)...

    And I'll turn on post reply notifications, so I don't keep people waiting ... (weird, these were already on, but I'm not seeing reply notifications in email. Hmm)

    PS - the offsets in the top post are just about everything you need to beat the game. Attack/defence stats of 8000 will let you one-hit-kill just about anything. It's kind of comical, actually. Some of the advanced bonus stuff needs specific pins (still playing through it now) and although I don't have the exact address of the pin table, there seems to be some stuff near 0x380 that looks promising. Pin numbers are stored as 16bit little-endian integers, but the trick is that you have to add/subtract 1 between the pin number displayed within the game, and what is stored in the file. For instance, if the game calls for pin #006, that corresponds to 0x0005 within the gamesave file (or actually, 0x05 0x00 in little-endian).
     
    Last edited by evilwombat, Nov 13, 2018
  16. BlackwingAngelx

    BlackwingAngelx GBAtemp Advanced Fan

    Member
    6
    Dec 7, 2013
    United States
    First off, thank you SO much for the detailed writeup. My issue was indeed not running the CMD in the correct folder, stupid mistake on my part. It's been a long time since I've needed to do that and it slipped my mind. The script runs 100% of the time now with an error..HOWEVER, funny enough, I still can't get it to work. The script seems to actually wipe my progress somehow. Running it works and no longer gives me the corrupted save data error, but instead it forces me to start a new game, with continue being grayed out. I've tested it a few times. Loading my save works, editing my money and running the script makes me start a new game. I did it three times now. The only edit I made was changing my money (88 13 to 9F 86 01, my 5,000 yen to 99,999) I'll try starting a new game and doing a fresh edit.

    Edit: Yeah, that did it. I started a new game and as soon as I had access to my phone, my yen was 99,999. Strange. I hope it doesn't erase my progress when I go to edit it again when I have a bigger wallet, but I'll cross that bridge when it comes. Now all I need is to figure out how to change my Scarletite amount and I'm set haha. Thanks again!

    Edit2: I did another edit and it didn't reset my progress. I guess I was just too early in the game before. Also, you can go over your wallet limit. I did 9,999,999 and it stuck. I just need to farm up some Scarletite so I can find the value and I'm set. I hate material grinding. A max materials code would be nice, but that would take a while.
     
    Last edited by BlackwingAngelx, Nov 14, 2018
  17. evilwombat
    OP

    evilwombat Member

    Newcomer
    1
    Sep 17, 2018
    United States
    Awesome! Glad it worked out. I haven't had to do any scarletite farming. When do you ever need that stuff, anyway? Either I didn't need it to beat the game, or it just sort of accumulated on its own.

    One solution would be to set your maxlevel to 99, set your attack/defense to a few thousand, then drag the level slider in the game to 1 and fight a battle or two. Maybe also set your difficulty as high as it will go. With a high diffiulty and low level, items drop like candy (not like you'll actually need them given the other mods, except in very few places).

    I was able to edit the game after starting it, but I've played through one or two of the days. Likely you weren't far enough before trying to edit, like you said.

    Have fun, and enjoy the game!
     
  18. BlackwingAngelx

    BlackwingAngelx GBAtemp Advanced Fan

    Member
    6
    Dec 7, 2013
    United States
     
  19. evilwombat
    OP

    evilwombat Member

    Newcomer
    1
    Sep 17, 2018
    United States
    At, that makes sense. Trust me, with the Attack / Defense / Brave / Luck (?) mods, you won't be needing any stickers :). But, I can certainly understand the appeal of wanting to play though as many of the available game mechanics as possible.
     
  20. BlackwingAngelx

    BlackwingAngelx GBAtemp Advanced Fan

    Member
    6
    Dec 7, 2013
    United States
    So I managed to find the quantities of most of my pins using the Yen pins, since I have large numbers. I'm working on finding my Scarletite now, shouldn't be too difficult. One thing that I can't seem to find is HP though. I changed the level, attack, defense, brave and drop rate with zero issues, but I can't find the value for HP. The legitimate max HP is 9999 and at max level, you have around 5000. The only way to get more is by eating and digesting certain foods, it's a long process to hit 9999 naturally. Do you think you could try finding the HP address? It's more than just searching for your HP value, because it gives 0 results every time. There has to be something else.
     
Quick Reply
Draft saved Draft deleted
Loading...