![]() |
|
PS5 PUP Format Reverse Engineered - Breakdown, Tools and 5.50 Analysis - Printable Version +- Sick Gaming (https://sickgaming.net) +-- Forum: Console Gaming (https://sickgaming.net/forum-119.html) +--- Forum: Sony Mods (https://sickgaming.net/forum-26.html) +---- Forum: Jailbreak (https://sickgaming.net/forum-28.html) +---- Thread: PS5 PUP Format Reverse Engineered - Breakdown, Tools and 5.50 Analysis (/thread-113455.html) |
PS5 PUP Format Reverse Engineered - Breakdown, Tools and 5.50 Analysis - SickProdigy - 09-29-2026 PS5 PUP Format Reverse Engineered - Full Breakdown, Tools & 5.50 Analysis
Introduction If you have spent any time in the PS5 scene, you have probably come across .PUP files - Sony's firmware update packages. You may have seen them referenced when discussing firmware versions or noticed decrypted versions shared for research purposes. Outside of a few scattered wiki entries and tool source code, very little has been written about what is inside these files, how the format works, and what the components are. This thread documents the PS5 5.50 Update PUP, including the file format, known component types, inner SELF header structures, and open-source Python tools for extracting and analysing PUP contents. The psdevwiki PS5 PUP page has also been updated with this information. What Is a PUP? PUP stands for PlayStation Update. It is the container Sony uses to deliver firmware updates to the PS5.
The PS5 accepts a PUP at or above the currently installed firmware version. Installing an older version requires applicable exploits. The SLB2 Container Format PUP Header
Entry Structure Each record in the entry table is 48 bytes (0x30).
Every PS5 PUP uses an outer container identified by the magic bytes 53 4C 42 32 at offset 0x00 - the ASCII string "SLB2". The existing psdevwiki page documented the magic bytes and a file table at 0x30. Parsing an actual 5.50 Update PUP made it possible to document the full header layout above. What Is Inside a 5.50 Update PUP The 5.50 Update PUP contains 95 entries across 14 distinct component types. Many entry IDs appear multiple times in the same PUP. This represents primary and backup copies for redundancy and, in some cases, different builds for different hardware revisions. For example, the 5.50 Update PUP contains 11 copies of the GPU microcode entry that are byte-for-byte identical and 5 copies of eap_kernel at differing sizes representing different hardware variants. Files extracted by pup_extract.py are named with the extension .arm64 or .bin. The .arm64 extension is assigned by the extractor's file-type detection heuristic and indicates that the blob passed an ARM64 opcode-density check. This is not a guarantee that the data is plaintext ARM64 code. Encrypted data can pass the same heuristic because of its byte distribution. The .bin extension is assigned to raw binaries, zero-padded blobs, and anything that did not match a known type. Known Entry IDs
The Encryption Situation This is important to understand. A decrypted PUP (.PUP.dec) has had the outer SLB2 container encryption removed. This gives you readable headers: you can parse the entry table, see component names and sizes, and extract each blob to a separate file. However, each individual firmware component uses the PS5 SELF format (ET_SCE_EXEC, type 0xFE00) with its own per-segment AES encryption. The SELF container headers are plaintext. ELF structure, segment layouts, load addresses, and entry points are readable, but the actual code and data in each segment are encrypted with keys specific to that binary and stored in Aeolia's secure storage on the hardware. In practice:
The entropy on every component's segment data is approximately 7.95-7.997 bits per byte, which is indistinguishable from random data and is what would be expected from AES encryption. Inner SELF Headers emc_ipl and smf_ipl - Identical SELF Both emc_ipl and smf_ipl contain the same x86-64 SELF executable. The full 0x4000 bytes of header data are byte-for-byte identical between the two files. The ELF is at different offsets within each outer blob: 0x8D318 in emc_ipl and 0x1C6C8 in smf_ipl. The encrypted wrapper before the SELF differs in size, but the payload inside is the same binary.
Segment layout:
Points of note:
Encrypted Segment Info Table The bytes immediately before the ELF header in emc_ipl contain a structured table describing encrypted segments. Three entries were recoverable from the plaintext region.
The offsets all end in 0x0006, suggesting a consistent alignment or header prefix on each encrypted block. The compression ratios are extreme. Entry 12 has an encrypted size of approximately 630 KB and decrypts to only about 1.2 KB. Entry 14 is approximately 1.2 MB and decrypts to about 20 KB. These figures suggest deliberate padding to obscure the true size of the decrypted contents, which is a known anti-analysis technique. psp_kernel and sio_firmware No ELF was found in either psp_kernel or sio_firmware. Both begin with opaque encrypted data and contain no recognisable container signatures: no SLB2, SELF, BLS, or SEAD. These components either use a format specific to their respective processors or are fully opaque encrypted blobs with no plaintext structural metadata. PS5 Security Architecture - Background The PS5's main game CPU is an AMD Zen 2 x86-64 chip, but it operates under the control of a separate security co-processor called Aeolia. Aeolia is a Sony-designed SoC containing ARM Cortex-A53 cores running a dedicated operating system independently of the main CPU. Aeolia is responsible for:
The eap_kernel entries in the PUP are the operating system running on those A53 cores. emc_ipl is the Aeolia embedded controller firmware. The bios entries boot the main x86-64 system. All of these are encrypted with Aeolia's on-chip keys. The firmware installation phases listed in the update log - emc_salina_c0.bls, titania.bls, and eap_kbl.bin - are early boot-stage components written to flash before the main system starts. The .bls files are Aeolia bootloader stages. Titania is the internal codename for the PS5's Aeolia chip revision. Update Index Order This is the firmware flashing sequence observed during a PS5 firmware update and documented from installation logs. Numbers in parentheses are the internal phase indices. Code: [INFO] writing system firmware phase 1 (18) usb_pdc_salina_c0.bls
[INFO] writing system firmware phase 2 (16) emc_salina_c0.bls
[INFO] writing system firmware phase 3 (11) titania.bls
[INFO] writing system firmware phase 4 (14) eap_kbl.bin
[INFO] writing system firmware phase 5 (4) mbr.bin
[INFO] writing system firmware phase 6 (259) oberon_sec_ldr_c0.bin
[INFO] writing system firmware phase 7 (5) kernel.bin
--- reboots here ---
[INFO] writing system firmware phase 8 (513) wlanbt.bin
[INFO] writing system firmware phase 9 (515) ssd0.system_b
[INFO] writing system firmware phase 10 (516) ssd0.system_ex_b
[INFO] writing system firmware phase 11 (519) ssd0.preinst
--- mounts system: nmount /dev/ssd0.system_b to /update/mnt/system ---
[INFO] writing system firmware phase 12 (2000) bluray.binPhases 8, 9, 10, and 12 cannot be decrypted with current public tools. The Tools Two Python scripts can be downloaded below. Both require Python 3.8 or above. The capstone library is an optional dependency for the analyser. Install it with: Code: pip install capstonepup_extract.py Parses the SLB2 header, lists all entries with their IDs, names, sizes, offsets, and detected file types, then extracts every component to an extracted/ subfolder. It also outputs a full entries.csv manifest and pup_header_hex.txt for manual inspection. Place the script in the same folder as your PS5UPDATE1.PUP.dec file and run: Code: python pup_extract.pyOutput: Code: extracted/ All components, named by index and type
entries.csv Full manifest with offsets, sizes, SHA-256 partial hashes, and detected file types
pup_header_hex.txt First 8 KB of the PUP header as a hex dumpThe script has three fallback strategies for non-standard header layouts:
analyse_extracted.py Scans the extracted/ folder produced by pup_extract.py, scores each file for ARM64 code density, checks known reference offsets, and attempts to identify firmware structure. It is designed for hardware-decrypted firmware dumps. Run it from the same folder: Code: python analyse_extracted.pyThe script outputs analysis_report.txt with per-file findings. What This Adds to Community Knowledge Before this research, the psdevwiki PS5 PUP page documented only the SLB2 magic bytes and a firmware installation log. This thread adds:
If you have additional entry IDs, sizes from other firmware versions, or corrections to anything here, post them below. Downloads: Mega + Mirror |