How the PS4 Save Resigning Process Works in Apollo Save Tool: CMD_RESIGN_SAVE Explained

The CMD_RESIGN_SAVE command in Apollo Save Tool executes a two-step workflow that patches the save's param.sfo with current account credentials and applies any active cheat modifications to the save data files.

When a user selects "Apply Changes & Resign" for a PlayStation 4 save within the Apollo Save Tool, the application triggers the CMD_RESIGN_SAVE command defined in include/saves.h. This command orchestrates the complete resigning workflow implemented in source/exec_cmd.c, ensuring the save file is re-signed to the current user's account while preserving any modifications selected through the cheat interface.

Overview of the CMD_RESIGN_SAVE Workflow

The resigning process follows a strict execution path designed to maintain save integrity while updating ownership metadata. According to the source code in bucanero/apollo-ps4, the workflow consists of two primary stages:

  1. SFO Patching – Updates the save's param.sfo file with the current account credentials (user ID, PSID, account ID) and processes any SFO-related cheat codes the user activated.
  2. Cheat Patching – Applies active GameGenie, BSD, or Python cheat files to the save's data files.

If both stages complete successfully, the UI displays a confirmation message. If either stage fails, the process logs the error and returns control to the UI with an appropriate failure notification.

Step-by-Step Execution Flow

Command Dispatch

The process begins in source/exec_cmd.c at approximately line 1852, where the command dispatcher handles the CMD_RESIGN_SAVE case:

case CMD_RESIGN_SAVE:
    resignSave(selected_entry);
    break;

The dispatcher routes the UI-generated command to the resignSave() helper function, passing a pointer to the currently selected save_entry_t structure containing the save's metadata and file paths.

Building the Patch Structure

Inside resignSave() (starting at line 1542 in source/exec_cmd.c), the function constructs an sfo_patch_t structure populated with the running user's credentials:

sfo_patch_t patch = {
    .user_id = apollo_config.user_id,
    .psid = apollo_config.psid,
    .account_id = apollo_config.account_id
};

This structure serves as the instruction set for the SFO patcher, defining exactly which values to write into the save's param.sfo file.

Applying SFO Patches

The function then calls apply_sfo_patches(entry, &patch) at lines 1554-1555. This routine:

  • Iterates through the save's codes list seeking items of type PATCH_SFO that the user enabled
  • Processes specific SFO opcodes including SFO_CHANGE_ACCOUNT_ID, SFO_REMOVE_PSID, and SFO_CHANGE_TITLE_ID
  • Updates the patch structure fields based on active cheat codes
  • Renames the save's directory if the title ID changes
  • Calls patch_sfo() on sce_sys/param.sfo to write the changes

The low-level SFO manipulation occurs in source/psv_resign.c within the patch_sfo() function, which opens the binary SFO file, modifies the specified fields, and writes the updated structure back to disk.

Applying Cheat Patches

Following SFO processing, apply_cheat_patches(entry) executes at lines 1558-1559. This function:

  • Scans the codes list for active entries of type PATCH_GAMEGENIE, PATCH_BSD, or PATCH_PYTHON
  • Resolves file paths handling wildcards and ~extracted shortcuts
  • Invokes apply_cheat_patch_code() for each active cheat

The actual cheat application logic resides in source/patch.c, where apply_cheat_patch_code() parses the cheat script format and applies the modifications to the target save data files. Errors during this process are logged but do not halt execution; the function continues processing remaining cheats.

User Feedback

Upon completion of both stages (lines 1561-1562), the function displays:

show_message(_("Save %s successfully modified!"), entry->title_id);

If either the SFO or cheat patching stage fails, an error toast appears instead, though control returns to the UI in either case.

Core Functions and File Locations

Function Description Location
resignSave() Orchestrates the complete resigning workflow for a single save. source/exec_cmd.c (line ~1542)
apply_sfo_patches() Parses active SFO commands and writes credentials to param.sfo. Handles account ID changes, PSID removal, and title ID renaming. source/exec_cmd.c (line ~1554)
apply_cheat_patches() Executes all active cheat scripts (GameGenie, BSD, Python) against save data files. source/exec_cmd.c (line ~1558)
patch_sfo() Low-level routine that opens, modifies, and writes the binary SFO file format. source/psv_resign.c
apply_cheat_patch_code() Parses individual cheat scripts and applies memory/file patches. source/patch.c

The command constant CMD_RESIGN_SAVE is declared in include/saves.h (around line 84) and wired to the UI menu in source/saves.c (around line 371).

Programmatically Triggering CMD_RESIGN_SAVE

While typically invoked through the UI, developers can trigger the resigning process programmatically by constructing the command structure manually:

/* Assume selected_save points to a populated save_entry_t */
code_entry_t *cmd = _createCmdCode(PATCH_COMMAND,
                                  CHAR_ICON_SIGN " ",
                                  _("Apply Changes & Resign"),
                                  CMD_RESIGN_SAVE);

/* Invoke the command handler directly */
execCodeCommand(cmd, (char[]){ CMD_RESIGN_SAVE, 0 });
/* UI will display "Save <title_id> successfully modified!" */

This mirrors the internal UI flow defined in source/saves.c where the menu entry triggers the same command dispatch logic found in source/exec_cmd.c.

Summary

  • The PS4 save resigning process in Apollo Save Tool centers on the CMD_RESIGN_SAVE command, dispatched from source/exec_cmd.c.
  • The workflow executes two distinct phases: SFO patching (updating param.sfo with current account credentials via apply_sfo_patches()) and cheat patching (applying GameGenie/BSD/Python modifications via apply_cheat_patches()).
  • Core functions reside in source/exec_cmd.c, with low-level SFO manipulation in source/psv_resign.c and cheat application in source/patch.c.
  • Successful completion updates the save ownership to the current user while preserving all selected modifications, confirmed via a UI success message.

Frequently Asked Questions

What does the CMD_RESIGN_SAVE command do in Apollo Save Tool?

The CMD_RESIGN_SAVE command triggers the complete save modification workflow in Apollo Save Tool. It re-signs a PS4 save to the current user's account by updating the param.sfo file with new credentials (user ID, PSID, and account ID) while simultaneously applying any active cheat codes selected by the user. The command is defined in include/saves.h and implemented in source/exec_cmd.c.

Where is the resignSave() function implemented?

The resignSave() function is implemented in source/exec_cmd.c starting at approximately line 1542. This function serves as the primary orchestrator for the resigning process, constructing the sfo_patch_t structure with current user credentials and sequentially calling apply_sfo_patches() and apply_cheat_patches() to complete the modification workflow.

How does Apollo Save Tool handle SFO patching during resigning?

During the resigning process, Apollo Save Tool handles SFO patching through the apply_sfo_patches() function in source/exec_cmd.c. This function iterates through active cheat codes of type PATCH_SFO, processes specific opcodes like SFO_CHANGE_ACCOUNT_ID and SFO_REMOVE_PSID, updates the sfo_patch_t structure accordingly, and calls patch_sfo() from source/psv_resign.c to write the changes to sce_sys/param.sfo. It also handles directory renaming if the title ID changes.

Can I trigger the save resigning process programmatically?

Yes, developers can trigger the save resigning process programmatically by constructing a code_entry_t command structure with CMD_RESIGN_SAVE and invoking execCodeCommand(). This requires creating the command using _createCmdCode() with PATCH_COMMAND type and the CMD_RESIGN_SAVE identifier, then passing it to the command executor. This programmatic approach mirrors the UI flow defined in source/saves.c and executes the same logic in source/exec_cmd.c that handles SFO and cheat patching.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →