Category PS4 CFW and Hacks       Thread starter PSXHAX       Start date Feb 28, 2019 at 8:22 AM       8,751       23            
Previously we've seen guides on How to Obtain Your PS4 SFlash alongside some example file dumps, and today developer @zecoxao shared on Twitter SFlash0Unpack which is a script to unpack sflash0 files from PS4 flash dumps for PlayStation 4 scene devs to examine.

In related news, pearlxcore (Twitter) also made available a PS4 Dump Extractor utilized to extract PlayStation 4 dumps including sflash0 files. :tup:

Download: sflash0unpack-master.zip / GIT / ps4_sflash0_pack_tool.py / GIT / PS4.Dump.Extractor.exe / PS4 Dump Extractor GIT

Below is main.c from Github followed by the makefile, with a Python version of the PS4 Sflash0 Pack Tool from @SocraticBliss (Twitter) on Github for those interested and also a extractor.pl Perl version from BwE! :ninja:

Main.c:
Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <inttypes.h>
#include <sys/stat.h>

/*
   0x0 <- Header (0x1000)
   0x1000 <- Unk (0x1000)
   0x2000 <- MBR1 (0x1000) (for sflash0s1.cryptx3b)
   0x3000 <- MBR2 (0x1000) (for sflash0s1.cryptx3)
   0x4000 <- sflash0s0x32b (emc_ipl) (0x60000)
   0x64000 <- sflash0s0x32 (emc_ipl) (0x60000)
   0xC4000 <- sflash0s0x33 (eap_kbl) (0x80000)
   0x144000 <- sflash0s0x34 (wifi fw) (0x80000)
   0x1C4000 <- sflash0s0x38 (nvs) (0xC000)
   0x1D0000 <- sflash0s0x0 (blank1) (0x30000)
   0x200000 <- Header2 (0x1000)
   0x201000 <- Unk 2(0x1000)
   0x202000 <- MBR3(0x1000) (for sflash0s1.cryptx2b)
   0x203000 <- MBR4(0x1000) (for sflash0s1.cryptx2)
   0x204000 <- sflash0s1.cryptx2b (sam_ipl/secure loader) (0x3E000)
   0x242000 <- sflash0s1.cryptx2 (sam_ipl/secure loader) (0x3E000)
   0x280000 <- sflash0s1.cryptx1 (idata) (0x80000)
   0x300000 <- sflash0s1.cryptx39 (bd_hrl?) (0x80000)
   0x380000 <- sflash0s1.cryptx6 (Virtual TRM) (0x40000)
   0x3C0000 <- sflash0s1.cryptx3b (secure kernel, secure modules) (0xCC0000)
   0x1080000 <- sflash0s1.cryptx3 (secure kernel, secure modules) (0xCC0000)
   0x1D40000 <- sflash0s1.cryptx40 (blank2) (0x2C0000)
*/

typedef struct
{
   unsigned char header[0x1000];
   unsigned char unk[0x1000];
   unsigned char mbr1[0x1000];
   unsigned char mbr2[0x1000];
   unsigned char emc_iplb[0x60000];
   unsigned char emc_ipl[0x60000];
   unsigned char eap_kbl[0x80000];
   unsigned char wifi_fw[0x80000];
   unsigned char nvs[0xC000];
   unsigned char blank[0x30000];
   unsigned char header2[0x1000];
   unsigned char unk2[0x1000];
   unsigned char mbr3[0x1000];
   unsigned char mbr4[0x1000];
   unsigned char sam_iplb[0x3E000];
   unsigned char sam_ipl[0x3E000];
   unsigned char idata[0x80000];
   unsigned char bd_hrl[0x80000];
   unsigned char vtrm[0x40000];
   unsigned char secureb[0xCC0000];
   unsigned char secure[0xCC0000];
   unsigned char blank2[0x2C0000];
} SFLASH0;

int main(int argc, char **argv){
 
   if(argc != 3){
       printf ("\nusage: sflash0unpack [sflash0] [outdir]  \n");
       return -1;
   }
 
   unsigned char out[256];
 
   mkdir(argv[2],0777);
 
   FILE *fp = fopen(argv[1],"rb");
 
   unsigned char *buf = (unsigned char*) malloc (0x2000000);
 
   fread(buf,0x2000000,1,fp);
 
   SFLASH0* entries = (SFLASH0*)buf;
 
   sprintf(out,"%s/header.bin",argv[2]);
 
   FILE *fl = fopen(out,"wb");
 
   fwrite(entries->header,sizeof(entries->header),1,fl);
 
   fclose(fl);
 
   sprintf(out,"%s/emc_ipl.bin",argv[2]);
 
   fl = fopen(out,"wb");
 
   fwrite(entries->emc_ipl,sizeof(entries->emc_ipl),1,fl);
 
   fclose(fl);
 
   sprintf(out,"%s/emc_iplb.bin",argv[2]);
 
   fl = fopen(out,"wb");
 
   fwrite(entries->emc_iplb,sizeof(entries->emc_iplb),1,fl);
 
   fclose(fl);
 
   sprintf(out,"%s/eap_kbl.bin",argv[2]);
 
   fl = fopen(out,"wb");
 
   fwrite(entries->eap_kbl,sizeof(entries->eap_kbl),1,fl);
 
   fclose(fl);
 
   sprintf(out,"%s/wifi_fw.bin",argv[2]);
 
   fl = fopen(out,"wb");
 
   fwrite(entries->wifi_fw,sizeof(entries->wifi_fw),1,fl);
 
   fclose(fl);
 
   sprintf(out,"%s/sam_ipl.bin",argv[2]);
 
   fl = fopen(out,"wb");
 
   fwrite(entries->sam_ipl,sizeof(entries->sam_ipl),1,fl);
 
   fclose(fl);
 
   sprintf(out,"%s/sam_iplb.bin",argv[2]);
 
   fl = fopen(out,"wb");
 
   fwrite(entries->sam_iplb,sizeof(entries->sam_iplb),1,fl);
 
   fclose(fl);
 
   sprintf(out,"%s/idata.bin",argv[2]);
 
   fl = fopen(out,"wb");
 
   fwrite(entries->idata,sizeof(entries->idata),1,fl);
 
   fclose(fl);
 
   sprintf(out,"%s/bd_hrl.bin",argv[2]);
 
   fl = fopen(out,"wb");
 
   fwrite(entries->bd_hrl,sizeof(entries->bd_hrl),1,fl);
 
   fclose(fl);
 
   sprintf(out,"%s/vtrm.bin",argv[2]);
 
   fl = fopen(out,"wb");
 
   fwrite(entries->vtrm,sizeof(entries->vtrm),1,fl);
 
   fclose(fl);
 
   sprintf(out,"%s/secure.bin",argv[2]);
 
   fl = fopen(out,"wb");
 
   fwrite(entries->secure,sizeof(entries->secure),1,fl);
 
   fclose(fl);
 
   sprintf(out,"%s/secureb.bin",argv[2]);
 
   fl = fopen(out,"wb");
 
   fwrite(entries->secureb,sizeof(entries->secureb),1,fl);
 
   fclose(fl);
 
   sprintf(out,"%s/blank.bin",argv[2]);
 
   fl = fopen(out,"wb");
 
   fwrite(entries->blank,sizeof(entries->blank),1,fl);
 
   fclose(fl);
 
   sprintf(out,"%s/nvs.bin",argv[2]);
 
   fl = fopen(out,"wb");
 
   fwrite(entries->nvs,sizeof(entries->nvs),1,fl);
 
   fclose(fl);
 
   sprintf(out,"%s/unk.bin",argv[2]);
 
   fl = fopen(out,"wb");
 
   fwrite(entries->unk,sizeof(entries->unk),1,fl);
 
   fclose(fl);
 
   sprintf(out,"%s/mbr1.bin",argv[2]);
 
   fl = fopen(out,"wb");
 
   fwrite(entries->mbr1,sizeof(entries->mbr1),1,fl);
 
   fclose(fl);
 
   sprintf(out,"%s/mbr2.bin",argv[2]);
 
   fl = fopen(out,"wb");
 
   fwrite(entries->mbr2,sizeof(entries->mbr2),1,fl);
 
   fclose(fl);
 
   sprintf(out,"%s/unk2.bin",argv[2]);
 
   fl = fopen(out,"wb");
 
   fwrite(entries->unk2,sizeof(entries->unk2),1,fl);
 
   fclose(fl);
 
   sprintf(out,"%s/mbr3.bin",argv[2]);
 
   fl = fopen(out,"wb");
 
   fwrite(entries->mbr3,sizeof(entries->mbr3),1,fl);
 
   fclose(fl);
 
   sprintf(out,"%s/mbr4.bin",argv[2]);
 
   fl = fopen(out,"wb");
 
   fwrite(entries->mbr4,sizeof(entries->mbr4),1,fl);
 
   fclose(fl);
 
   sprintf(out,"%s/header2.bin",argv[2]);
 
   fl = fopen(out,"wb");
 
   fwrite(entries->header2,sizeof(entries->header2),1,fl);
 
   fclose(fl);
 
   sprintf(out,"%s/blank2.bin",argv[2]);
 
   fl = fopen(out,"wb");
 
   fwrite(entries->blank2,sizeof(entries->blank2),1,fl);
 
   fclose(fl);
 
   fclose(fp);
 
 
   return 0;
}
:idea: To find out (and document) the minimum version of your PS4, download with ftp buf 0x200 payload the file /dev/sflash0s1.cryptx1 (size 512KB) at 0x10008 you can find the minver (endian swapped) next to the SMI header
ps4_sflash0_pack_tool.py
Code:
# PS4 Sflash0 Pack Tool
# SocraticBliss (R)
# Thanks to zecoxao <3

