Archive of https://github.com/zecoxao/bar — backup and restore utility
  • C 85.5%
  • Python 7.8%
  • C++ 5.8%
  • CMake 0.9%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
zecoxao 38de675640 ci: fix Linux AppImage naming + macOS Qt (use Homebrew, avoid AGL)
- Package (Linux) failed because linuxdeploy names the AppImage from the
  desktop Name (p4br), not the executable; set OUTPUT so it is written as
  p4br-qt-<os>.AppImage, add APPIMAGE_EXTRACT_AND_RUN=1 (no FUSE on runners)
  and QMAKE. Validated end-to-end in a local Linux container.
- macOS Build failed at link with 'framework AGL not found' (the aqtinstall Qt
  references the removed AGL framework); install Qt from Homebrew on macOS,
  which is built against the current SDK.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-10-11 23:00:05 +01:00
.github/workflows ci: fix Linux AppImage naming + macOS Qt (use Homebrew, avoid AGL) 2026-10-11 23:00:05 +01:00
packaging Make the cores portable, add a cross-platform Qt 6 GUI, CMake and CI 2026-10-11 22:38:16 +01:00
qt Fix Linux/macOS build: include <stdarg.h> and <cstring> 2026-10-11 22:53:25 +01:00
.gitattributes Make the cores portable, add a cross-platform Qt 6 GUI, CMake and CI 2026-10-11 22:38:16 +01:00
.gitignore Make the cores portable, add a cross-platform Qt 6 GUI, CMake and CI 2026-10-11 22:38:16 +01:00
bar_crypto.h Make the cores portable, add a cross-platform Qt 6 GUI, CMake and CI 2026-10-11 22:38:16 +01:00
bar_platform.h Make the cores portable, add a cross-platform Qt 6 GUI, CMake and CI 2026-10-11 22:38:16 +01:00
CMakeLists.txt Make the cores portable, add a cross-platform Qt 6 GUI, CMake and CI 2026-10-11 22:38:16 +01:00
p4br_create.c Fix Linux/macOS build: include <stdarg.h> and <cstring> 2026-10-11 22:53:25 +01:00
p4br_create_gui.c Auto-extract a backup source + emit in template catalog order 2026-10-11 19:15:39 +01:00
p4br_create_gui.exe Auto-extract a backup source + emit in template catalog order 2026-10-11 19:15:39 +01:00
p4br_extract.c Fix Linux/macOS build: include <stdarg.h> and <cstring> 2026-10-11 22:53:25 +01:00
p4br_extract.exe Add obligatory HMAC-SHA256 verification to CLI and GUI 2026-10-09 15:41:15 +01:00
p4br_extract.py Add obligatory HMAC-SHA256 verification to CLI and GUI 2026-10-09 15:41:15 +01:00
p4br_extract_gui.c Add obligatory HMAC-SHA256 verification to CLI and GUI 2026-10-09 15:41:15 +01:00
p4br_extract_gui.exe Add obligatory HMAC-SHA256 verification to CLI and GUI 2026-10-09 15:41:15 +01:00
README.md Make the cores portable, add a cross-platform Qt 6 GUI, CMake and CI 2026-10-11 22:38:16 +01:00
seg3_codec.py Finish the creator: generate seg3 registry + aux, template + settings overlay 2026-10-10 18:44:30 +01:00

bar — PS4 "Back Up PS4" (SCECAF / P4BR) tools

Extract and create PS4 USB backups (archive.dat [+ archiveNNNN.dat ...]), in C (with a Win32 GUI) and Python.

A PS4 backup is a SCECAF container wrapping a file-level P4BR archive (not a disk image): a header + segment table, AES-128-CBC segment encryption (with a ciphertext-stealing tail) and HMAC-SHA256 per-segment / header signatures. Decrypted segment order:

seg0  P4BR header (names, dir/file counts, OpenPSID, hardware, version)
seg1  directory records (0x458 each)
seg2  file records      (0x458 each)
seg3  system registry   (0x64600)   ] aux metadata
seg4  reboot data                   ]
seg5  sparse count                  ]
seg6+ file payload, one segment per file, tight-packed in catalog order

Tools

file what it does
p4br_extract.c portable CLI extractor (Windows/Linux/macOS; HMAC-verify, --list, include/exclude, manifest)
p4br_create.c portable CLI creator (folder → restorable-shaped backup; skeleton/template/keyset)
qt/ cross-platform Qt 6 GUI (p4br-qt) with Extract + Create tabs
bar_crypto.h / bar_platform.h shared portable crypto (AES-NI + software fallback) + OS layer
p4br_extract.py / seg3_codec.py Python reference extractor + seg3 registry codec/validator
p4br_extract_gui.c / p4br_create_gui.c original Windows-only Win32 GUIs (superseded by qt/)

seg3 = the PS4 system registry

