From c4717fae2f69baa8ce393d0ae400df1d1afb8681 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 28 Jul 2018 09:37:12 -0700 Subject: [PATCH] Savedata: Reset data size when retrying hash. It's even possible we might've not loaded the key before, so let's play it safe and reset everything. The previous fix only worked in some games, when dataSize was larger than necessary. --- Core/Dialog/SavedataParam.cpp | 27 ++++++++++++++++++--------- Core/Dialog/SavedataParam.h | 2 +- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/Core/Dialog/SavedataParam.cpp b/Core/Dialog/SavedataParam.cpp index 3182f3b3df..dfb436dca7 100644 --- a/Core/Dialog/SavedataParam.cpp +++ b/Core/Dialog/SavedataParam.cpp @@ -642,20 +642,28 @@ int SavedataParam::DetermineCryptMode(const SceUtilitySavedataParam *param) cons return decryptMode; } -void SavedataParam::LoadCryptedSave(SceUtilitySavedataParam *param, u8 *data, u8 *saveData, int &saveSize, int prevCryptMode, const u8 *expectedHash, bool &saveDone) { +void SavedataParam::LoadCryptedSave(SceUtilitySavedataParam *param, u8 *data, const u8 *saveData, int &saveSize, int prevCryptMode, const u8 *expectedHash, bool &saveDone) { + int orig_size = saveSize; int align_len = align16(saveSize); u8 *data_base = new u8[align_len]; u8 *cryptKey = new u8[0x10]; - memset(cryptKey, 0, 0x10); int decryptMode = DetermineCryptMode(param); const int detectedMode = decryptMode; - bool hasKey = decryptMode > 1; - if (hasKey) { - memcpy(cryptKey, param->key, 0x10); - } - memset(data_base + saveSize, 0, align_len - saveSize); - memcpy(data_base, saveData, saveSize); + bool hasKey; + + auto resetData = [&](int mode) { + saveSize = orig_size; + align_len = align16(saveSize); + hasKey = mode > 1; + + if (hasKey) { + memcpy(cryptKey, param->key, 0x10); + } + memcpy(data_base, saveData, saveSize); + memset(data_base + saveSize, 0, align_len - saveSize); + }; + resetData(decryptMode); if (decryptMode != prevCryptMode) { if (prevCryptMode == 1 && param->key[0] == 0) { @@ -688,12 +696,13 @@ void SavedataParam::LoadCryptedSave(SceUtilitySavedataParam *param, u8 *data, u8 int err = DecryptSave(decryptMode, data_base, &saveSize, &align_len, hasKey ? cryptKey : nullptr, expectedHash); // Perhaps the file had the wrong mode.... if (err != 0 && detectedMode != decryptMode) { - hasKey = detectedMode > 1; + resetData(detectedMode); err = DecryptSave(detectedMode, data_base, &saveSize, &align_len, hasKey ? cryptKey : nullptr, expectedHash); } // TODO: Should return an error, but let's just try with a bad hash. if (err != 0 && expectedHash != nullptr) { WARN_LOG(SCEUTILITY, "Incorrect hash on save data, likely corrupt"); + resetData(decryptMode); err = DecryptSave(decryptMode, data_base, &saveSize, &align_len, hasKey ? cryptKey : nullptr, nullptr); } diff --git a/Core/Dialog/SavedataParam.h b/Core/Dialog/SavedataParam.h index 0a26f1aeb1..e509463712 100644 --- a/Core/Dialog/SavedataParam.h +++ b/Core/Dialog/SavedataParam.h @@ -361,7 +361,7 @@ private: void ClearFileInfo(SaveFileInfo &saveInfo, const std::string &saveName); int LoadSaveData(SceUtilitySavedataParam *param, const std::string &saveDirName, const std::string& dirPath, bool secureMode); - void LoadCryptedSave(SceUtilitySavedataParam *param, u8 *data, u8 *saveData, int &saveSize, int prevCryptMode, const u8 *expectedHash, bool &saveDone); + void LoadCryptedSave(SceUtilitySavedataParam *param, u8 *data, const u8 *saveData, int &saveSize, int prevCryptMode, const u8 *expectedHash, bool &saveDone); void LoadNotCryptedSave(SceUtilitySavedataParam *param, u8 *data, u8 *saveData, int &saveSize); void LoadSFO(SceUtilitySavedataParam *param, const std::string& dirPath); void LoadFile(const std::string& dirPath, const std::string& filename, PspUtilitySavedataFileData *fileData);