import os
import sys

'''
   Offsets
 
   0x0       <- Header (0x1000)
   0x1000    <- Unk    (0x1000)
   0x2000    <- MBR1   (for sflash0s1.cryptx3b) (0x1000)
   0x3000    <- MBR2   (for sflash0s1.cryptx3) (0x1000)
   0x4000    <- sflash0s0x32b (emc_ipl) (0x60000)
   0x64000   <- sflash0s0x32  (emc_ipl) (0x60000)
   0xC4000   <- sflash0s0x33  (eap_kbl) (0x80000)
   0x144000  <- sflash0s0x34  (wifi fw) (0x80000)
   0x1C4000  <- sflash0s0x38  (nvs) (0xC000)
   0x1D0000  <- sflash0s0x0   (blank) (0x30000)
   0x200000  <- Header2 (0x1000)
   0x201000  <- Unk2    (0x1000)
   0x202000  <- MBR3    (for sflash0s1.cryptx2b) (0x1000)
   0x203000  <- MBR4    (for sflash0s1.cryptx2) (0x1000)
   0x204000  <- sflash0s1.cryptx2b (sam_ipl/secure loader) (0x3E000)
   0x242000  <- sflash0s1.cryptx2  (sam_ipl/secure loader) (0x3E000)
   0x280000  <- sflash0s1.cryptx1  (idata) (0x80000)
   0x300000  <- sflash0s1.cryptx39 (bd_hrl?) (0x80000)
   0x380000  <- sflash0s1.cryptx6  (Virtual TRM) (0x40000)
   0x3C0000  <- sflash0s1.cryptx3b (secure kernel, secure modules) (0xCC0000)
   0x1080000 <- sflash0s1.cryptx3  (secure kernel, secure modules) (0xCC0000)
   0x1D40000 <- sflash0s1.cryptx40 (blank2) (0x2C0000)
'''

SFLASH0 = [
   ('header.bin',   0x0,       0x1000),
   ('unknown.bin',  0x1000,    0x1000),
   ('mbr1.bin',     0x2000,    0x1000),
   ('mbr2.bin',     0x3000,    0x1000),
   ('emc_iplb.bin', 0x4000,    0x60000),
   ('emc_ipl.bin',  0x64000,   0x60000),
   ('eap_kbl.bin',  0xC4000,   0x80000),
   ('wifi_fw.bin',  0x144000,  0x80000),
   ('nvs.bin',      0x1C4000,  0xC000),
   ('blank.bin',    0x1D0000,  0x30000),
   ('header2.bin',  0x200000,  0x1000),
   ('unknown2.bin', 0x201000,  0x1000),
   ('mbr3.bin',     0x202000,  0x1000),
   ('mbr4.bin',     0x203000,  0x1000),
   ('sam_iplb.bin', 0x204000,  0x3E000),
   ('sam_ipl.bin',  0x242000,  0x3E000),
   ('idata.bin',    0x280000,  0x80000),
   ('bd_hrl.bin',   0x300000,  0x80000),
   ('vtrm.bin',     0x380000,  0x40000),
   ('secureb.bin',  0x3C0000,  0xCC0000),
   ('secure.bin',   0x1080000, 0xCC0000),
   ('blank2.bin',   0x1D40000, 0x2C0000),
]

