Skip to content

About

macOS and Windows app to build PS5 fPKG (.pkg) and .ffpfsc containers from any source. Game folder, archive, or disk image. Pack, unpack, browse a .pkg block-by-block, patch, fake-sign. Verified launching on retail FW 11.60 with kstuff-lite 1.13+.

Topics

Resources

Stars

70 stars

Watchers

0 watching

Forks

Latest commit

 

History

320 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PS5 UltraPack

Sources on the left, the steps of a job in the middle, the output formats on the right, the tools below

A desktop app for macOS and Windows that packs, converts, patches, backports and signs PS5 games, builds installable .pkg files, and checks and fixes PS4 and PS5 packages. You add a game folder, an archive, a disk image, a .ffpfs/.ffpfsc or a .pkg, pick what should happen to it and what should come out, and the queue works through it.

The app used to be called PS5 FFPFSC ULTRA.

macOS 26 or newer (Apple Silicon) Windows x64 preview FW 11.60 verified Source MIT Binary GPL-3

If you like what I do, you can buy me a coffee*: Support me on Ko-fi
*It doesn't have to be a big donation. A few cents show me who uses the tool and cares about where it goes next. That keeps me motivated, and I know I'm not coding for the bin ;)


Download

Grab the latest build from Releases.

  • macOS 26 or newer on Apple Silicon (every M1 or later Mac can update to it for free): unzip and start the app. The app is only ad-hoc signed, so if macOS refuses to open it, run this once:
    xattr -dr com.apple.quarantine "PS5 UltraPack.app"
  • Windows x64 (preview): unzip and start PS5 UltraPack.exe. SmartScreen will warn on first start because the exe isn't signed ("More info", then "Run anyway"). Everything works on Windows 11 in my tests, but I haven't tried a package built on Windows on a console yet.

Screenshots

Main window with four jobs in the queue and the details of the selected one

The queue at full width
Queue
Add job: source, changes, output
Add job
Add job with a folder of PS4 and PS5 games, each with its own output folder
A folder with PS4 and PS5 games
Settings, Compression, with the Auto output table
Auto output in Settings
Add job with a PS4 package that carries the default keystone and a merged update
A PS4 package that needs a fix
PS4 PKG Tools with a package, a keystone and one update
PS4 PKG Tools
Add job with a PS5 package and what the checks found
A PS5 package that needs a fix
PS5 PKG Tools with a package that has the default keystone
PS5 PKG Tools
Main window in light mode
Light mode

Older versions of the UI are in docs/screenshots.

What it does

Inputs: a decrypted game folder (eboot.bin + sce_sys/param.json), a folder full of games (one job each), ZIP/RAR/7z archives including multi-part RAR sets and encrypted headers, .exfat/.ffpkg disk images, .ffpfs, .ffpfsc, and PS5 or PS4 .pkg files.

Outputs: .ffpfsc (compressed), .ffpfs (uncompressed, faster to mount), .exfat (an exFAT image with 64 KiB clusters, which ShadowMountPlus reads fastest from USB), an installable .pkg, a plain folder, or "Organize", which files the source into your library as it is. Auto picks one of these per source: you set in Settings › Compression what a game folder, an image or a .pkg turns into, and an archive counts as what it holds.

On the way a job can integrate a patch, backport the game to an older firmware, fake-sign the executables and, for games that load through AMPR, put their data into LZ4 asset packs, in that order. The packs make the game about half the size and are read by drakmor's ampr_emu, which the app puts into fakelib/; "Unpack LZ4" is the way back. All of that happens on a working copy. Your source only changes if you ask for it (signing or backporting a folder in place), and if a patch job on your own folder fails, the patch is rolled back.

Some things that make day-to-day use easier:

  • Archives can go straight in. Saved passwords are tried first, and the app only asks if none of them works. The queue shows what an archive holds (.pkg, Folder, .exfat) instead of .rar. An archive with several games in it is unpacked once and each game gets its own job.
  • A folder with PS4 and PS5 games side by side gives one job each, and the two platforms get their own output folder. Each "Save to" field remembers the folders you last used for that platform.
  • A download folder with one game and a folder of add-ons next to it gives one job. After the game is done, its DLC and updates are unpacked and sorted into the game's title folder in the library, and anything else in the folder is copied next to the output. The add-ons don't show up as jobs of their own.
  • Output files are named from the game itself: <Title> [PPSA12345] [v01.200] [fw8.00].ffpfsc in a folder per title. The firmware tag comes from the SDK version in eboot.bin. Names stay within ShadowMountPlus's length limit.
  • Extras that come with a release (notes, checksums, backport files, DLC folders) don't go into the image, but they aren't thrown away either. They end up next to the output. macOS and Windows junk like .DS_Store, ._* and Thumbs.db is dropped.
  • Work is spread across drives. The image is built on your fast temp SSD and the result is written to the output drive. If the SSD is too small, the app splits the work or falls back to the output drive. A job that won't fit is skipped up front, with the numbers, so it doesn't fail halfway.
  • The queue keeps its order, can be rearranged by drag and drop, and shows overall progress and time left. Failed jobs stay in the list and can be edited and retried. Pause lets the running job finish first.
  • After a job the source can stay, go to the Trash, be moved somewhere or be deleted.

