From a58f2b001695b9242e54f8e1515855962fb28fb9 Mon Sep 17 00:00:00 2001 From: bucanero Date: Tue, 17 Dec 2024 22:02:43 -0300 Subject: [PATCH] improve encrypted saves --- include/menu.h | 2 -- include/saves.h | 1 + source/exec_cmd.c | 7 ++--- source/orbis_jbc.c | 4 +-- source/saves.c | 71 +++++++++++++++++++++++++++++++++++++--------- 5 files changed, 64 insertions(+), 21 deletions(-) diff --git a/include/menu.h b/include/menu.h index c3652a9..f6465bb 100644 --- a/include/menu.h +++ b/include/menu.h @@ -263,12 +263,10 @@ void drawEndLogo(void); int load_app_settings(app_config_t* config); int save_app_settings(app_config_t* config); -int reset_app_settings(app_config_t* config); int initialize_jbc(void); void terminate_jbc(void); int initVshDataMount(void); int get_max_pfskey_ver(void); -char* get_fw_by_pfskey_ver(int key_ver); #endif diff --git a/include/saves.h b/include/saves.h index f1aa5ed..4253b03 100644 --- a/include/saves.h +++ b/include/saves.h @@ -330,3 +330,4 @@ int vmp_resign(const char *src_vmp); char* sjis2utf8(char* input); uint8_t* getIconPS2(const char* folder, const char* iconfile); +const char* get_fw_by_pfskey_ver(int key_ver); diff --git a/source/exec_cmd.c b/source/exec_cmd.c index 657c1bd..e05a606 100644 --- a/source/exec_cmd.c +++ b/source/exec_cmd.c @@ -451,7 +451,7 @@ static void copySavePFS(const save_entry_t* save) if (!orbis_SaveMount(save, ORBIS_SAVE_DATA_MOUNT_MODE_RDWR | ORBIS_SAVE_DATA_MOUNT_MODE_CREATE2 | ORBIS_SAVE_DATA_MOUNT_MODE_COPY_ICON, mount)) { - LOG("[!] Error: can't create/mount save!"); + show_message("Error: can't create HDD save"); return; } orbis_SaveUmount(mount); @@ -476,7 +476,6 @@ static void copySavePFS(const save_entry_t* save) if (!orbis_SaveMount(save, ORBIS_SAVE_DATA_MOUNT_MODE_RDWR, mount)) { - LOG("[!] Error: can't remount save"); show_message("Error! Can't mount encrypted save.\n(incompatible save-game firmware version)"); return; } @@ -638,9 +637,9 @@ static int webReqHandler(dWebRequest_t* req, dWebResponse_t* res, void* list) { base = strdup(item->path); path = strdup(item->path); - *strrchr(base, '/') = 0; } *strrchr(base, '/') = 0; + *strrchr(base, '/') = 0; id = zip_directory(base, path, res->data); if (item->flags & SAVE_FLAG_HDD) @@ -673,7 +672,7 @@ static int webReqHandler(dWebRequest_t* req, dWebResponse_t* res, void* list) // http://ps3-ip:8080/icon/CUSA12345-DIR-NAME/sce_sys/icon0.png if (wildcard_match(req->resource, "/icon/*/sce_sys/icon0.png")) { - asprintf(&res->data, "%sAPOLLO/%s", selected_entry->path, req->resource + 6); + asprintf(&res->data, "%sPS4/APOLLO/%s", selected_entry->path, req->resource + 6); return (file_exists(res->data) == SUCCESS); } diff --git a/source/orbis_jbc.c b/source/orbis_jbc.c index ad7aa5b..156400c 100644 --- a/source/orbis_jbc.c +++ b/source/orbis_jbc.c @@ -214,9 +214,9 @@ int get_max_pfskey_ver(void) return 0; } -char* get_fw_by_pfskey_ver(int key_ver) +const char* get_fw_by_pfskey_ver(int key_ver) { - char* fw[] = {"???", "Any", "4.50+", "4.70+", "5.00+", "5.50+", "6.00+", "6.50+", "7.00+", "7.50+", "8.00+"}; + const char* fw[] = {"???", "Any", "4.50+", "4.70+", "5.00+", "5.50+", "6.00+", "6.50+", "7.00+", "7.50+", "8.00+"}; if (key_ver > 10) key_ver = 0; return fw[key_ver]; diff --git a/source/saves.c b/source/saves.c index d9cd379..340d7d1 100644 --- a/source/saves.c +++ b/source/saves.c @@ -841,6 +841,26 @@ static void _addSfoCommands(save_entry_t* save) */ } +static int set_pfs_codes(save_entry_t* item) +{ + uint8_t data[16]; + char savePath[256]; + code_entry_t* cmd; + item->codes = list_alloc(); + + cmd = _createCmdCode(PATCH_COMMAND, CHAR_ICON_USER " View Save Details", CMD_VIEW_DETAILS); + list_append(item->codes, cmd); + + snprintf(savePath, sizeof(savePath), "%s%s.bin", item->path, item->dir_name); + read_file(savePath, data, sizeof(data)); + snprintf(savePath, sizeof(savePath), CHAR_ICON_WARN " --- Encrypted save requires firmware %s --- " CHAR_ICON_WARN, get_fw_by_pfskey_ver(data[8])); + + cmd = _createCmdCode(PATCH_NULL, savePath, CMD_CODE_NULL); + list_append(item->codes, cmd); + + return list_count(item->codes); +} + option_entry_t* get_file_entries(const char* path, const char* mask) { return _getFileOptions(path, mask, CMD_CODE_NULL); @@ -864,6 +884,9 @@ int ReadCodes(save_entry_t * save) char mount[ORBIS_SAVE_DATA_DIRNAME_DATA_MAXSIZE]; char *tmp = NULL; + if (save->type == FILE_TYPE_NULL) + return set_pfs_codes(save); + save->codes = list_alloc(); if (save->flags & (SAVE_FLAG_HDD|SAVE_FLAG_LOCKED)) @@ -1665,8 +1688,9 @@ static void read_usb_encrypted_saves(const char* userPath, list_t *list, uint64_ { DIR *d, *d2; struct dirent *dir, *dir2; - save_entry_t *item; + save_entry_t *item, tmp; char savePath[256]; + char mount[ORBIS_SAVE_DATA_DIRNAME_DATA_MAXSIZE]; d = opendir(userPath); @@ -1691,30 +1715,51 @@ static void read_usb_encrypted_saves(const char* userPath, list_t *list, uint64_ if (dir2->d_type != DT_REG || endsWith(dir2->d_name, ".bin")) continue; - snprintf(savePath, sizeof(savePath), "%s%s/%s.bin", userPath, dir->d_name, dir2->d_name); - if (file_exists(savePath) != SUCCESS) + snprintf(savePath, sizeof(savePath), "%s%s/", userPath, dir->d_name); + tmp.path = savePath; + tmp.title_id = dir->d_name; + tmp.dir_name = dir2->d_name; + if (!orbis_SaveMount(&tmp, SAVE_FLAG_LOCKED, mount)) + { + snprintf(savePath, sizeof(savePath), CHAR_ICON_WARN "%s/%s", dir->d_name, dir2->d_name); + item = _createSaveEntry(SAVE_FLAG_PS4 | SAVE_FLAG_LOCKED, savePath); + item->type = FILE_TYPE_NULL; + item->dir_name = strdup(dir2->d_name); + asprintf(&item->path, "%s%s/", userPath, dir->d_name); + asprintf(&item->title_id, "%.9s", dir->d_name); + list_append(list, item); + continue; + } + + snprintf(savePath, sizeof(savePath), APOLLO_SANDBOX_PATH "sce_sys/param.sfo", mount); + LOG("Reading %s...", savePath); + + sfo_context_t* sfo = sfo_alloc(); + if (sfo_read(sfo, savePath) < 0) { + LOG("Unable to read from '%s'", savePath); + sfo_free(sfo); continue; + } - snprintf(savePath, sizeof(savePath), "(Encrypted) %s/%s", dir->d_name, dir2->d_name); + snprintf(savePath, sizeof(savePath), "%s - %s", sfo_get_param_value(sfo, "MAINTITLE"), sfo_get_param_value(sfo, "SUBTITLE")); item = _createSaveEntry(SAVE_FLAG_PS4 | SAVE_FLAG_LOCKED, savePath); item->type = FILE_TYPE_PS4; - + item->dir_name = strdup(dir2->d_name); asprintf(&item->path, "%s%s/", userPath, dir->d_name); asprintf(&item->title_id, "%.9s", dir->d_name); - item->dir_name = strdup(dir2->d_name); - if (apollo_config.account_id == account) + uint64_t* int_data = (uint64_t*) sfo_get_param_value(sfo, "ACCOUNT_ID"); + if (int_data && (apollo_config.account_id == *int_data)) item->flags |= SAVE_FLAG_OWNER; - snprintf(savePath, sizeof(savePath), "%s%s/%s", userPath, dir->d_name, dir2->d_name); - - uint64_t size = 0; - get_file_size(savePath, &size); - item->blocks = size / ORBIS_SAVE_DATA_BLOCK_SIZE; + int_data = (uint64_t*) sfo_get_param_value(sfo, "SAVEDATA_BLOCKS"); + item->blocks = (*int_data); + + sfo_free(sfo); + orbis_SaveUmount(mount); LOG("[%s] F(%X) name '%s'", item->title_id, item->flags, item->name); list_append(list, item); - } closedir(d2); }