seg3 is the output of the kernel registry backup (sceRegMgrBackupPullData, regmgr syscall). It was fully reverse-engineered from the kernel: the 0x64600 blob is a plaintext registry (header + a 16-byte descriptor per key + a value/data area + padding) transformed by a deterministic XOR obfuscation and custom checksums with no per-console or SAMU secret. seg3_codec.py reproduces it byte-for-byte (verified against real 5.05 and 9.x backups), so registry values can be decoded, edited and re-encoded offline.

Creating a backup

p4br_create <source_folder> [-o out] [-n name] [-l label] [--verify true|false]
            [-t template_archive.dat]
            [--set-user NAME] [--set-hostname NAME]
            [--openpsid 32HEX] [--set KEYIDHEX=STRING] ...
p4br_create            (no args → GUI)

A backup's seg3 is the whole PS4 registry, seg0 holds the registered accounts / OpenPSID, and seg4 is reboot-state — all live console state that isn't in firmware. Capture it once from any real backup of your console, then create backups from just the files:

p4br_create --make-skeleton  "X:\PS4\EXPORT\BACKUP\…\archive.dat"
            -> writes  <exe dir>\p4br_skeleton\archive.dat

p4br_create  ./my_files  -o ./out  --set-user NAME --set-hostname NAME
            -> uses the bundled skeleton automatically; no template needed

In the GUI: click Make skeleton from a backup… once, then just pick a Source folder and Create (identity fields auto-fill from the skeleton and stay editable). The output keeps the skeleton console's OpenPSID / hardware, so it restores to that console.

What the Source must be

The Source is the file tree to back up — a folder holding user/ and/or system_data/ subfolders. It is not a backup folder and not an archive.dat. As a convenience, if you do point it at a backup (a folder containing archive.dat, or an archive.dat itself), the tool detects it and auto-extracts that backup's real file tree first, then rebuilds from it — so re-packing a backup reproduces its exact catalog instead of packing one bogus /archive.dat. To edit files, extract a backup (p4br_extract <backup> -o work), change files under work/user/ or work/system_data/, then Source = work.

Catalog order matters: when a template or the bundled skeleton is present, dirs/files are emitted in the template's exact catalog order (payloads follow file order), and new files you added are appended last. A re-pack of an unchanged backup then comes out plaintext-identical to the original (only the per-segment IVs differ), i.e. structurally a known-good backup.

Explicit template / no aux

  • Without -t and no skeleton: packs the folder into a valid SCECAF/P4BR container that round-trips through p4br_extract (no aux — not restorable).
  • With -t <template archive.dat>: also writes the aux segments. seg3 (registry), seg4 and seg5 are taken from the template, and the P4BR header (OpenPSID / hardware / version / GUID) is kept from it, producing a restorable-shaped backup. The registry in seg3 is decoded, your overrides are applied, and it is re-encoded:
    • --set-user NAME → local user name (registry key 0x07800200)
    • --set-hostname NAME → console name (0x02050000)
    • --openpsid 32HEX → P4BR header + registry header OpenPSID
    • --set KEYIDHEX=STRING→ any string registry key (repeatable)

A real PS4 restore validates OpenPSID, so the template's registry / OpenPSID must match the target console. Make the template on that console, or override with --openpsid. Value sizes are fixed by the registry schema (a string can't exceed its key's slot size).

The output is sealed with the same keyset as the template (auto-detected). A console can only validate its own keyset — e.g. a 5.05 unit uses the OLD keyset, and a mismatched keyset restores as DATA_CORRUPTED (CE-33310-0 / 0x81300203). Force it with --keyset old|new if needed.

Example:

p4br_create ./my_user_tree -o ./out -t /path/CONSOLE/archive.dat \
    --set-user Alice --set-hostname PS4-ALICE

Build (Windows / Linux / macOS)

The portable CLIs and the Qt 6 GUI build with CMake. Prebuilt archives for all three platforms (GUI p4br-qt + p4br_extract + p4br_create) are attached to each release.

cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=/path/to/Qt/6.x/<kit>
cmake --build build
# -> build/p4br_extract, build/p4br_create (CLIs) and build/p4br-qt (GUI)

If Qt 6 is not found, the two CLIs still build. On x86 CMake adds -maes -msse4.1 for the AES-NI path; AES-NI is used only when the CPU advertises it, with a pure-software fallback (so the same binary runs on CPUs without it, and on ARM / Apple Silicon the intrinsics are compiled out entirely).

The GUI reuses the portable cores unchanged: qt/extract_bridge.c and qt/create_bridge.c compile p4br_extract.c / p4br_create.c with their *_GUI macro and expose a small C API (qt/bar_bridge.h) to the Qt C++ UI.

CLI only (no Qt)

cc -O3 p4br_extract.c -o p4br_extract        # add -maes -msse4.1 on x86
cc -O3 p4br_create.c  -o p4br_create -lpthread

Python tools need pycryptodome (py -m pip install pycryptodome), e.g. python seg3_codec.py <archive.dat> runs a decode→encode round-trip self-check.

Keys

The AES cipher key and the HMAC key are built into the C sources and the Python scripts (new and old keysets); pass -k / -H to override. They are not listed here.