Building .pkg files

The app builds PS5 debug fake packages natively, without Wine or Sony's DLL. It uses drakmor's LibProsperoPkg, wrapped in a small .NET tool that ships with the app.

I've tested this on a retail PS5 on firmware 11.60 with kstuff-lite: both homebrew and a retail game built this way install and launch, and the game keeps its saves. Which firmware a package runs on depends on the jailbreak, not on the builder.

Add job with .pkg as output and More options open

  • Any input can become a .pkg. Content ID, title ID, version and title are read from the game's param.json. If a folder has none, "More options" asks for them.
  • The app fixes common problems in the working copy before building, such as icons in the wrong format, stale DDS files or a PlayGo set that doesn't match the files. A broken param.json or an empty eboot.bin stops the build with a message.
  • Every build is checked afterwards (container, signatures, PlayGo, images, license, NP files, versions, eboot). If something is off, the log tells you which check failed.
  • Compression uses Kraken, level -4 to 9 (default 0). Higher levels take a lot longer for very little gain.
  • It also works the other way round: a .pkg with "Folder" as output unpacks the whole game including sce_sys. Building that folder again gives the same file byte for byte.

Backporting

Add job with Backport to 7.61
Backport in Add job
Settings, Backport and libraries
Settings › Backport & libraries

A backport lowers the SDK version the game declares in eboot.bin and its modules. If the older firmware is missing functions the game uses, the game also needs patched system libraries in its fakelib/ folder, which ShadowMountPlus loads instead of the system ones.

The app does the SDK part itself, also on fake-signed files (only the two SDK values inside the signature change). It doesn't ship any system libraries. You extract them from your own firmware, and the app can apply the public patches for you.

Target Notes
7.61 Public library patches exist. This is the usual route.
6.02 Experimental, smaller patch set, only some games run.
10.xx SDK only, for games slightly newer than the console.
Any firmware in your folder SDK values taken from that firmware's own libraries.

How to set it up:

  1. In Settings › Backport & libraries, point the app at a folder with one subfolder per firmware (7.61, 9.60, 10.01, …), each containing that firmware's original libraries. Each subfolder shows up as a target.
  2. Put your 10.01 libraries in the 10.01 folder, choose an output folder for patched libraries and click Prepare 7.61 or Prepare 6.02. The app downloads the BPS patches from BestPig/BackPork and applies them.
  3. In Add job, Check tells you whether a game runs on the target with a lower SDK alone or needs the patched libraries. Every build runs this check first and stops before touching anything if libraries are missing.

Whether a particular game runs after a backport depends on the game and on the jailbreak's fakelib support.

The same is available on the command line:

python3 backend/cli.py --backport-analyze <game folder> --backport-target 9.60 --fw-libs-root <firmware folder>
python3 backend/cli.py --prepare-backport-libs 7.61 --fw-libs-root <firmware folder> --backport-libs <patched folder>
python3 backend/cli.py <game>.ffpfsc <output folder> --to ffpfsc --backport-target 7.61 --fw-libs-root <firmware folder> --backport-libs <patched folder>

PS4 PKG Tools

A PS4 save holds the keystone of the game that wrote it. A fake package built with a different keystone (most builders use a default one) shows saves of the retail game as corrupted. A full game with an update merged in can have a second problem: if its app version stayed at the game's, the console keeps offering the official update. Add job tells you about both.

PS4 PKG Tools with a package, a keystone and one update