# Unpack entries from a Sflash0 binary...
def unpack(file, dir):

   with open(file, 'rb') as input:
       sflash0 = input.read()
 
       # Validate input file...
       if sflash0[:0x4] != 'SONY':
           raise SystemExit('\nInvalid PS4 Sflash0 binary!')
 
       for num, entry in enumerate(SFLASH0):
           with open('%s/%s' % (dir, SFLASH0[num][0]), 'wb') as output:
               begin = SFLASH0[num][1]
               end = begin + SFLASH0[num][2]
       
               output.write(sflash0[begin:end])
               print('Unpacked %s' % SFLASH0[num][0])

# Pack entries into a Sflash0 binary...
def pack(dir, file):

   with open(file, 'wb') as output:
       try:
           for num, entry in enumerate(SFLASH0):
               with open('%s/%s' % (dir, SFLASH0[num][0]), 'rb') as input:
                   output.write(input.read())
 
       except IOError as error:
           raise SystemExit('\n%s' % error)


def main(argc, argv):
 
   # Print Usage Statement...
   if argc not in [2, 3]:
       raise SystemExit('\nUsage: python %s <input> [output]' % argv[0])
 
   # File Input -> Unpack
   if os.path.isfile(argv[1]):
 
       # Create a custom directory...
       if argc == 3:
           try:
               os.makedirs(argv[2])
           except:
               pass
 
       unpack(argv[1], argv[2] if argc == 3 else '.')
 
   # Directory Input -> Pack
   elif os.path.isdir(argv[1]):
       pack(argv[1], argv[2] if argc == 3 else 'sflash0.bin')
 
   else:
       raise SystemExit('\nUsage: python %s <input> [output]' % argv[0])
 
   print('\nDone!')

if __name__ == '__main__':
   main(len(sys.argv), sys.argv)
SFlash0Unpack Unpack SFlash0 Files From PS4 Flash Dumps by Zecoxao.jpg

PS4 Dump Extractor.png
 

Comments

BwE

Developer
Senior Member
Contributor
Hey. My program already does this, albeit with improper file names. I guess I can do it differently if this is indeed the proper file structure?

Secondly you're extracting files without taking into account the fact their file sizes aren't always going to be the same? At least that's how I read the code.... This would result in corrupt files being interpreted as complete and valid.
 
Recent Articles
Red Dead Redemption 2 Modding Demos by RDR2 Modder JediJosh920
Following the Spider-Man PS4 Models & Textures Tool and IG PS4 Modding Tools, this weekend RDR2 modder @jedijosh920 (Web site / Twitter) shared on his YouTube Channel some demonstration videos of...
Action-RPG Oninaki Joins New PlayStation 4 Games Next Week
Next week Tokyo RPG Factory's latest action-RPG Oninaki hits PlayStation 4 on August 22nd casting you as a Watcher, tasked with helping usher the souls of the departed into their next life. šŸ—¼...
Electric Purple, Red Camouflage, Titanium Blue & Rose Gold DS4 Controllers!
Earlier this year we saw an Alpine Green DualShock 4 PS4 Controller, and now Sony announced their latest batch of DualShock 4 PS4 Controllers will include Electric Purple, Red Camouflage, Titanium...
Iconit: PS4 Tool to Change PlayStation 4 Game Icons by OfficialAhmed
Following his PS4HEN Trophy Calculator release, developer OfficialAhmed shared Iconit v1.00 on Twitter today, which allows jailbroken console owners with PS4 HEN to change PlayStation 4 game icons...
Top