Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature request] Stub FS::Get[This]SaveDataSecureValue to always allow loading of saves #1987

Open
duckfromdiscord opened this issue Jan 8, 2024 · 10 comments

Comments

@duckfromdiscord
Copy link

Some 3DS games like "Rusty's Real Deal Baseball" won't load their saves after they've been restored by a save manager such as Checkpoint. I tried for weeks to figure out why, and apparently the IPC calls responsible for this issue are GetThisSaveDataSecureValue and GetSaveDataSecureValue. There's a flag there that, if set incorrectly, will prevent these games from loading their saves. I found this out because Citra had this issue: https://github.com/citra-emu/citra/pull/7191. Is it possible for us to stub these IPC calls in Luma3DS, or somehow using a patch?

If this is not possible, let me know, and I will continue researching into patching the individual games. But since there's at least two of these games that currently won't load a modified save because of this IPC, I think it may be better to fix them all at once.

@eku
Copy link

eku commented Jan 9, 2024

Why shouldn't Checkpoint set the flag?

@profi200
Copy link
Contributor

profi200 commented Jan 9, 2024

As far as i'm aware the way save managers handle secure values is to just delete them because in most games this triggers the game to just create a new secure value and move on. A way to get around this would be restoring secure values along with the savegame they match to.

@duckfromdiscord
Copy link
Author

Why shouldn't Checkpoint set the flag?

Is the flag returned by the system process or is it set as a part of the secure value itself? I don't quite understand how this flag is determined.

Anyway, myself and one other person in the Checkpoint Discord server asked for help last week but there has been no response yet. The last stable Checkpoint release for 3DS was released 5 years ago, in 2019. A newer release caused instability, causing development to stop.

A way to get around this would be restoring secure values along with the savegame they match to.

Up until now, all backup saves in existence won't have the secure values since the save managers that have been in use aren't saving them yet, only the save files themselves. We can start saving them and restore them with saves right now, but that won't fix old backups.

Fixing the problem at the source by patching the system process would allow all saves to pass the check. Perhaps this should be added, but optional.

@eku
Copy link

eku commented Jan 10, 2024

Anyway, myself and one other person in the Checkpoint Discord server asked for help last week but there has been no response yet. The last stable Checkpoint release for 3DS was released 5 years ago, in 2019. A newer release caused instability, causing development to stop.

Did you try JKSM?

Fixing the problem at the source by patching the system process

Let's leave it to the developers of Luma to decide whether they want to correct errors from savemanagers in their code.

@profi200
Copy link
Contributor

This is the responsibility of the save manager. I looked it up and the "exists" flag is literally that. The game checks if the secure value exists. If Luma would patch this the check would fail anyway because there is no valid secure value (the save manager deleted it).

@duckfromdiscord
Copy link
Author

duckfromdiscord commented Jan 11, 2024

Did you try JKSM?

I'm on the latest version (05.08.2020) and just tried restoring a save, but the game still rejects it. The latest commit was more recent, though; only 3 years ago, and I don't think development there has stopped entirely. I could open an issue there.

I looked it up and the "exists" flag is literally that.

What do you mean by "exists" flag? Is that the flag in question that only these three games are looking for?

This is the responsibility of the save manager.

So, assuming we can get JKSM and/or Checkpoint on board with backing up the secure value, how will we deal with old saves?

If Luma would patch this the check would fail anyway because there is no valid secure value (the save manager deleted it).

Can't we just do what Citra does and provide a 0 for the (now non-existent) secure value?

rb.Push(RESULT_SUCCESS);
rb.Push<bool>(false); // indicates that the secure value doesn't exist
rb.Push<bool>(true);  // seems to override checking the validity so should be true
rb.Push<u64>(0);      // the secure value

The game I tried started working in the emulator after the release with this commit came out, so assuming we patch the IPC to return those values, they should work on the console as well.

I know for a fact it works because I wasn't able to load saves in the emulator either until I updated.

EDIT: I accidentally posted the entire diff, instead of just the new code. This is fixed now.

@duckfromdiscord
Copy link
Author

With that code, all games should load saves unconditionally. The IPC will correctly indicate that there is no secure value (and return 0 for it accordingly), set a flag to bypass the check entirely, and also account for this other flag that only these three games check.

@PabloMK7
Copy link
Collaborator

I have researched the FS module further. The unknown value seems to be hardcoded to be set to true if the requester process is a gamecard, otherwise it is set to false.

@duckfromdiscord
Copy link
Author

duckfromdiscord commented Jan 15, 2024

Very interesting. My guess is Nintendo decided it would be too difficult for a user to edit save data on a gamecard, and as such they might as well bypass the check.

What doesn't make sense is that the games in question using this flag are eShop games, not cartridges. Unless I'm getting two different flags confused.

EDIT: Though I suppose there is probably other logic that happens for eShop games.

@PabloMK7
Copy link
Collaborator

You are probably getting the idea wrong. The secure value is stored in NAND, while the save data is on the SD or the game card itself. It doesn't make sense to have a secure value for game cards because you can put the game card on another console which may have a different secure value.

Also, the SDK (and therefore, the function that checks the secure value) is the same for digital and physical games.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants