From a23ca01f16874b2f600de6815c51700e5e83f530 Mon Sep 17 00:00:00 2001 From: Xele02 Date: Mon, 24 Dec 2012 22:28:10 +0100 Subject: [PATCH 1/4] 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; From 020e4e7f13e37e14eed93a026392aa4c741fecbd Mon Sep 17 00:00:00 2001 From: Xele02 Date: Tue, 25 Dec 2012 13:30:10 +0100 Subject: [PATCH 2/4] Add code for sdk version info Modify Encrypt file data --- Core/Dialog/SavedataParam.cpp | 22 ++-- Core/HLE/sceKernelMemory.cpp | 190 +++++++++++++++++++++++++++++----- Core/HLE/sceKernelMemory.h | 1 + 3 files changed, 180 insertions(+), 33 deletions(-) diff --git a/Core/Dialog/SavedataParam.cpp b/Core/Dialog/SavedataParam.cpp index ec8ee4cc7a..1c479f89b1 100644 --- a/Core/Dialog/SavedataParam.cpp +++ b/Core/Dialog/SavedataParam.cpp @@ -68,6 +68,13 @@ namespace return result != 0; } + + struct EncryptFileInfo + { + int fileVersion; + u8 key[16]; + int sdkVersion; + }; } SavedataParam::SavedataParam() @@ -237,17 +244,20 @@ bool SavedataParam::Save(SceUtilitySavedataParam* param, int saveId) // 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()); + EncryptFileInfo encryptInfo; + int dataSize = sizeof(encryptInfo); // version + key + sdkVersion + memset(&encryptInfo,0,dataSize); + + encryptInfo.fileVersion = 1; + encryptInfo.sdkVersion = sceKernelGetCompiledSdkVersion(); if(param->size > 1500) - memcpy(data_+16,param->key,16); + memcpy(encryptInfo.key,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.WriteFile(handle, (u8*)&encryptInfo, dataSize); pspFileSystem.CloseFile(handle); } } diff --git a/Core/HLE/sceKernelMemory.cpp b/Core/HLE/sceKernelMemory.cpp index 5513850417..0edcc83a0e 100644 --- a/Core/HLE/sceKernelMemory.cpp +++ b/Core/HLE/sceKernelMemory.cpp @@ -32,6 +32,12 @@ BlockAllocator kernelMemory(256); // STATE END ////////////////////////////////////////////////////////////////////////// +#define SCE_KERNEL_HASCOMPILEDSDKVERSION 0x1000 +#define SCE_KERNEL_HASCOMPILERVERSION 0x2000 + +int flags_ = 0; +int sdkVersion_; +int compilerVersion_; struct NativeFPL { @@ -439,6 +445,154 @@ void sceKernelPrintf() RETURN(0); } +void sceKernelSetCompiledSdkVersion(int sdkVersion) +{ + int sdkMainVersion = sdkVersion & 0xFFFF0000; + bool valiSDK = false; + switch(sdkMainVersion) + { + case 0x1000000: + case 0x1050000: + case 0x2000000: + case 0x2050000: + case 0x2060000: + case 0x2070000: + case 0x2080000: + case 0x3000000: + case 0x3010000: + case 0x3030000: + case 0x3040000: + case 0x3050000: + case 0x3060000: + valiSDK = true; + break; + default: + valiSDK = false; + break; + } + + if(valiSDK) + { + sdkVersion_ = sdkVersion; + flags_ |= SCE_KERNEL_HASCOMPILEDSDKVERSION; + } + else + { + ERROR_LOG(HLE,"sceKernelSetCompiledSdkVersion unknown SDK : %x\n",sdkVersion); + } + return; +} + +void sceKernelSetCompiledSdkVersion370(int sdkVersion) +{ + int sdkMainVersion = sdkVersion & 0xFFFF0000; + if(sdkMainVersion == 0x3070000) + { + sdkVersion_ = sdkVersion; + flags_ |= SCE_KERNEL_HASCOMPILEDSDKVERSION; + } + else + { + ERROR_LOG(HLE,"sceKernelSetCompiledSdkVersion370 unknown SDK : %x\n",sdkVersion); + } + return; +} + +void sceKernelSetCompiledSdkVersion380_390(int sdkVersion) +{ + int sdkMainVersion = sdkVersion & 0xFFFF0000; + if(sdkMainVersion == 0x3080000 || sdkMainVersion == 0x3090000) + { + sdkVersion_ = sdkVersion; + flags_ |= SCE_KERNEL_HASCOMPILEDSDKVERSION; + } + else + { + ERROR_LOG(HLE,"sceKernelSetCompiledSdkVersion380_390 unknown SDK : %x\n",sdkVersion); + } + return; +} + +void sceKernelSetCompiledSdkVersion395(int sdkVersion) +{ + int sdkMainVersion = sdkVersion & 0xFFFFFF00; + if(sdkMainVersion == 0x4000000 + || sdkMainVersion == 0x4000100 + || sdkMainVersion == 0x4000500 + || sdkMainVersion == 0x3090500 + || sdkMainVersion == 0x3090600) + { + sdkVersion_ = sdkVersion; + flags_ |= SCE_KERNEL_HASCOMPILEDSDKVERSION; + } + else + { + ERROR_LOG(HLE,"sceKernelSetCompiledSdkVersion395 unknown SDK : %x\n",sdkVersion); + } + return; +} + +void sceKernelSetCompiledSdkVersion600_602(int sdkVersion) +{ + int sdkMainVersion = sdkVersion & 0xFFFF0000; + if(sdkMainVersion == 0x6010000 + || sdkMainVersion == 0x6000000 + || sdkMainVersion == 0x6020000) + { + sdkVersion_ = sdkVersion; + flags_ |= SCE_KERNEL_HASCOMPILEDSDKVERSION; + } + else + { + ERROR_LOG(HLE,"sceKernelSetCompiledSdkVersion395 unknown SDK : %x\n",sdkVersion); + } + return; +} + +void sceKernelSetCompiledSdkVersion603_605(int sdkVersion) +{ + int sdkMainVersion = sdkVersion & 0xFFFF0000; + if(sdkMainVersion == 0x6040000 + || sdkMainVersion == 0x6030000 + || sdkMainVersion == 0x6050000) + { + sdkVersion_ = sdkVersion; + flags_ |= SCE_KERNEL_HASCOMPILEDSDKVERSION; + } + else + { + ERROR_LOG(HLE,"sceKernelSetCompiledSdkVersion395 unknown SDK : %x\n",sdkVersion); + } + return; +} + +void sceKernelSetCompiledSdkVersion606(int sdkVersion) +{ + int sdkMainVersion = sdkVersion & 0xFFFF0000; + if(sdkMainVersion == 0x6060000) + { + sdkVersion_ = sdkVersion; + flags_ |= SCE_KERNEL_HASCOMPILEDSDKVERSION; + } + else + { + ERROR_LOG(HLE,"sceKernelSetCompiledSdkVersion395 unknown SDK : %x\n",sdkVersion); + } + return; +} + +int sceKernelGetCompiledSdkVersion() +{ + if(!(flags_ & SCE_KERNEL_HASCOMPILEDSDKVERSION)) + return 0; + return sdkVersion_; +} + +void sceKernelSetCompilerVersion(int version) +{ + compilerVersion_ = version; + flags_ |= SCE_KERNEL_HASCOMPILERVERSION; +} // VPL = variable length memory pool @@ -657,23 +811,6 @@ u32 GetMemoryBlockPtr(u32 uid, u32 addr) { return 0; } -u32 sceKernelSetCompiledSdkVersion(u32 param) { - // pretty sure this only takes one arg - ERROR_LOG(HLE,"UNIMPL sceKernelSetCompiledSdkVersion(%08x)", param); - return 0; -} - -u32 sceKernelSetCompiledSdkVersion395(u32 param) { - // pretty sure this only takes one arg - ERROR_LOG(HLE,"UNIMPL sceKernelSetCompiledSdkVersion395(%08x)", param); - return 0; -} - -u32 sceKernelSetCompilerVersion(u32 a, u32 b, u32 c, u32 d) { - ERROR_LOG(HLE,"UNIMPL sceKernelSetCompilerVersion(%08x, %08x, %08x, %08x)", a, b, c, d); - return 0; -} - const HLEFunction SysMemUserForUser[] = { {0xA291F107,sceKernelMaxFreeMemSize, "sceKernelMaxFreeMemSize"}, {0xF919F628,sceKernelTotalFreeMemSize,"sceKernelTotalFreeMemSize"}, @@ -682,16 +819,15 @@ const HLEFunction SysMemUserForUser[] = { {0xB6D61D02,sceKernelFreePartitionMemory,"sceKernelFreePartitionMemory"}, //(void *ptr) ? {0x9D9A5BA1,sceKernelGetBlockHeadAddr,"sceKernelGetBlockHeadAddr"}, //(void *ptr) ? {0x13a5abef,sceKernelPrintf,"sceKernelPrintf 0x13a5abef"}, - {0xf77d77cb,WrapU_UUUU,"sceKernelSetCompilerVersion"}, - {0x7591c7db,WrapU_U,"sceKernelSetCompiledSdkVersion"}, - {0x342061E5,0,"sceKernelSetCompiledSdkVersion370"}, - {0x315AD3A0,0,"sceKernelSetCompiledSdkVersion380_390"}, - {0xEBD5C3E6,WrapU_U,"sceKernelSetCompiledSdkVersion395"}, - {0x91DE343C,0,"sceKernelSetCompiledSdkVersion_500_505"}, - {0x35669d4c,0,"sceKernelSetCompiledSdkVersion600_602"}, //?? - {0x1b4217bc,0,"sceKernelSetCompiledSdkVersion603_605"}, - {0x358ca1bb,0,"sceKernelSetCompiledSdkVersion606"}, - + {0x7591c7db,&WrapV_I,"sceKernelSetCompiledSdkVersion"}, + {0x342061E5,&WrapV_I,"sceKernelSetCompiledSdkVersion370"}, + {0x315AD3A0,&WrapV_I,"sceKernelSetCompiledSdkVersion380_390"}, + {0xEBD5C3E6,&WrapV_I,"sceKernelSetCompiledSdkVersion395"}, + {0xf77d77cb,&WrapV_I,"sceKernelSetCompilerVersion"}, + {0x35669d4c,&WrapV_I,"sceKernelSetCompiledSdkVersion600_602"}, //?? + {0x1b4217bc,&WrapV_I,"sceKernelSetCompiledSdkVersion603_605"}, + {0x358ca1bb,&WrapV_I,"sceKernelSetCompiledSdkVersion606"}, + {0xfc114573,&WrapI_V,"sceKernelGetCompiledSdkVersion"}, // Obscure raw block API {0xDB83A952,WrapU_UU,"SysMemUserForUser_DB83A952"}, // GetMemoryBlockAddr {0x50F61D8A,WrapU_U,"SysMemUserForUser_50F61D8A"}, // FreeMemoryBlock diff --git a/Core/HLE/sceKernelMemory.h b/Core/HLE/sceKernelMemory.h index 247f683d7f..eaf2e23f4c 100644 --- a/Core/HLE/sceKernelMemory.h +++ b/Core/HLE/sceKernelMemory.h @@ -49,5 +49,6 @@ void sceKernelFreeFpl(); void sceKernelCancelFpl(); void sceKernelReferFplStatus(); +int sceKernelGetCompiledSdkVersion(); void Register_SysMemUserForUser(); From f965fb76238654bd9d7bff2d6287b955e6560716 Mon Sep 17 00:00:00 2001 From: Xele02 Date: Tue, 25 Dec 2012 18:20:37 +0100 Subject: [PATCH 3/4] * Add PSP Homebrew for encode/decode save between PSP and PPSSPP. --- Tools/SaveTool/Makefile | 44 ++ Tools/SaveTool/README | 77 ++++ Tools/SaveTool/decrypt.c | 164 +++++++ Tools/SaveTool/decrypt.h | 31 ++ Tools/SaveTool/encrypt.c | 233 ++++++++++ Tools/SaveTool/encrypt.h | 38 ++ Tools/SaveTool/hash.c | 129 ++++++ Tools/SaveTool/hash.h | 34 ++ Tools/SaveTool/kernelcall.prx | Bin 0 -> 2642 bytes Tools/SaveTool/kernelcall/Makefile | 24 + Tools/SaveTool/kernelcall/kernelcall.c | 84 ++++ Tools/SaveTool/kernelcall/kernelcall.h | 9 + Tools/SaveTool/main.c | 579 +++++++++++++++++++++++++ Tools/SaveTool/psf.c | 114 +++++ Tools/SaveTool/psf.h | 29 ++ 15 files changed, 1589 insertions(+) create mode 100644 Tools/SaveTool/Makefile create mode 100644 Tools/SaveTool/README create mode 100644 Tools/SaveTool/decrypt.c create mode 100644 Tools/SaveTool/decrypt.h create mode 100644 Tools/SaveTool/encrypt.c create mode 100644 Tools/SaveTool/encrypt.h create mode 100644 Tools/SaveTool/hash.c create mode 100644 Tools/SaveTool/hash.h create mode 100644 Tools/SaveTool/kernelcall.prx create mode 100644 Tools/SaveTool/kernelcall/Makefile create mode 100644 Tools/SaveTool/kernelcall/kernelcall.c create mode 100644 Tools/SaveTool/kernelcall/kernelcall.h create mode 100644 Tools/SaveTool/main.c create mode 100644 Tools/SaveTool/psf.c create mode 100644 Tools/SaveTool/psf.h diff --git a/Tools/SaveTool/Makefile b/Tools/SaveTool/Makefile new file mode 100644 index 0000000000..fc7a38f73c --- /dev/null +++ b/Tools/SaveTool/Makefile @@ -0,0 +1,44 @@ +SUBDIRS = kernelcall +release: + @for i in $(SUBDIRS); do echo "make all in $$i..."; (cd $$i; $(MAKE) release; cp $$i.prx ..); done + make all + +allclean: + make clean + @for i in $(SUBDIRS); do echo "Clearing in $$i..."; (cd $$i; $(MAKE) clean; rm -rf $$i.prx); done + +TARGET = ppssppsavetool +OBJS = main.o decrypt.o encrypt.o hash.o psf.o $(KERNELCALL_OBJS) + +BUILD_PRX=1 + + +EXTRA_TARGETS = EBOOT.PBP +PSP_EBOOT_TITLE = PPSSPP Save Tool + +PSP_FW_VERSION=350 + +INCDIR = +CFLAGS = -O0 -G0 -Wall -g +CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti +ASFLAGS = $(CFLAGS) + +KERNELCALL_OBJS = kernelcall_0000.o \ + kernelcall_0001.o \ + kernelcall_0002.o \ + kernelcall_0003.o \ + kernelcall_0004.o \ + kernelcall_0005.o \ + kernelcall_0006.o \ + kernelcall_0007.o + +$(KERNELCALL_OBJS): kernelcall/kernelcall.S + psp-gcc $(CFLAGS) -DF_$* $< -c -o $@ + +LIBDIR = +LDFLAGS = + +LIBS = -lpsputility -lpspgum -lpspgu -lm + +PSPSDK=$(shell psp-config --pspsdk-path) +include $(PSPSDK)/lib/build.mak diff --git a/Tools/SaveTool/README b/Tools/SaveTool/README new file mode 100644 index 0000000000..0581e316b8 --- /dev/null +++ b/Tools/SaveTool/README @@ -0,0 +1,77 @@ + +PSP Tool for encoding save data from PPSSPP to read on PSP and decoding +PSP save to read on PPSSPP. + +Alpha version. Was only tested on Project Dive Extend. + + +Build +===== + +Require PSP Toolchain with PSP SDK + + +make release +This will build ppssppsavetool.prx and kernelcall.prx. + +clean : make allclean + + +How to use +========== + +Require PSP Toolchain with PRX Link and usb link, pspsh to work. Seems +there is limitation for directories listing when running directly the +tool from the PSP. + +A) PREPARING DATA +================= + +1) Play the game on PPSSPP until a game save is done. This will create +the file "ENCRYPT_INFO.BIN" in the save directory. It contain the +encoding key and sdk version of the game. This file is the same for all +save of the game, so you can use it on different save folder without +the need to make them all on PPSSPP. + +2) Run usbhostfs_pc. Then mount .ppsspp/PSP/SAVEDATA directory : +mount 1 +If you enter "drives", you should see host1: mapped to the directory. + +3) Run PRX Link on the psp, and pspsh on the PC. + +B) ENCODING A SAVE FROM PPSSPP TO PSP +===================================== + +1) From pspsh, run ppssppsavetool.prx. + +2) In the menu, select "Encrypt", "host1:/". This will list the +directories in ppsspp save directory which can be encoded. +For a directory to appear, it must contain the ENCRYPT_INFO.BIN file, +and the files of a ppsspp save. + +3) After selecting the directory to encode, it will be copied into +the PSP/SAVEGAME directory and encoded. Now you can play the save on +the PSP. + +C) DECODING A SAVE FROM PSP TO PPSSPP +===================================== + +1) You should have a directory in the PPSSPP save directory with the +same name that the PSP save you want to convert. And in it, the +"ENCRYPT_INFO.BIN" file. + +Ex : You want to decrypt the save in ms0:/PSP/SAVEDATA/XXXXYYY/ +You create .ppsspp/PSP/SAVEDATA/XXXXYYY/ if not existing, and put the +"ENCRYPT_INFO.BIN" generated before in it. + +2) From pspsh, run ppssppsavetool.prx. + +3) In the menu, select "decrypt", "host1:/". You should see your +directory in the list. + +4) After selecting it, the game decode the save and save it into the +PPSSPP save directory. You can now launch your game in PPSSPP and load +the save. + + + diff --git a/Tools/SaveTool/decrypt.c b/Tools/SaveTool/decrypt.c new file mode 100644 index 0000000000..146572199d --- /dev/null +++ b/Tools/SaveTool/decrypt.c @@ -0,0 +1,164 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * decrypt.c - Decryption routines using sceChnnlsv + * + * Copyright (c) 2005 Jim Paris + * Coypright (c) 2005 psp123 + * + * $Id: decrypt.c 1562 2005-12-10 20:52:45Z jim $ + */ + +#include "decrypt.h" +#include +#include +#include +#include +#include +#include "kernelcall/kernelcall.h" + +unsigned int align16(unsigned int v) +{ + return ((v + 0xF) >> 4) << 4; +} + +/* Read, decrypt, and write a savedata file. See main.c for example usage. */ +int decrypt_file(const char *decrypted_filename, + const char *encrypted_filename, + const unsigned char *gamekey, + const int mainSdkVersion) +{ + FILE *in, *out; + int len, aligned_len; + unsigned char *data, *cryptkey; + int retval; + + /* Open file and get size */ + + if ((in = fopen(encrypted_filename, "r")) == NULL) { + retval = -1; + goto out; + } + + fseek(in, 0, SEEK_END); + len = ftell(in); + fseek(in, 0, SEEK_SET); + + if (len <= 0) { + retval = -2; + goto out1; + } + + /* Allocate buffers */ + + aligned_len = align16(len); + + if ((data = (unsigned char *) memalign(0x10, aligned_len)) == NULL) { + retval = -3; + goto out1; + } + + if ((cryptkey = (unsigned char *) memalign(0x10, 0x10)) == NULL) { + retval = -4; + goto out2; + } + + /* Fill buffers */ + + if (gamekey != NULL) + memcpy(cryptkey, gamekey, 0x10); + + memset(data + len, 0, aligned_len - len); + if (fread(data, 1, len, in) != len) { + retval = -5; + goto out3; + } + + /* Do the decryption */ + + if ((retval = decrypt_data( gamekey ? (mainSdkVersion >= 4 ? 5 : 3) : 1, // 5 for sdk >= 4, else 3 + data, &len, &aligned_len, + gamekey ? cryptkey : NULL)) < 0) { + retval -= 100; + goto out3; + } + + /* Write the data out. decrypt_data has set len correctly. */ + + if ((out = fopen(decrypted_filename, "w")) == NULL) { + retval = -6; + goto out3; + } + + if (fwrite(data, 1, len, out) != len) { + retval = -7; + goto out4; + } + + /* All done. Return file length. */ + retval = len; + out4: + fclose(out); + out3: + free(cryptkey); + out2: + free(data); + out1: + fclose(in); + out: + return retval; +} + +/* Do the actual hardware decryption. + mode is 3 for saves with a cryptkey, or 1 otherwise + data, dataLen, and cryptkey must be multiples of 0x10. + cryptkey is NULL if mode == 1. +*/ +int decrypt_data(unsigned int mode, + unsigned char *data, + int *dataLen, + int *alignedLen, + unsigned char *cryptkey) +{ + pspChnnlsvContext1 ctx1; + pspChnnlsvContext2 ctx2; + + /* Need a 16-byte IV plus some data */ + if (*alignedLen <= 0x10) + return -1; + *dataLen -= 0x10; + *alignedLen -= 0x10; + + /* Set up buffers */ + memset(&ctx1, 0, sizeof(pspChnnlsvContext1)); + memset(&ctx2, 0, sizeof(pspChnnlsvContext2)); + + /* Perform the magic */ + if (sceChnnlsv_E7833020_(&ctx1, mode) < 0) + return -2; + if (sceChnnlsv_ABFDFC8B_(&ctx2, mode, 2, data, cryptkey) < 0) + return -3; + if (sceChnnlsv_F21A1FCA_(&ctx1, data, 0x10) < 0) + return -4; + if (sceChnnlsv_F21A1FCA_(&ctx1, data + 0x10, *alignedLen) < 0) + return -5; + if (sceChnnlsv_850A7FA1_(&ctx2, data + 0x10, *alignedLen) < 0) + return -6; + + /* Verify that it decrypted correctly */ + if (sceChnnlsv_21BE78B4_(&ctx2) < 0) + return -7; + + /* If desired, a new file hash from this PSP can be computed now: + if (sceChnnlsv_C4C494F8(ctx1, newhash, cryptkey) < 0) + return -8; + */ + + /* The decrypted data starts at data + 0x10, so shift it back. */ + memmove(data, data + 0x10, *dataLen); + + /* All done */ + return 0; +} diff --git a/Tools/SaveTool/decrypt.h b/Tools/SaveTool/decrypt.h new file mode 100644 index 0000000000..57b8881d6c --- /dev/null +++ b/Tools/SaveTool/decrypt.h @@ -0,0 +1,31 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * decrypt.h - Declarations for functions in decrypt.c + * + * Copyright (c) 2005 Jim Paris + * Coypright (c) 2005 psp123 + * + * $Id: decrypt.h 1562 2005-12-10 20:52:45Z jim $ + */ + +#include + +/* Detect the samegame format and decrypt it. See main.c for an example. */ +int decrypt_file(const char *decrypted_filename, + const char *encrypted_filename, + const unsigned char *gamekey, + const int mainSdkVersion); + +/* Do the actual hardware decryption. + mode is 3 for saves with a cryptkey, or 1 otherwise. + data, alignedLen, and cryptkey must be multiples of 0x10. + cryptkey is NULL if mode == 1. +*/ +int decrypt_data(unsigned int mode, + unsigned char *data, + int *dataLen, + int *alignedLen, + unsigned char *cryptkey); diff --git a/Tools/SaveTool/encrypt.c b/Tools/SaveTool/encrypt.c new file mode 100644 index 0000000000..8da226e153 --- /dev/null +++ b/Tools/SaveTool/encrypt.c @@ -0,0 +1,233 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * encrypt.c - Encryption routines using sceChnnlsv + * + * Copyright (c) 2005 Jim Paris + * Coypright (c) 2005 psp123 + * + * $Id: encrypt.c 1560 2005-12-10 01:16:32Z jim $ + */ + +#include "encrypt.h" +#include "hash.h" +#include +#include +#include +#include +#include +#include "kernelcall/kernelcall.h" + +static inline int align16(unsigned int v) +{ + return ((v + 0xF) >> 4) << 4; +} + +int fopen_getsize(const char *filename, FILE **fd, int *size) +{ + if ((*fd = fopen(filename, "r")) == NULL) + return -1; + + fseek(*fd, 0, SEEK_END); + *size = ftell(*fd); + fseek(*fd, 0, SEEK_SET); + + if (*size <= 0) { + fclose(*fd); + return -2; + } + + return 0; +} + +/* Encrypt the given plaintext file, and update the message + authentication hashes in the param.sfo. The data_filename is + usually the final component of encrypted_filename, e.g. "DATA.BIN". + See main.c for an example of usage. */ +int encrypt_file(const char *plaintext_filename, + const char *encrypted_filename, + const char *data_filename, + const char *paramsfo_filename, + const char *paramsfo_filename_out, + const unsigned char *gamekey, + const int mainSdkVersion) +{ + FILE *in = NULL, *out = NULL, *sfo = NULL; + unsigned char *data = NULL, *cryptkey = NULL, *hash = NULL; + unsigned char paramsfo[0x1330]; + int len, aligned_len, tmp; + int retval; + + /* Open plaintext and param.sfo files and get size */ + + if (fopen_getsize(plaintext_filename, &in, &len) < 0) { + retval = -1; + goto out; + } + + if (fopen_getsize(paramsfo_filename, &sfo, &tmp) < 0) { + retval = -2; + goto out; + } + + /* Verify size of param.sfo; all known saves use this size */ + + if (tmp != 0x1330) { + retval = -3; + goto out; + } + + /* Allocate buffers. data has 0x10 bytes extra for the IV. */ + + aligned_len = align16(len); + + if ((data = + (unsigned char *) memalign(0x10, aligned_len + 0x10)) == NULL) { + retval = -4; + goto out; + } + + if ((cryptkey = (unsigned char *) memalign(0x10, 0x10)) == NULL) { + retval = -5; + goto out; + } + + if ((hash = (unsigned char *) memalign(0x10, 0x10)) == NULL) { + retval = -6; + goto out; + } + + /* Fill buffers. */ + + memset(data + len, 0, aligned_len - len); + if (fread(data, 1, len, in) != len) { + retval = -7; + goto out; + } + + if (fread(paramsfo, 1, 0x1330, sfo) != 0x1330) { + retval = -8; + goto out; + } + + if (gamekey != NULL) + memcpy(cryptkey, gamekey, 0x10); + + /* Do the encryption */ + + if ((retval = encrypt_data( gamekey ? (mainSdkVersion >= 4 ? 5 : 3) : 1, // 5 for sdk >= 4, 3 otherwise + data, + &len, &aligned_len, + hash, + gamekey ? cryptkey : NULL)) < 0) { + retval -= 1000; + goto out; + } + + /* Update the param.sfo hashes */ + + if ((retval = update_hashes(paramsfo, 0x1330, + data_filename, hash, + gamekey ? 3 : 1)) < 0) { + retval -= 2000; + goto out; + } + + /* Write the data to the file. encrypt_data has already set len. */ + + if ((out = fopen(encrypted_filename, "w")) == NULL) { + retval = -9; + goto out; + } + + if (fwrite(data, 1, len, out) != len) { + retval = -10; + goto out; + } + + /* Reopen param.sfo, and write the updated copy out. */ + + fclose(sfo); + if ((sfo = fopen(paramsfo_filename_out, "w")) == NULL) { + retval = -11; + goto out; + } + + if (fwrite(paramsfo, 1, 0x1330, sfo) != 0x1330) { + retval = -12; + goto out; + } + + /* All done. Return file length. */ + + retval = len; + + out: + if(out) fclose(out); + if(hash) free(hash); + if(cryptkey) free(cryptkey); + if(data) free(data); + if(sfo) fclose(sfo); + if(in) fclose(in); + + return retval; +} + +/* Do the actual hardware encryption. + mode is 3 for saves with a cryptkey, or 1 otherwise + data, dataLen, and cryptkey must be multiples of 0x10. + cryptkey is NULL if mode == 1. +*/ +int encrypt_data(unsigned int mode, + unsigned char *data, + int *dataLen, + int *alignedLen, + unsigned char *hash, + unsigned char *cryptkey) +{ + pspChnnlsvContext1 ctx1; + pspChnnlsvContext2 ctx2; + + /* Make room for the IV in front of the data. */ + memmove(data + 0x10, data, *alignedLen); + + /* Set up buffers */ + memset(&ctx1, 0, sizeof(pspChnnlsvContext1)); + memset(&ctx2, 0, sizeof(pspChnnlsvContext2)); + memset(hash, 0, 0x10); + memset(data, 0, 0x10); + + /* Build the 0x10-byte IV and setup encryption */ + if (sceChnnlsv_ABFDFC8B_(&ctx2, mode, 1, data, cryptkey) < 0) + return -1; + if (sceChnnlsv_E7833020_(&ctx1, mode) < 0) + return -2; + if (sceChnnlsv_F21A1FCA_(&ctx1, data, 0x10) < 0) + return -3; + if (sceChnnlsv_850A7FA1_(&ctx2, data + 0x10, *alignedLen) < 0) + return -4; + + /* Clear any extra bytes left from the previous steps */ + memset(data + 0x10 + *dataLen, 0, *alignedLen - *dataLen); + + /* Encrypt the data */ + if (sceChnnlsv_F21A1FCA_(&ctx1, data + 0x10, *alignedLen) < 0) + return -5; + + /* Verify encryption */ + if (sceChnnlsv_21BE78B4_(&ctx2) < 0) + return -6; + + /* Build the file hash from this PSP */ + if (sceChnnlsv_C4C494F8_(&ctx1, hash, cryptkey) < 0) + return -7; + + /* Adjust sizes to account for IV */ + *alignedLen += 0x10; + *dataLen += 0x10; + + /* All done */ + return 0; +} diff --git a/Tools/SaveTool/encrypt.h b/Tools/SaveTool/encrypt.h new file mode 100644 index 0000000000..2b06da21e7 --- /dev/null +++ b/Tools/SaveTool/encrypt.h @@ -0,0 +1,38 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * encrypt.h - Declarations for functions in encrypt.c + * + * Copyright (c) 2005 Jim Paris + * Coypright (c) 2005 psp123 + * + * $Id: encrypt.h 1559 2005-12-10 01:10:11Z jim $ + */ + +#include + +/* Encrypt the given plaintext file, and update the message + authentication hashes in the param.sfo. The data_filename is + usually the final component of encrypted_filename, e.g. "DATA.BIN". + See main.c for an example of usage. */ +int encrypt_file(const char *plaintext_filename, + const char *encrypted_filename, + const char *data_filename, + const char *paramsfo_filename, + const char *paramsfo_filename_out, + const unsigned char *gamekey, + const int mainSdkVersion); + +/* Do the actual hardware encryption. + mode is 3 for saves with a cryptkey, or 1 otherwise. + data, alignedLen, cryptkey, and hash must be multiples of 0x10. + cryptkey is NULL if mode == 1. +*/ +int encrypt_data(unsigned int mode, + unsigned char *data, + int *dataLen, + int *alignedLen, + unsigned char *hash, + unsigned char *cryptkey); diff --git a/Tools/SaveTool/hash.c b/Tools/SaveTool/hash.c new file mode 100644 index 0000000000..0a83a4ca3a --- /dev/null +++ b/Tools/SaveTool/hash.c @@ -0,0 +1,129 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * hash.c - Hashing routines using sceChnnlsv + * + * Copyright (c) 2005 Jim Paris + * Coypright (c) 2005 psp123 + * + * $Id: hash.c 1560 2005-12-10 01:16:32Z jim $ + */ + +#include "hash.h" +#include "psf.h" +#include +#include +#include +#include +#include +#include "kernelcall/kernelcall.h" + +static inline int align16(unsigned int v) +{ + return ((v + 0xF) >> 4) << 4; +} + +/* Update the hashes in the param.sfo data, using + the given file hash, and by computing the param.sfo hashes. + filehash must be a multiple of 16 bytes, and is reused to + store other hashes. The filename is e.g. "DATA.BIN". */ +int update_hashes(unsigned char *data, + int len, + const char *filename, + unsigned char *filehash, + int encryptmode) +{ + int alignedLen = align16(len); + unsigned char *datafile, *savedata_params; + int listLen, paramsLen; + int ret; + + /* Locate SAVEDATA_PARAM section in the param.sfo. */ + if ((ret = find_psf_section("SAVEDATA_PARAMS", data, 0x1330, + &savedata_params, ¶msLen)) < 0) { + return ret - 100; + } + + /* Locate the pointer for this DATA.BIN equivalent */ + if ((ret = find_psf_section("SAVEDATA_FILE_LIST", data, 0x1330, + &datafile, &listLen)) < 0) { + return ret - 200; + } + + if ((ret = find_psf_datafile(filename, datafile, + listLen, &datafile)) < 0) { + return ret - 300; + } + + /* Check minimum sizes based on where we want to write */ + if ((listLen < 0x20) || (paramsLen < 0x80)) { + return -1; + } + + /* Clear params and insert file hash */ + memset(savedata_params, 0, paramsLen); + memcpy(datafile + 0x0D, filehash, 0x10); + + /* Compute 11D0 hash over entire file */ + if ((ret = build_hash(filehash, data, len, alignedLen, + (encryptmode & 2) ? 4 : 2, NULL)) < 0) { // Not sure about "2" + return ret - 400; + } + + /* Copy 11D0 hash to param.sfo and set flag indicating it's there */ + memcpy(savedata_params + 0x20, filehash, 0x10); + *savedata_params |= 0x01; + + /* If new encryption mode, compute and insert the 1220 hash. */ + if (encryptmode & 2) { + + /* Enable the hash bit first */ + *savedata_params |= 0x20; + + if ((ret = build_hash(filehash, data, len, alignedLen, + 3, 0)) < 0) { + return ret - 500; + } + memcpy(savedata_params + 0x70, filehash, 0x10); + } + + /* Compute and insert the 11C0 hash. */ + if ((ret = build_hash(filehash, data, len, alignedLen, 1, 0)) < 0) { + return ret - 600; + } + memcpy(savedata_params + 0x10, filehash, 0x10); + + /* All done. */ + return 0; +} + +/* Build a single hash using the given data and mode. + data and alignedLen must be multiples of 0x10. + cryptkey is NULL for savedata. */ +int build_hash(unsigned char *output, + unsigned char *data, + unsigned int len, + unsigned int alignedLen, + int mode, + unsigned char *cryptkey) +{ + pspChnnlsvContext1 ctx1; + + /* Set up buffers */ + memset(&ctx1, 0, sizeof(pspChnnlsvContext1)); + memset(output, 0, 0x10); + memset(data + len, 0, alignedLen - len); + + /* Perform the magic */ + if (sceChnnlsv_E7833020_(&ctx1, mode & 0xFF) < 0) + return -1; + if (sceChnnlsv_F21A1FCA_(&ctx1, data, alignedLen) < 0) + return -2; + if (sceChnnlsv_C4C494F8_(&ctx1, output, cryptkey) < 0) + return -3; + + /* All done. */ + return 0; +} diff --git a/Tools/SaveTool/hash.h b/Tools/SaveTool/hash.h new file mode 100644 index 0000000000..978627a693 --- /dev/null +++ b/Tools/SaveTool/hash.h @@ -0,0 +1,34 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * hash.h - Declarations for functions in hash.c + * + * Copyright (c) 2005 Jim Paris + * Coypright (c) 2005 psp123 + * + * $Id: hash.h 1559 2005-12-10 01:10:11Z jim $ + */ + +#include + +/* Update the hashes in the param.sfo data, using + the given file hash, and by computing the param.sfo hashes. + filehash must be a multiple of 16 bytes, and is reused to + store other hashes. The filename is e.g. "DATA.BIN". */ +int update_hashes(unsigned char *data, + int len, + const char *filename, + unsigned char *filehash, + int encryptmode); + +/* Build a single hash using the given data and mode. + data, and alignedLen must be multiples of 0x10. + cryptkey is NULL for savedata.*/ +int build_hash(unsigned char *output, + unsigned char *data, + unsigned int len, + unsigned int alignedLen, + int mode, + unsigned char *cryptkey); diff --git a/Tools/SaveTool/kernelcall.prx b/Tools/SaveTool/kernelcall.prx new file mode 100644 index 0000000000000000000000000000000000000000..350ee401704d44b8116a5fbff33e9dec504b5f18 GIT binary patch literal 2642 zcmb_dPiPcZ82`=AOPrKNMjPu=0?vYE_fVEJSn45%U|X?}YEUm0#r)Y(L#LatJCXEI z45$#=!}Q=Gl^oU{icn<&=Hg*@C9WoT@DFV@BIq6p%}GKLn?q#foB7`6x$MeP{9yRa z_ulXOzW2TPy*FpR?BAf`2FP2E0J{JfZGhJOtGNpnG$ippwg&Tq9MCN=by)!P zv;i<>BDU3PArVE%H&FEBt9kti5Dljme1V%ju;2;Y^x`Ww^e9T6fud)kkT6iuiMLWM zBsx*@O^!EE_M^Dv$1UKFlFLBZi{h4dkH-WSg4}Vduf`Kt2_o}88uZtRML&k6xAxhIMK6XW z@2?i>??lP7Q1p`Tpx;L=)N8cAjdasUGml%y-$*Z^u0u@&WnYjcO(4|qn;KrL77~KF zk|R*`3}t`f=AcfRk1tOlK=$bj$g|KYDmEoF4WZXJp86cu=wYd0_2yQeE9F$g>w0)^;f@NI`iK7`N?AZ>GQn@ z-quGmqq~uwb|%n0NP8wtZtW%jd0zgxxZsv6;>zh#Wk=Bx8V=u^Lzh@QReI4}Q3bZ9n{5<8lx{G!Bj1FKQ^ENB_o+*Pe8d%GwUUg-$LAmjUE$M1&s2 z2CN_^JC+`Dhp6z^W9bRU{wi}~ER1L}Q{x}BbE9cH!z*eyUgPc`O@k>& +#include +#include +#include +#include +#include +#include +#include +#include + + + +PSP_MODULE_INFO("kernelcall", 0x1006, 2, 0); + + +u64 sceSysreg_driver_4F46EEDE(); + + +u64 GetFuseId() +{ + u64 fuseId = sceSysreg_driver_4F46EEDE(); + return fuseId; +} + +int sceChnnlsv_E7833020_(pspChnnlsvContext1 *ctx, int mode) +{ + int k1 = pspSdkSetK1(0); + int res = sceChnnlsv_E7833020(ctx,mode); + + pspSdkSetK1(k1); + return res; +} + +int sceChnnlsv_F21A1FCA_(pspChnnlsvContext1 *ctx, unsigned char *data, int len) +{ + int k1 = pspSdkSetK1(0); + int res = sceChnnlsv_F21A1FCA(ctx,data,len); + pspSdkSetK1(k1); + return res; +} + +int sceChnnlsv_C4C494F8_(pspChnnlsvContext1 *ctx, + unsigned char *hash, unsigned char *cryptkey) +{ + int k1 = pspSdkSetK1(0); + int res = sceChnnlsv_C4C494F8(ctx,hash,cryptkey); + pspSdkSetK1(k1); + return res; +} + +int sceChnnlsv_ABFDFC8B_(pspChnnlsvContext2 *ctx, int mode1, int mode2, + unsigned char *hashkey, unsigned char *cipherkey) +{ + int k1 = pspSdkSetK1(0); + int res = sceChnnlsv_ABFDFC8B(ctx,mode1,mode2,hashkey,cipherkey); + pspSdkSetK1(k1); + return res; +} + +int sceChnnlsv_850A7FA1_(pspChnnlsvContext2 *ctx, unsigned char *data, int len) +{ + int k1 = pspSdkSetK1(0); + int res = sceChnnlsv_850A7FA1(ctx,data,len); + pspSdkSetK1(k1); + return res; +} + +int sceChnnlsv_21BE78B4_(pspChnnlsvContext2 *ctx) +{ + int k1 = pspSdkSetK1(0); + int res = sceChnnlsv_21BE78B4(ctx); + pspSdkSetK1(k1); + return res; +} + +int module_start(SceSize args, void *argp) +{ + return 0; +} + +int module_stop() +{ + return 0; +} diff --git a/Tools/SaveTool/kernelcall/kernelcall.h b/Tools/SaveTool/kernelcall/kernelcall.h new file mode 100644 index 0000000000..4baf4c2ed3 --- /dev/null +++ b/Tools/SaveTool/kernelcall/kernelcall.h @@ -0,0 +1,9 @@ +u64 GetFuseId(); +int sceChnnlsv_E7833020_(pspChnnlsvContext1 *ctx, int mode); +int sceChnnlsv_F21A1FCA_(pspChnnlsvContext1 *ctx, unsigned char *data, int len); +int sceChnnlsv_C4C494F8_(pspChnnlsvContext1 *ctx, + unsigned char *hash, unsigned char *cryptkey); +int sceChnnlsv_ABFDFC8B_(pspChnnlsvContext2 *ctx, int mode1, int mode2, + unsigned char *hashkey, unsigned char *cipherkey); +int sceChnnlsv_850A7FA1_(pspChnnlsvContext2 *ctx, unsigned char *data, int len); +int sceChnnlsv_21BE78B4_(pspChnnlsvContext2 *ctx); diff --git a/Tools/SaveTool/main.c b/Tools/SaveTool/main.c new file mode 100644 index 0000000000..54a2b34e96 --- /dev/null +++ b/Tools/SaveTool/main.c @@ -0,0 +1,579 @@ +#include +#include +#include +#include +#include +#include +#include +#include "kernelcall/kernelcall.h" +#include +#include +#include +#include "encrypt.h" +#include "decrypt.h" +#include "psf.h" + +#define printf pspDebugScreenPrintf + +/* Define the module info section */ +PSP_MODULE_INFO("ppssppsavetool", 0, 1, 0); +PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_USER); +PSP_HEAP_SIZE_KB(-64); + +#define ENCRYPT_FILE_VERSION 1 + + +int currentMenu = 0; +int selectedOption = 0; +int basePath = 0; +int workDir = 0; + +char *menuList0[] = {"Encrypt","Decrypt", "Exit", NULL}; +char *menuList1[] = {"ms0:/PSP/SAVEDATAPPSSPP/","host0:/","host1:/", "host2:/", "Back", NULL}; +char *menuList2[] = {"Back", NULL}; + +int GetSDKMainVersion(int sdkVersion) +{ + if(sdkVersion > 0x307FFFF) + return 6; + if(sdkVersion > 0x300FFFF) + return 5; + if(sdkVersion > 0x206FFFF) + return 4; + if(sdkVersion > 0x205FFFF) + return 3; + if(sdkVersion >= 0x2000000) + return 2; + if(sdkVersion >= 0x1000000) + return 1; + return 0; +}; + +int ProcessInput(int maxOption, int *selectedOption) +{ + SceCtrlData pad, oldpad; + sceCtrlReadBufferPositive(&oldpad, 1); + while(1) + { + sceCtrlReadBufferPositive(&pad, 1); + + if (pad.Buttons != 0) + { + if (!(oldpad.Buttons & PSP_CTRL_CROSS) && pad.Buttons & PSP_CTRL_CROSS) + { + return *selectedOption; + } + else if (!(oldpad.Buttons & PSP_CTRL_UP) && pad.Buttons & PSP_CTRL_UP && *selectedOption > 0) + { + *selectedOption = *selectedOption-1; + return -1; + } + else if (!(oldpad.Buttons & PSP_CTRL_DOWN) && pad.Buttons & PSP_CTRL_DOWN && *selectedOption < maxOption-1) + { + *selectedOption = *selectedOption + 1; + return -1; + } + } + oldpad = pad; + } +} + +typedef struct +{ + char name[30]; + char saveFile[30]; + int errorId; +} DirInfo; + +typedef struct +{ + int fileVersion; + u8 key[16]; + int sdkVersion; +} EncryptFileInfo; + +DirInfo dirList[128]; +int numDirList; +DirInfo invalidDirList[128]; +int numInvalidDirList; + +int FileExist(char* basePath, char* dirPath, char* fileName) +{ + SceIoStat fileStat; + char path[1024]; + sprintf(path,"%s%s/%s",basePath, dirPath, fileName); + if(sceIoGetstat(path, &fileStat) < 0) // no file + return 0; + return 1; +} + +int FileRead(char* basePath, char* dirPath, char* fileName, u8* dataout, int size) +{ + char path[1024]; + sprintf(path,"%s%s/%s",basePath, dirPath, fileName); + SceUID fileId = sceIoOpen(path, PSP_O_RDONLY, 0777); + if(fileId < 0) + return -1; + sceIoRead(fileId, dataout, size); + sceIoClose(fileId); + return 0; +} + +void AddErrorDir(char* dirName, int error) +{ + if(numInvalidDirList >= 128) + return; + DirInfo *inf = &invalidDirList[numInvalidDirList]; + strcpy(inf->name,dirName); + inf->errorId = error; + numInvalidDirList++; +} + +int UpdateValidDir(int isEncrypt) +{ + numDirList = 0; + numInvalidDirList = 0; + + const char* pspPath = "ms0:/PSP/SAVEDATA/"; + + char* pathSrc; + char* pathDst; + if(isEncrypt) + { + pathSrc = menuList1[basePath]; + pathDst = pspPath; + } + else + { + pathSrc = pspPath; + pathDst = menuList1[basePath]; + } + + int dfd; + dfd = sceIoDopen(menuList1[basePath]); + if(dfd >= 0) + { + SceIoDirent data; + while(sceIoDread(dfd, &data) > 0 && numDirList < 128) + { + if(!(data.d_stat.st_attr & 0x10)) // is not a directory + { + continue; + } + + if(data.d_name[0] == '.') // ignore "." and ".." + continue; + + if(FileExist(menuList1[basePath], data.d_name, "ENCRYPT_INFO.BIN") < 0) + { + AddErrorDir(data.d_name,1); + continue; + } + + EncryptFileInfo encryptInfo; + if(FileRead(menuList1[basePath], data.d_name, "ENCRYPT_INFO.BIN",(u8*)&encryptInfo,sizeof(encryptInfo)) < 0) + { + AddErrorDir(data.d_name,2); + continue; + } + + if(encryptInfo.fileVersion != ENCRYPT_FILE_VERSION) // Not good version + { + AddErrorDir(data.d_name,3); + continue; + } + + if(FileExist(pathSrc, data.d_name, "PARAM.SFO") < 0) + { + AddErrorDir(data.d_name,4); + continue; + } + + u8 paramsfo[0x1330]; + if(FileRead(pathSrc, data.d_name, "PARAM.SFO",(u8*)¶msfo,0x1330) < 0) + { + AddErrorDir(data.d_name,5); + continue; + } + + u8 *datafile; + int listLen; + if (find_psf_section("SAVEDATA_FILE_LIST", paramsfo, 0x1330, + &datafile, &listLen) < 0) + { + AddErrorDir(data.d_name,6); + continue; + } + if(datafile[0] == 0) + { + AddErrorDir(data.d_name,7); + continue; + } + + char filename[32]; + strcpy(filename, (char*)datafile); + + if(FileExist(pathSrc, data.d_name, filename) < 0) + { + AddErrorDir(data.d_name,8); + continue; + } + + DirInfo *inf = &dirList[numDirList]; + inf->errorId = 0; + strcpy(inf->name, data.d_name); + strcpy(inf->saveFile, filename); + + numDirList++; + + } + sceIoDclose(dfd); + if(numDirList == 0) + { + return -1; + } + } + else + { + return -2; + } + return 0; +} + +int FileCopy(char* srcPath, char* destPath, char* fileName) +{ + SceIoStat fileStat; + char path[258]; + sprintf(path,"%s/%s",srcPath, fileName); + + if(sceIoGetstat(path, &fileStat) < 0) + return -1; + u8* data = malloc(fileStat.st_size); + + SceUID fileId = sceIoOpen(path, PSP_O_RDONLY, 0777); + if(fileId < 0) + { + printf("Fail opening %s\n",path); + return -1; + } + sceIoRead(fileId, data, fileStat.st_size); + sceIoClose(fileId); + + sprintf(path,"%s/%s",destPath, fileName); + + fileId = sceIoOpen(path, PSP_O_WRONLY | PSP_O_CREAT, 0777); + if(fileId < 0) + { + printf("Fail opening %s\n",path); + return -1; + } + sceIoWrite(fileId, data, fileStat.st_size); + sceIoClose(fileId); + + free(data); + return 0; +} + +int main(int argc, char *argv[]) +{ + int i; + pspDebugScreenInit(); + + SceUID mod = pspSdkLoadStartModule ("flash0:/kd/chnnlsv.prx",PSP_MEMORY_PARTITION_KERNEL); + if (mod < 0) { + printf("Error 0x%08X loading/starting chnnlsv.prx.\n", mod); + } + + mod = pspSdkLoadStartModule ("kernelcall.prx",PSP_MEMORY_PARTITION_KERNEL); + if (mod < 0) { + printf("Error 0x%08X loading/starting kernelcall.prx.\n", mod); + } + + sceCtrlSetSamplingCycle(0); + sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG); + for(;;) + { + printf("===================================================================="); + printf("PPSSPP Save Tool\n"); + printf("====================================================================\n\n\n"); + + switch(currentMenu) + { + + case 0: + { + int maxOption = 0; + for(i = 0; menuList0[i]; i++) + { + if(i == selectedOption) + printf(" > %s\n",menuList0[i]); + else + printf(" %s\n",menuList0[i]); + maxOption++; + } + + int input = ProcessInput(maxOption, &selectedOption); + if(input == 0) + { + currentMenu = 1; + selectedOption = 0; + } + else if(input == 1) + { + currentMenu = 4; + selectedOption = 0; + } + else if(input == 2) + { + sceKernelExitGame(); + } + } + break; + case 4: + case 1: + { + int maxOption = 0; + printf("PPSSPP Decrypted Save Directory : \n"); + for(i = 0; menuList1[i]; i++) + { + if(i == selectedOption) + printf(" > %s\n",menuList1[i]); + else + printf(" %s\n",menuList1[i]); + maxOption++; + } + + int input = ProcessInput(maxOption, &selectedOption); + if(input == maxOption-1) + { + if(currentMenu == 1) + selectedOption = 0; + else + selectedOption = 1; + currentMenu = 0; + } + else if(input >= 0) + { + basePath = selectedOption; + if(currentMenu == 1) + { + currentMenu = 2; + UpdateValidDir(1); + } + else + { + currentMenu = 5; + UpdateValidDir(0); + } + selectedOption = 0; + } + } + break; + case 5: + case 2: + { + int maxOption = 0; + if(currentMenu == 2) + printf("Save to encrypt : \n"); + else + printf("Save to decrypt : \n"); + + if(numDirList == 0) + { + printf("No compatible data, see README for help on use\n"); + } + for(i = 0; i < numDirList; i++) + { + if(i == selectedOption) + printf(" > %s\n",dirList[i].name); + else + printf(" %s\n",dirList[i].name); + maxOption++; + } + + for(i = 0; menuList2[i]; i++) + { + if((i+numDirList) == selectedOption) + printf(" > %s\n",menuList2[i]); + else + printf(" %s\n",menuList2[i]); + maxOption++; + } + + printf("\n Invalid path : \n"); + for(i = 0; i < numInvalidDirList && i < (22-numDirList); i++) + { + switch(invalidDirList[i].errorId) + { + case 1: + printf(" %s : ENCRYPT_INFO.BIN not found\n",invalidDirList[i].name); + break; + case 2: + printf(" %s : ENCRYPT_INFO.BIN read error\n",invalidDirList[i].name); + break; + case 3: + printf(" %s : ENCRYPT_INFO.BIN wrong version\n",invalidDirList[i].name); + break; + case 4: + printf(" %s : PARAM.SFO not found\n",invalidDirList[i].name); + break; + case 5: + printf(" %s : PARAM.SFO read error\n",invalidDirList[i].name); + break; + case 6: + printf(" %s : SAVEDATA_FILE_LIST not found in PARAM.SFO\n",invalidDirList[i].name); + break; + case 7: + printf(" %s : no save name in SAVEDATA_FILE_LIST\n",invalidDirList[i].name); + break; + case 8: + printf(" %s : no save found\n",invalidDirList[i].name); + break; + default: + break; + } + } + + int input = ProcessInput(maxOption, &selectedOption); + if(input == numDirList) + { + if(currentMenu == 2) + currentMenu = 1; + else + currentMenu = 4; + selectedOption = basePath; + } + else if(input >= 0) + { + if(currentMenu == 2) + currentMenu = 3; + else + currentMenu = 6; + workDir = input; + selectedOption = 0; + } + } + break; + case 6: + case 3: + { + + EncryptFileInfo encryptInfo; + if(FileRead(menuList1[basePath], dirList[workDir].name, "ENCRYPT_INFO.BIN",(u8*)&encryptInfo,sizeof(encryptInfo)) < 0) + { + printf("Can't read encrypt file\n"); + } + else + { + printf("Key : "); + for(i = 0; i < 16; i++) + printf(" %02x",(u8)encryptInfo.key[i]); + printf("\n"); + printf("SDK Version : 0x%x\n",encryptInfo.sdkVersion); + + char srcPath[128]; + char dstPath[128]; + if(currentMenu == 3) + { + sprintf(srcPath,"%s%s",menuList1[basePath], dirList[workDir].name); + sprintf(dstPath,"ms0:/PSP/SAVEDATA/%s",dirList[workDir].name); + sceIoMkdir(dstPath,0777); + } + else + { + sprintf(srcPath,"ms0:/PSP/SAVEDATA/%s",dirList[workDir].name); + sprintf(dstPath,"%s%s",menuList1[basePath], dirList[workDir].name); + } + + int dfd; + dfd = sceIoDopen(srcPath); + if(dfd >= 0) + { + SceIoDirent dirinfo; + while(sceIoDread(dfd, &dirinfo) > 0) + { + + if(!(dirinfo.d_stat.st_mode & 0x2000)) // is not a file + continue; + + if(strcmp(dirinfo.d_name,"ENCRYPT_INFO.BIN") == 0) // don't copy encrypt info + continue; + + FileCopy(srcPath, dstPath, dirinfo.d_name); + + } + sceIoDclose(dfd); + } + + if(currentMenu == 3) + { + + char decryptedFile[258], encryptedFile[258], srcSFO[258], dstSFO[258]; + sprintf(decryptedFile,"%s/%s",srcPath ,dirList[workDir].saveFile); + sprintf(srcSFO,"%s/PARAM.SFO",srcPath); + + sprintf(encryptedFile,"%s/%s",dstPath ,dirList[workDir].saveFile); + sprintf(dstSFO,"%s/PARAM.SFO",dstPath); + + printf("Encoding %s into %s\n",decryptedFile, encryptedFile); + + int ret = encrypt_file(decryptedFile, + encryptedFile, + dirList[workDir].saveFile, + srcSFO, + dstSFO, + encryptInfo.key[0] != 0 ? encryptInfo.key : NULL, + GetSDKMainVersion(encryptInfo.sdkVersion) + ); + + if(ret < 0) { + printf("Error: encrypt_file() returned %d\n\n", ret); + } else { + printf("Successfully wrote %d bytes to\n", ret); + printf(" %s\n", encryptedFile); + printf("and updated hashes in\n"); + printf(" %s\n\n", dstSFO); + } + } + else + { + char decryptedFile[258], encryptedFile[258]; + sprintf(encryptedFile,"%s/%s",srcPath ,dirList[workDir].saveFile); + sprintf(decryptedFile,"%s/%s",dstPath ,dirList[workDir].saveFile); + + printf("Decoding %s into %s\n",encryptedFile, decryptedFile); + + int ret = decrypt_file(decryptedFile, encryptedFile, encryptInfo.key[0] != 0 ? encryptInfo.key : NULL, GetSDKMainVersion(encryptInfo.sdkVersion)); + + if(ret < 0) { + printf("Error: decrypt_file() returned %d\n\n", ret); + } else { + printf("Successfully wrote %d bytes to\n", ret); + printf(" %s\n", decryptedFile); + } + } + printf(" > Back\n"); + + int input = ProcessInput(1, &selectedOption); + if(input >= 0) + { + if(currentMenu == 3) + currentMenu = 2; + else + currentMenu = 5; + selectedOption = 0; + } + } + } + break; + default: + sceKernelExitGame(); + break; + } + + pspDebugScreenClear(); + sceDisplayWaitVblankStart(); + sceGuSwapBuffers(); + } + return 0; +} diff --git a/Tools/SaveTool/psf.c b/Tools/SaveTool/psf.c new file mode 100644 index 0000000000..5f68b1cc74 --- /dev/null +++ b/Tools/SaveTool/psf.c @@ -0,0 +1,114 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * psf.c - PSF parsing routines + * + * Copyright (c) 2005 Jim Paris + * Coypright (c) 2005 psp123 + * + * $Id: psf.c 1560 2005-12-10 01:16:32Z jim $ + */ + +#include "psf.h" +#include +#include +#include +#include +#include + +/* Find to the named section in the PSF file, and return an + absolute pointer to it and the section size. */ +int find_psf_section(const char *name, + unsigned char *data, + int dataLen, + unsigned char **location, + int *size) +{ + unsigned short int nameLoc; + int i, magicHead, strLoc, headLen, numSects; + int sectCurLen, sectBufLen, sectBufLoc, curPos; + + if (dataLen < 0x14) + return -1; + + /* Get the basics from the header */ + magicHead = *(unsigned int *)&data[0x00]; + strLoc = *(unsigned int *)&data[0x08]; + headLen = *(unsigned int *)&data[0x0C]; + numSects = *(unsigned int *)&data[0x10]; + + /* Do some error checking */ + if (magicHead != 0x46535000) + return -2; + + /* Verify strLoc is proper */ + if ((strLoc > headLen) || (strLoc >= dataLen)) + return -3; + + /* Verify headLen is proper */ + if (headLen >= dataLen) + return -4; + + /* Verify numSects is proper */ + if (numSects != ((strLoc - 0x14) / 0x10)) + return -5; + + /* Process all sections */ + for (i = 0; i < numSects; i++) + { + /* Get the curPos */ + curPos = 0x14 + (i * 0x10); + + /* Verify curPos is proper */ + if (curPos >= strLoc) + return -6; + + /* Get some basic info about this section */ + nameLoc = *(unsigned short *)&data[curPos]; + sectCurLen = *(unsigned short *)&data[curPos + 0x04]; + sectBufLen = *(unsigned short *)&data[curPos + 0x08]; + sectBufLoc = *(unsigned short *)&data[curPos + 0x0C]; + + /* Do some error checking */ + if ((nameLoc < dataLen) && (sectCurLen < dataLen) + && (sectBufLen < dataLen) && (sectBufLoc < dataLen)) + { + /* Check if this is the section we want */ + if (!stricmp((char *)&data[strLoc + nameLoc], name)) + { + /* Update the location and size */ + *location = &data[headLen + sectBufLoc]; + *size = sectBufLen; + return 0; + } + } + } + + /* Section was not found if it makes it here */ + return -7; +} + +/* Find the named file inside the FILE_LIST, and return + an absolute pointer to it. */ +int find_psf_datafile(const char *name, + unsigned char *filelist, + int size, + unsigned char **location) +{ + int i; + + /* Process all files */ + for (i = 0; (i + 0x0d) <= size; i += 0x20) + { + /* Check if this is the filename we want */ + if (!strncasecmp((char *)&filelist[i], name, 0x0d)) { + *location = &filelist[i]; + return 0; + } + } + + /* File was not found if it makes it here */ + return -1; +} diff --git a/Tools/SaveTool/psf.h b/Tools/SaveTool/psf.h new file mode 100644 index 0000000000..261e241e84 --- /dev/null +++ b/Tools/SaveTool/psf.h @@ -0,0 +1,29 @@ +/* + * PSP Software Development Kit - http://www.pspdev.org + * ----------------------------------------------------------------------- + * Licensed under the BSD license, see LICENSE in PSPSDK root for details. + * + * psf.h - Declarations for functions in psf.c + * + * Copyright (c) 2005 Jim Paris + * Coypright (c) 2005 psp123 + * + * $Id: psf.h 1559 2005-12-10 01:10:11Z jim $ + */ + +#include + +/* Find the named section in the PSF file, and return an + absolute pointer to it and the section size. */ +int find_psf_section(const char *name, + unsigned char *data, + int dataLen, + unsigned char **location, + int *size); + +/* Find the named file inside the FILE_LIST, and return + an absolute pointer to it. */ +int find_psf_datafile(const char *name, + unsigned char *filelist, + int size, + unsigned char **location); From 05a3574315f1fd5fe3dbb2d805897a539b788e31 Mon Sep 17 00:00:00 2001 From: Xele02 Date: Fri, 28 Dec 2012 12:00:43 +0100 Subject: [PATCH 4/4] Add missing break --- Core/Dialog/PSPSaveDialog.cpp | 2 +- Core/Dialog/SavedataParam.cpp | 7 +------ Core/HLE/sceKernelMemory.cpp | 6 +++--- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/Core/Dialog/PSPSaveDialog.cpp b/Core/Dialog/PSPSaveDialog.cpp index 92a0a5e398..44d110f5ab 100644 --- a/Core/Dialog/PSPSaveDialog.cpp +++ b/Core/Dialog/PSPSaveDialog.cpp @@ -665,7 +665,7 @@ int PSPSaveDialog::Update() param.GetPspParam()->result = SCE_UTILITY_SAVEDATA_ERROR_SIZES_NO_DATA; } status = SCE_UTILITY_STATUS_FINISHED; - // TODO: intentional missing break? + break; case SCE_UTILITY_SAVEDATA_TYPE_LIST: param.GetList(param.GetPspParam()); param.GetPspParam()->result = 0; diff --git a/Core/Dialog/SavedataParam.cpp b/Core/Dialog/SavedataParam.cpp index 1c479f89b1..6fd27dd0e9 100644 --- a/Core/Dialog/SavedataParam.cpp +++ b/Core/Dialog/SavedataParam.cpp @@ -254,12 +254,7 @@ bool SavedataParam::Save(SceUtilitySavedataParam* param, int saveId) memcpy(encryptInfo.key,param->key,16); std::string encryptInfoPath = dirPath+"/"+"ENCRYPT_INFO.BIN"; - handle = pspFileSystem.OpenFile(encryptInfoPath,(FileAccess)(FILEACCESS_WRITE | FILEACCESS_CREATE)); - if (handle) - { - pspFileSystem.WriteFile(handle, (u8*)&encryptInfo, dataSize); - pspFileSystem.CloseFile(handle); - } + WritePSPFile(encryptInfoPath, (u8*)&encryptInfo, dataSize); } } return true; diff --git a/Core/HLE/sceKernelMemory.cpp b/Core/HLE/sceKernelMemory.cpp index 0edcc83a0e..0b5a3c49b7 100644 --- a/Core/HLE/sceKernelMemory.cpp +++ b/Core/HLE/sceKernelMemory.cpp @@ -544,7 +544,7 @@ void sceKernelSetCompiledSdkVersion600_602(int sdkVersion) } else { - ERROR_LOG(HLE,"sceKernelSetCompiledSdkVersion395 unknown SDK : %x\n",sdkVersion); + ERROR_LOG(HLE,"sceKernelSetCompiledSdkVersion600_602 unknown SDK : %x\n",sdkVersion); } return; } @@ -561,7 +561,7 @@ void sceKernelSetCompiledSdkVersion603_605(int sdkVersion) } else { - ERROR_LOG(HLE,"sceKernelSetCompiledSdkVersion395 unknown SDK : %x\n",sdkVersion); + ERROR_LOG(HLE,"sceKernelSetCompiledSdkVersion603_605 unknown SDK : %x\n",sdkVersion); } return; } @@ -576,7 +576,7 @@ void sceKernelSetCompiledSdkVersion606(int sdkVersion) } else { - ERROR_LOG(HLE,"sceKernelSetCompiledSdkVersion395 unknown SDK : %x\n",sdkVersion); + ERROR_LOG(HLE,"sceKernelSetCompiledSdkVersion606 unknown SDK : %x\n",sdkVersion); } return; }