PS4 PKG Tools in the sidebar fix them:

  1. Pick the game package.
  2. Give the keystone of the retail game, or leave the field empty to keep the one the package has. On a jailbroken console, open Apollo Save Tool, pick a save of the game, and either Export Keystone (then fetch /data/apollo/<user id>/<title id>/keystone by FTP and pick the file) or Show Keystone Fingerprint (then type the 64 hex digits).
  3. If the package has the version problem, a Version line shows up. Checked, the job swaps app version and master version in its param.sfo, so the app version is the merged update's.
  4. Check the updates of the game. The tool lists the ones next to the package; add others with Add…. Each update records the package it belongs to, and the job points it at the changed package so it still installs. An update whose saves would go to another folder than the game's gets the game's folder. An update converted from another region is marked, because its language can differ from the game's.
  5. Add to queue and start the queue.

The packages are changed in place, nothing is rebuilt. Everything the job replaces is kept in the app folder under keystone-undo/, and Undo last change puts it back, one run at a time and newest first. A run that is stopped half-way can be undone too.

PS5 PKG Tools

PS5 PKG Tools with a package that has the default keystone

PS5 PKG Tools in the sidebar check a PS5 package without unpacking it. They run the validate checklist (package layout, param.json, PlayGo tables, images, license, executables) and compare the firmware the game needs with the firmware your console runs. They also look at the keystone, at update markers in param.json, for a stray param.sfo, at the checksums of the trophy archives, at the AMPR index of a game that ships the AMPR emulator, and, for an update package, at the game package next to it (the update has to be newer). Each finding says whether the rebuild fixes it. Add job shows the result for a PS5 package too.

The tools build a new package in the output folder and leave the original as it is. The rebuild already puts images, license and PlayGo tables right. On top of that you can:

  • put in the keystone from the game's own dump (its folder, .ffpfsc or .pkg) or from a keystone file, instead of the default keystone a builder makes when the source has none,
  • lower the firmware to the one your console runs,
  • regenerate the PlayGo tables,
  • make it a standalone game, which clears the update-check URL in param.json.

A trophy archive with a wrong checksum gets the right one, and a missing or stale AMPR index is written again. An update package is only checked, since the rebuild is for full games.

The view also has Look inside and Unpack for the package.

Organize

Organize (in the sidebar) cleans up an existing library. Pick a folder and press Scan. You get a list of every game folder, image, package and archive in it with its current and new name. Apply only renames, so it's fast even on a large drive, and Undo last organize puts things back, one Apply at a time.

Each game ends up in one title folder named after the newest version it has. PS4 packages get their own layout with UPDATE and DLC entries. Archives keep their file names. If the app can't tell which game an archive belongs to, it leaves that folder alone and says so.

Look inside

Look inside a .ffpfsc

Look inside opens a .ffpfs, .ffpfsc or .pkg and shows the file tree. You can extract single files or folders without unpacking the whole thing. Only the blocks you need are read and decompressed, so even a 100 GB container opens quickly. Extracted files are identical to the originals. Unpack all as a job puts the whole image into a folder through the queue.

Other bits

  • PlayGo/APR titles: the app detects playgo-chunk.dat, adds the fakelib module and the AMPRIDX3 index, and signs before indexing so the sizes are right.
  • HDR: the HDR flag in param.json is kept in .pkg builds (--fpkg-hdr-flag auto|on|off). python3 backend/cli.py --param-report <folder> lists title ID, version, HDR flag, required system software and SDK version for a whole folder.
  • Fake-sign uses a vendored, pure-Python make_fself. Files that are already signed are skipped, so running it twice is harmless.
  • Block size: images are always packed with 64 KiB PFS blocks. Smaller blocks pass a local check but crash on the console.

Running from source

You need Python 3.10 or newer. This is also the way to run the app on a macOS older than 26: the release builds need macOS 26, but a source run uses whatever your Python is built for. I don't test or support older systems, though.

python3 -m pip install customtkinter pillow tkinterdnd2 py7zr rarfile psutil cryptography
python3 -m pip install ./backend/unrar
python3 PS5_UltraPack.py

The RAR module needs a C++ compiler (Xcode Command Line Tools on macOS). For .pkg features build the fPKG helper once with ./BUILD_PKG_TOOL.sh (needs the .NET SDK 9+) and its OpenSSL with ./BUILD_OPENSSL.sh. Without the bundled 7-Zip, the app uses an installed 7-Zip or falls back to a slower Python path for .7z. AES and Deflate64 ZIPs need 7-Zip in any case.

On Windows, run.bat installs the packages from requirements-build.txt and starts the app. Build the fPKG helper with BUILD_PKG_TOOL.ps1. run.bat doesn't build the RAR module, so RAR needs 7-Zip or WinRAR installed. Windows has a 260-character path limit unless long paths are enabled, so keep temp and output folders short (e.g. D:\ps5).

