From a23ca01f16874b2f600de6815c51700e5e83f530 Mon Sep 17 00:00:00 2001 From: Xele02 Date: Mon, 24 Dec 2012 22:28:10 +0100 Subject: [PATCH] Mode 8 Correction Modif for save encryption in Param.sfo and export save filename and encode key in a file --- Core/Dialog/PSPSaveDialog.cpp | 4 +-- Core/Dialog/SavedataParam.cpp | 46 +++++++++++++++++++++++++++++------ Core/ELF/ParamSFO.cpp | 44 ++++++++++++++++++--------------- Core/ELF/ParamSFO.h | 40 ++++++++++++++++++++++++++++-- 4 files changed, 104 insertions(+), 30 deletions(-) diff --git a/Core/Dialog/PSPSaveDialog.cpp b/Core/Dialog/PSPSaveDialog.cpp index 2660f562eb..92a0a5e398 100644 --- a/Core/Dialog/PSPSaveDialog.cpp +++ b/Core/Dialog/PSPSaveDialog.cpp @@ -47,8 +47,8 @@ int PSPSaveDialog::Init(int paramAddr) u32 retval = param.SetPspParam(&request); - DEBUG_LOG(HLE,"sceUtilitySavedataInitStart(%08x)", paramAddr); - DEBUG_LOG(HLE,"Mode: %i", param.GetPspParam()->mode); + INFO_LOG(HLE,"sceUtilitySavedataInitStart(%08x)", paramAddr); + INFO_LOG(HLE,"Mode: %i", param.GetPspParam()->mode); switch(param.GetPspParam()->mode) { diff --git a/Core/Dialog/SavedataParam.cpp b/Core/Dialog/SavedataParam.cpp index af3cb111be..ec8ee4cc7a 100644 --- a/Core/Dialog/SavedataParam.cpp +++ b/Core/Dialog/SavedataParam.cpp @@ -184,8 +184,20 @@ bool SavedataParam::Save(SceUtilitySavedataParam* param, int saveId) sfoFile.SetValue("PARENTAL_LEVEL",param->sfoParam.parentalLevel,4); sfoFile.SetValue("CATEGORY","MS",4); sfoFile.SetValue("SAVEDATA_DIRECTORY",GetSaveDir(param,saveId),64); - sfoFile.SetValue("SAVEDATA_FILE_LIST","",3168); // This need to be filed with the save filename and a hash - sfoFile.SetValue("SAVEDATA_PARAMS","",128); // This need to be filled with a hash of the save file encrypted. + + // For each file, 32 bytes for filename, 32 bytes for file hash (0 in PPSSPP) + u8* tmpData = new u8[3168]; + memset(tmpData, 0, 3168); + sprintf((char*)tmpData,"%s",GetFileName(param).c_str()); + sfoFile.SetValue("SAVEDATA_FILE_LIST", tmpData, 3168, 3168); + delete[] tmpData; + + // No crypted save, so fill with 0 + tmpData = new u8[128]; + memset(tmpData, 0, 128); + sfoFile.SetValue("SAVEDATA_PARAMS", tmpData, 128, 128); + delete[] tmpData; + u8 *sfoData; size_t sfoSize; sfoFile.WriteSFO(&sfoData,&sfoSize); @@ -222,6 +234,23 @@ bool SavedataParam::Save(SceUtilitySavedataParam* param, int saveId) std::string snd0path = dirPath+"/"+snd0Name; WritePSPFile(snd0path, data_, param->snd0FileData.bufSize); } + + // Save Encryption Data + { + int dataSize = 16+16; // key + save filename + data_ = new u8[dataSize]; + memset(data_,0,dataSize); + sprintf((char*)data_,GetFileName(param).c_str(),GetFileName(param).size()); + if(param->size > 1500) + memcpy(data_+16,param->key,16); + std::string encryptInfoPath = dirPath+"/"+"ENCRYPT_INFO.BIN"; + handle = pspFileSystem.OpenFile(encryptInfoPath,(FileAccess)(FILEACCESS_WRITE | FILEACCESS_CREATE)); + if (handle) + { + pspFileSystem.WriteFile(handle, data_, dataSize); + pspFileSystem.CloseFile(handle); + } + } } return true; } @@ -293,6 +322,8 @@ bool SavedataParam::GetSizes(SceUtilitySavedataParam *param) return false; } + bool ret = true; + if (Memory::IsValidAddress(param->msFree)) { Memory::Write_U32((u32)MemoryStick_SectorSize(),param->msFree); // cluster Size @@ -317,12 +348,13 @@ bool SavedataParam::GetSizes(SceUtilitySavedataParam *param) } else { - Memory::Write_U32(1,param->msData+36); - Memory::Write_U32(0x20,param->msData+40); + Memory::Write_U32(0,param->msData+36); + Memory::Write_U32(0,param->msData+40); Memory::Write_U8(0,param->msData+44); - Memory::Write_U32(0x20,param->msData+52); + Memory::Write_U32(0,param->msData+52); Memory::Write_U8(0,param->msData+56); - //return false; + ret = false; + // this should return SCE_UTILITY_SAVEDATA_ERROR_SIZES_NO_DATA } } if (Memory::IsValidAddress(param->utilityData)) @@ -345,7 +377,7 @@ bool SavedataParam::GetSizes(SceUtilitySavedataParam *param) Memory::Memset(param->utilityData+20,0,spaceTxt.size()+1); Memory::Memcpy(param->utilityData+20,spaceTxt.c_str(),spaceTxt.size()); // save size in text } - return true; + return ret; } diff --git a/Core/ELF/ParamSFO.cpp b/Core/ELF/ParamSFO.cpp index e2b423b29e..7965c1455b 100644 --- a/Core/ELF/ParamSFO.cpp +++ b/Core/ELF/ParamSFO.cpp @@ -46,23 +46,18 @@ void ParamSFOData::SetValue(std::string key, unsigned int value, int max_size) } void ParamSFOData::SetValue(std::string key, std::string value, int max_size) { - if(key == "ACCOUNT_ID" || - key == "PADDING" || - key == "PARAMS" || - key == "PARAMS2" || - key == "SAVEDATA_FILE_LIST" || - key == "SAVEDATA_PARAMS") - { - values[key].type = VT_UTF8_SPE; - } - else - { - values[key].type = VT_UTF8; - } + values[key].type = VT_UTF8; values[key].s_value = value; values[key].max_size = max_size; } +void ParamSFOData::SetValue(std::string key, const u8* value, unsigned int size, int max_size) +{ + values[key].type = VT_UTF8_SPE; + values[key].SetData(value,size); + values[key].max_size = max_size; +} + int ParamSFOData::GetValueInt(std::string key) { std::map::iterator it = values.find(key); @@ -73,10 +68,21 @@ int ParamSFOData::GetValueInt(std::string key) std::string ParamSFOData::GetValueString(std::string key) { std::map::iterator it = values.find(key); - if(it == values.end() || (it->second.type != VT_UTF8 && it->second.type != VT_UTF8_SPE)) + if(it == values.end() || (it->second.type != VT_UTF8)) return ""; return it->second.s_value; } +u8* ParamSFOData::GetValueData(std::string key, unsigned int *size) +{ + std::map::iterator it = values.find(key); + if(it == values.end() || (it->second.type != VT_UTF8_SPE)) + return 0; + if(size) + { + *size = it->second.u_size; + } + return it->second.u_value; +} // I'm so sorry Ced but this is highly endian unsafe :( bool ParamSFOData::ReadSFO(const u8 *paramsfo, size_t size) @@ -108,9 +114,9 @@ bool ParamSFOData::ReadSFO(const u8 *paramsfo, size_t size) case 0x0004: // Special format UTF-8 { - const char *utfdata = (const char *)(data_start + indexTables[i].data_table_offset); + const u8 *utfdata = (const u8 *)(data_start + indexTables[i].data_table_offset); DEBUG_LOG(LOADER, "%s %s", key, utfdata); - SetValue(key,std::string(utfdata,indexTables[i].param_len),indexTables[i].param_max_len); + SetValue(key, utfdata, indexTables[i].param_len, indexTables[i].param_max_len); } break; case 0x0204: @@ -187,10 +193,10 @@ bool ParamSFOData::WriteSFO(u8 **paramsfo, size_t *size) else if(it->second.type == VT_UTF8_SPE) { index_ptr->param_fmt = 0x0004; - index_ptr->param_len = it->second.s_value.size()+1; + index_ptr->param_len = it->second.u_size; - memcpy(data_ptr,it->second.s_value.c_str(),index_ptr->param_len); - data_ptr[index_ptr->param_len] = 0; + memset(data_ptr,0,index_ptr->param_max_len); + memcpy(data_ptr,it->second.u_value,index_ptr->param_len); } else if(it->second.type == VT_UTF8) { diff --git a/Core/ELF/ParamSFO.h b/Core/ELF/ParamSFO.h index 3d3441c521..fc4e07efc7 100644 --- a/Core/ELF/ParamSFO.h +++ b/Core/ELF/ParamSFO.h @@ -25,9 +25,11 @@ class ParamSFOData public: void SetValue(std::string key, unsigned int value, int max_size); void SetValue(std::string key, std::string value, int max_size); + void SetValue(std::string key, const u8* value, unsigned int size, int max_size); int GetValueInt(std::string key); std::string GetValueString(std::string key); + u8* GetValueData(std::string key, unsigned int *size); bool ReadSFO(const u8 *paramsfo, size_t size); bool WriteSFO(u8 **paramsfo, size_t *size); @@ -37,14 +39,48 @@ private: { VT_INT, VT_UTF8, - VT_UTF8_SPE + VT_UTF8_SPE // raw data in u8 }; - struct ValueData + class ValueData { + public: ValueType type; int max_size; std::string s_value; int i_value; + + u8* u_value; + unsigned int u_size; + + void SetData(const u8* data, int size) + { + if(u_value) + { + delete[] u_value; + u_value = 0; + } + if(size > 0) + { + u_value = new u8[size]; + memcpy(u_value,data,size); + } + u_size = size; + } + + ValueData() + { + u_value = 0; + u_size = 0; + type = VT_INT; + max_size = 0; + i_value = 0; + } + + ~ValueData() + { + if(u_value) + delete[] u_value; + } }; std::map values;