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

> Understand how CMD_RESIGN_SAVE in Apollo Save Tool works. It patches param.sfo with account details and applies cheat modifications to your PS4 save data.

- Repository: [Damián Parrino/apollo-ps4](https://github.com/bucanero/apollo-ps4)
- Tags: internals
- Published: 2026-02-26

---

**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`](https://github.com/bucanero/apollo-ps4/blob/main/include/saves.h). This command orchestrates the complete resigning workflow implemented in [`source/exec_cmd.c`](https://github.com/bucanero/apollo-ps4/blob/main/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`](https://github.com/bucanero/apollo-ps4/blob/main/source/exec_cmd.c) at approximately line 1852, where the command dispatcher handles the `CMD_RESIGN_SAVE` case:

```c
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`](https://github.com/bucanero/apollo-ps4/blob/main/source/exec_cmd.c)), the function constructs an `sfo_patch_t` structure populated with the running user's credentials:

```c
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`](https://github.com/bucanero/apollo-ps4/blob/main/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`](https://github.com/bucanero/apollo-ps4/blob/main/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:

```c
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`](https://github.com/bucanero/apollo-ps4/blob/main/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`](https://github.com/bucanero/apollo-ps4/blob/main/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`](https://github.com/bucanero/apollo-ps4/blob/main/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`](https://github.com/bucanero/apollo-ps4/blob/main/source/psv_resign.c) |
| `apply_cheat_patch_code()` | Parses individual cheat scripts and applies memory/file patches. | [`source/patch.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/patch.c) |

The command constant `CMD_RESIGN_SAVE` is declared in [`include/saves.h`](https://github.com/bucanero/apollo-ps4/blob/main/include/saves.h) (around line 84) and wired to the UI menu in [`source/saves.c`](https://github.com/bucanero/apollo-ps4/blob/main/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:

```c
/* 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`](https://github.com/bucanero/apollo-ps4/blob/main/source/saves.c) where the menu entry triggers the same command dispatch logic found in [`source/exec_cmd.c`](https://github.com/bucanero/apollo-ps4/blob/main/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`](https://github.com/bucanero/apollo-ps4/blob/main/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`](https://github.com/bucanero/apollo-ps4/blob/main/source/exec_cmd.c), with low-level SFO manipulation in [`source/psv_resign.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/psv_resign.c) and cheat application in [`source/patch.c`](https://github.com/bucanero/apollo-ps4/blob/main/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`](https://github.com/bucanero/apollo-ps4/blob/main/include/saves.h) and implemented in [`source/exec_cmd.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/exec_cmd.c).

### Where is the resignSave() function implemented?

The `resignSave()` function is implemented in [`source/exec_cmd.c`](https://github.com/bucanero/apollo-ps4/blob/main/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`](https://github.com/bucanero/apollo-ps4/blob/main/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`](https://github.com/bucanero/apollo-ps4/blob/main/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`](https://github.com/bucanero/apollo-ps4/blob/main/source/saves.c) and executes the same logic in [`source/exec_cmd.c`](https://github.com/bucanero/apollo-ps4/blob/main/source/exec_cmd.c) that handles SFO and cheat patching.