SFlash0Unpack: Unpack SFlash0 Files in PS4 Flash Dumps by Zecoxao
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.
Download: sflash0unpack-master.zip / GIT / ps4_sflash0_pack_tool.py / 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!
image: https://www.psxhax.com/styles/default/xenforo/clear.png

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;
}
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)
image: https://www.psxhax.com/attachments/sflash0unpack-unpack-sflash0-files-from-ps4-flash-dumps-by-zecoxao-jpg.4768/
Comments
Post a Comment