Building the app

macOS, from the repo root in a virtual environment (the script refuses to run outside one). It builds the fPKG helper first, so it needs the .NET SDK 9+:

python3 -m venv .venv && source .venv/bin/activate
./BUILD_MACOS_APP.sh

This writes dist/PS5 UltraPack.app plus dist/PS5-UltraPack-<version>-macos-arm64.zip and its .sha256. FETCH_7ZIP.sh downloads the pinned 7-Zip binaries for the bundle.

Windows: build the native parts on a Mac first with WIN_PYTHON=<copy of the Windows Python folder> ./BUILD_WINDOWS_PARTS.sh (needs the .NET SDK and mingw-w64). Then run BUILD_WINDOWS_APP.ps1 on Windows. It writes dist\windows\PS5 UltraPack\PS5 UltraPack.exe and the release zip.

Credits

This isn't a fork, but it builds on a lot of other people's work. Thanks to:

  • Bizkut for ps5-ffpfs-cli. backend/cli.py started out as its backend wrapper.
  • PSBrew for MkPFS, which does the PFS images and compression (bundled, 1.0.0).
  • drakmor for LibProsperoPkg 1.2.0, used for building and reading .pkg files. My wrapper is in backend/native/src/ffpfsc-pkg-tool/.
  • The ps5-payload-dev / flatz lineage for make_fself (BSD-3).
  • RARLAB for UnRAR, vendored as C++ source for the RAR module.
  • The authors of ShadowMountPlus and MicroMount, which load the .ffpfsc containers.
  • EchoStretch for kstuff-lite, and Drakmor and ArkSama for the fpkg launch fixes. Without them fPKG on 11.60 wouldn't launch at all.
  • BestPig for the BackPork library patches.
  • drakmor for ampr_emu, whose packer and runtime the LZ4 asset packs use (GPL-3), and Nazky and the other Lazy_AMPR authors for showing what it can do.
  • titoum-be, who got it running on Windows and sent the launcher and build script the Windows version is based on (#1).

Python libraries: customtkinter, py7zr, rarfile, tkinterdnd2, Pillow, psutil, cryptography.

License

The details, including trademark notes, are in NOTICES.md. Short version:

  • My own code (the GUI, the Python wrappers, the C# wrapper around LibProsperoPkg, tests and build scripts) is MIT, see LICENSE.
  • MkPFS 1.0.0 is GPL-3.0-or-later (backend/mkpfs/LICENSE).
  • LibProsperoPkg 1.2.0 is GPL-3.0-or-later (backend/native/LICENSE.LibProsperoPkg).
  • The UnRAR sources are under the UnRAR license: free for extraction, but they may not be used to build a RAR-compatible compressor (backend/unrar/license.txt).
  • ampr_emu's packer (backend/ampr_pack/) and its runtime libSceAmpr.sprx are GPL-3.0 (drakmor).
  • make_fself.py is BSD-3-Clause, attribution in the file header.
  • Bizkut's ps5-ffpfs-cli has no license file. backend/cli.py started from it and has been mostly rewritten. I don't claim a license for what's left of the original code; MIT covers my changes. See NOTICES.md.

Because the compiled app includes MkPFS and LibProsperoPkg, the binaries are distributed as a combined work under GPL-3.0-or-later. Everything needed to rebuild them is in this repo, including the LibProsperoPkg assembly (original and patched, with the patch tooling and a notice in backend/native/src/ffpfsc-pkg-tool/lib/).

Not affiliated with Sony Interactive Entertainment. "PlayStation" and "PS5" are their trademarks and are only used to name the console and formats this tool works with. The app processes files you provide. It doesn't decrypt or distribute any Sony content, firmware, keys or executables, and it's your responsibility to only use it with content you have the right to use (your own game dumps, homebrew you're allowed to redistribute).


If you like what I do, you can buy me a coffee*: Ko-fi

*It doesn't have to be a big donation. A few cents show me who uses the tool and cares about where it goes next. That keeps me motivated, and I know I'm not coding for the bin ;)

About

macOS and Windows app to build PS5 fPKG (.pkg) and .ffpfsc containers from any source. Game folder, archive, or disk image. Pack, unpack, browse a .pkg block-by-block, patch, fake-sign. Verified launching on retail FW 11.60 with kstuff-lite 1.13+.

Topics

Resources

Stars

70 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages