PS4 JAILBREAK PSP Injection Tutorial (PSPHD BASIC INJECTION TUTORIAL) by @seanp2500
Here's a Tutorial by strann0, and also another from KiiWii to quote: [WIP] PSP Injection
BASIC INJECTION TUTORIAL:
You will need:
Open the FPKG with pub-chk using all 0's as the key and extract ALL the content.
Copy all EXCEPT the playgo/psreserved/keystone files from the Sc0 folder
Locate Image0>sce_sys folder and paste the files in. (should look like this )
Replacing the game:
Locate Image0 > data folder and delete the USER_L0.IMG
(Trivia: L0 refers to layer 0 and L1 refers to layer 1 for PSP umd creation, L0&L1 can be = 900mb max, combined 1.8gb max)
Copy your PSP ISO to this location and to make things easier name it game.iso
Simple!
OPTIONAL Making your own homebrew ISO:
You need to locate: UMDGEN 4.0 & EBOOT2ISO 1.1
Open EBOOT2ISO, and select your homebrew eboot.pbp, put the output path as the same folder you are currently in, and click CONVERT
Place any files that came with the homebrew eboot.pbp into PSP_GAME/Sysdir. (Rom folders go here too FYI)
Open UMDGEN, drag the PSP_GAME folder into UMDGen, click the UMD PROPERTIES tab and click GENERATE.
Click Save and select UNCOMPRESSED ISO.
Rename to game.iso and place in Image0 > data folder to test.
(Massive thanks to Ploggy for the mini tut!)
Editing the configuration:
Locate Image0 > config-emu-ps4.txt (make a back up somewhere else first just in case) open it in notepad:
Edit the "Game Image" part to this:
Now go through config-emu-ps4.txt and ";" comment out EVERY uncommented command (you can actually leave SSAA4x if you want), for example:
Enabled:
Disabled (commented out):
Save config-emu-ps4.txt and exit.
Editing icons and SFO:
To edit the SFO use HXD (make a back up somewhere else first just in case) you can edit (in three places) the line "PaRappa The Rapperâ„¢ Remastered" to almost any string you like, careful to maintain the length, for example mine is now set to: "PSPHD INJECTIONZ TEST REMASTERED"
You can also overwrite the CUSA ID/UCUS ID to individualize the game and allow more than one to be installed. For example: UP9000-CUSA05289_00-UCUS987020000001 is parappa original > EP9000-UCUS00304_00-UCUS003040000100 = Custom ID using Loco Roco's actual UCUS ID. (thanks Shopeg over at hax)
Dont forget the CUSA05289 line at the very bottom of the SFO too.
Save Param.SFO and exit.
Now go to Image0 > sce_sys and edit nptitle.dat with HXD to match the CUSA ID you used in the SFO.
To edit the icons and bg PNG's I suggest start new images in GIMP2 (or your preferred image editor):
Stripping out unneeded files:
You can remove pretty much anything that relates to texture/movie/sample swaps, languages, etc leaving a bare bones set of directories ready to customize your own in future. For this tutorial I have left pretty much everything up to you to make it simpler. Feel free to experiment with what files are and aren't needed (for example .dds files arent needed )
Rebuilding the FPKG:
You can rename the PKG anything you like, I name mine as <content vX>.pkg for example: Loco Roco v3.pkg (version denotes changes I have made in case of regressions)
Copy the FPKG to your exfat USB stick, and install to PS4 through [SETTINGS] > [DEBUG SETTINGS] > [GAME] > [PKG INSTALLER].
Enjoy and report back any specific PSP game success stories! (psdevwiki compatibility list)
Spoiler
Please feel free to contribute!
PS4HEN PSP PKGs for PS4
So, the PSP Emulator on PS4 requires the BOOT.BIN to have certain section names that it is scanning. Most of the binaries actually do contain them AFTER decryption, but sometimes they are stripped. Luckily the string table is still there and sony left the offsets of the section header names intact. That means we can identify+restore them
Here is a script that can add those required (NPEZ00311, ULUS10567,..). If an empty entry is found, it will create a ".new" file. This will not magically make everything working, for that you still need to identify why the emulator is crashing, but you can read /dev/klog
I took partial elf reading code from flatz, so kudos to him: > python fix_elf.py <input_elf>
PSPHD Demo
Download: PSP HD GUI V1.0.0.0 (psphd.zip) / GIT / PSTools Patreon
To quote from xXxTheDarkprogramerxXx (aka @TheDarkprograme): This is a release of my psp chd gui it will repack psp games for ps4 emulation
Currently there is alot more research needed on the current psp emulation on the ps4
But i believe something will come soon to make this emu even better
As Always Please install the .application file in the zip attached and auto updates for this will be done via click once
Please feel free to use the psp menu (layout) as i spent the most time on it and it just looks sexy
Enjoy
XDPx
Here's a Tutorial by strann0, and also another from KiiWii to quote: [WIP] PSP Injection
BASIC INJECTION TUTORIAL:
You will need:
- orbis-pub-chk
- orbis-pub-gen
- parappa the rappa/patapon/loco roco 2 remasters fpkg
- A compatible PSP iso (also currently very few work, examples: lumines, loco roco games, patapon games (stuck at "sign" screen)) or build your own homebrew iso (See Optional)
- [plain]HXD[/plain]
- notepad
- gimp2
Open the FPKG with pub-chk using all 0's as the key and extract ALL the content.
Copy all EXCEPT the playgo/psreserved/keystone files from the Sc0 folder
Locate Image0>sce_sys folder and paste the files in. (should look like this )
Code:
/about
/trophy
icon0.dds
icon0.png
nptitle.dat
npbind.dat
param.sfo
pic0.dds
pic0.png
pic1.dds
pic1.png
pronunciation.sig
pronunciation.xml
save_data.png
shareparam.json
snd0.at9
Locate Image0 > data folder and delete the USER_L0.IMG
(Trivia: L0 refers to layer 0 and L1 refers to layer 1 for PSP umd creation, L0&L1 can be = 900mb max, combined 1.8gb max)
Copy your PSP ISO to this location and to make things easier name it game.iso
Simple!
OPTIONAL Making your own homebrew ISO:
You need to locate: UMDGEN 4.0 & EBOOT2ISO 1.1
Open EBOOT2ISO, and select your homebrew eboot.pbp, put the output path as the same folder you are currently in, and click CONVERT
Place any files that came with the homebrew eboot.pbp into PSP_GAME/Sysdir. (Rom folders go here too FYI)
Open UMDGEN, drag the PSP_GAME folder into UMDGen, click the UMD PROPERTIES tab and click GENERATE.
Click Save and select UNCOMPRESSED ISO.
Rename to game.iso and place in Image0 > data folder to test.
(Massive thanks to Ploggy for the mini tut!)
Editing the configuration:
Locate Image0 > config-emu-ps4.txt (make a back up somewhere else first just in case) open it in notepad:
Edit the "Game Image" part to this:
Code:
; Game Image
--image="data/game.iso"
Enabled:
Code:
; This enables bilinear filtering on replaced textures. (uncomment to enable)
--replacementfilter=true
Code:
; This enables bilinear filtering on replaced textures. (uncomment to enable)
;--replacementfilter=true
Editing icons and SFO:
To edit the SFO use HXD (make a back up somewhere else first just in case) you can edit (in three places) the line "PaRappa The Rapperâ„¢ Remastered" to almost any string you like, careful to maintain the length, for example mine is now set to: "PSPHD INJECTIONZ TEST REMASTERED"
You can also overwrite the CUSA ID/UCUS ID to individualize the game and allow more than one to be installed. For example: UP9000-CUSA05289_00-UCUS987020000001 is parappa original > EP9000-UCUS00304_00-UCUS003040000100 = Custom ID using Loco Roco's actual UCUS ID. (thanks Shopeg over at hax)
Dont forget the CUSA05289 line at the very bottom of the SFO too.
Save Param.SFO and exit.
Now go to Image0 > sce_sys and edit nptitle.dat with HXD to match the CUSA ID you used in the SFO.
To edit the icons and bg PNG's I suggest start new images in GIMP2 (or your preferred image editor):
- 512x512 24bit PNG for Icon0.png
- 1920x1080 24bit PNG for pic0.png and pic1.png
- 228x128 24bit PNG for save_data.png
Stripping out unneeded files:
You can remove pretty much anything that relates to texture/movie/sample swaps, languages, etc leaving a bare bones set of directories ready to customize your own in future. For this tutorial I have left pretty much everything up to you to make it simpler. Feel free to experiment with what files are and aren't needed (for example .dds files arent needed )
Rebuilding the FPKG:
- Open pub-gen, double click image0 in right pane, drag contents of your Image0 folder into that directory,
- Click chunk panel on left, right click image0 on left and tick switch chunks, press C to close that pane.
- Click command > project settings>package: give the pkg a name in the format "XXYY-XXXXYYYYY_00-ZZZZZZZZZZZZZZZZ" = use the ID you gave it while editing the SFO for easy way to remember it.
- Give the FPKG a passcode (32 0's is HIGHLY recommended)
- Click ok, hit build (far right) then set directory for output PKG, once selected then hit tab and hit enter to start the FPKG build.
You can rename the PKG anything you like, I name mine as <content vX>.pkg for example: Loco Roco v3.pkg (version denotes changes I have made in case of regressions)
Copy the FPKG to your exfat USB stick, and install to PS4 through [SETTINGS] > [DEBUG SETTINGS] > [GAME] > [PKG INSTALLER].
Enjoy and report back any specific PSP game success stories! (psdevwiki compatibility list)
Spoiler
Please feel free to contribute!
PS4HEN PSP PKGs for PS4
- Age Of Zombies
- Lumines
- PaRappa the Rapper Remastered
- Street Fighter Alpha 3 Max
So, the PSP Emulator on PS4 requires the BOOT.BIN to have certain section names that it is scanning. Most of the binaries actually do contain them AFTER decryption, but sometimes they are stripped. Luckily the string table is still there and sony left the offsets of the section header names intact. That means we can identify+restore them
Here is a script that can add those required (NPEZ00311, ULUS10567,..). If an empty entry is found, it will create a ".new" file. This will not magically make everything working, for that you still need to identify why the emulator is crashing, but you can read /dev/klog
I took partial elf reading code from flatz, so kudos to him: > python fix_elf.py <input_elf>
Code:
import struct
import sys
class ElfPHdr(object):
FMT = '<8I'
def __init__(self, idx):
self.idx = idx
self.type = None
self.offset = None
self.vaddr = None
self.paddr = None
self.filesz = None
self.memsz = None
self.flags = None
self.align = None
def load(self, f):
self.type, self.offset, self.vaddr, self.paddr, self.filesz, self.memsz, self.flags, self.align = struct.unpack(ElfPHdr.FMT, f.read(struct.calcsize(ElfPHdr.FMT)))
class ElfSHdr(object):
FMT = '<10I'
def __init__(self, idx):
self.idx = idx
self.name = None
self.name_end = None
self.name_len = None
self.type = None
self.flags = None
self.addr = None
self.offset = None
self.size = None
self.link = None
self.info = None
self.align = None
self.entsize = None
def load(self, f):
self.name, self.type, self.flags, self.addr, self.offset, self.size, self.link, self.info, self.align, self.entsize = struct.unpack(ElfSHdr.FMT, f.read(struct.calcsize(ElfSHdr.FMT)))
class ElfEHdr(object):
FMT = '<4s5B6xB'
EX_FMT = '<2HI3II6H'
def __init__(self):
self.magic = None
self.machine_class = None
self.data_encoding = None
self.version = None
self.os_abi = None
self.abi_version = None
self.nident_size = None
self.type = None
self.machine = None
self.version = None
self.entry = None
self.phoff = None
self.shoff = None
self.flags = None
self.ehsize = None
self.phentsize = None
self.phnum = None
self.shentsize = None
self.shnum = None
self.shstridx = None
def load(self, f):
self.magic, self.machine_class, self.data_encoding, self.version, self.os_abi, self.abi_version, self.nident_size = struct.unpack(ElfEHdr.FMT, f.read(struct.calcsize(ElfEHdr.FMT)))
self.type, self.machine, self.version, self.entry, self.phoff, self.shoff, self.flags, self.ehsize, self.phentsize, self.phnum, self.shentsize, self.shnum, self.shstridx = struct.unpack(ElfEHdr.EX_FMT, f.read(struct.calcsize(ElfEHdr.EX_FMT)))
def has_segments(self):
return self.phentsize > 0 and self.phnum > 0
def has_sections(self):
return self.shentsize > 0 and self.shnum > 0
class ElfFile(object):
def __init__(self):
self.ehdr = None
self.phdrs = None
self.shdrs = None
self.file_size = None
self.segments = None
self.sections = None
self.shstrtab = None
self.shstrtab_offset = None
def load(self, f):
start_offset = f.tell()
data = f.read()
self.file_size = len(data)
f.seek(start_offset)
self.ehdr = ElfEHdr()
self.ehdr.load(f)
self.phdrs = []
self.segments = []
if self.ehdr.has_segments():
for i in xrange(self.ehdr.phnum):
#print "[*] ElfPHdr Offset: %x" % (start_offset + self.ehdr.phoff + i * self.ehdr.phentsize)
f.seek(start_offset + self.ehdr.phoff + i * self.ehdr.phentsize)
phdr = ElfPHdr(i)
phdr.load(f)
self.phdrs.append(phdr)
if phdr.filesz > 0:
f.seek(start_offset + phdr.offset)
data = f.read(phdr.filesz)
else:
data = ''
self.segments.append(data)
self.shdrs = []
self.sections = []
if self.ehdr.has_sections():
for i in xrange(self.ehdr.shnum):
#print "[*] ElfSHdr Offset: %x" % (start_offset + self.ehdr.shoff + i * self.ehdr.shentsize)
f.seek(start_offset + self.ehdr.shoff + i * self.ehdr.shentsize)
shdr = ElfSHdr(i)
shdr.load(f)
self.shdrs.append(shdr)
for i in xrange(self.ehdr.shnum):
if self.shdrs[i].type == 3 and self.shdrs[i].size > 1:#self.shdrs[i].name_len == 9: # shstrtab
self.shstrtab_offset = self.shdrs[i].offset
print "[*] shstrtab found at: 0x%x" % self.shstrtab_offset
f.seek(self.shstrtab_offset)
self.shstrtab = f.read(self.shdrs[i].size)
#print self.shstrtab
for i in xrange(self.ehdr.shnum):
if i > 0:
self.shdrs[i-1].name_end = self.shdrs[i].name - 1
self.shdrs[i-1].name_len = self.shdrs[i-1].name_end - self.shdrs[i-1].name
#print "%d name_end - name - name_len: %x - %x = %x" % (i,self.shdrs[i-1].name_end, self.shdrs[i-1].name, self.shdrs[i-1].name_len)
if i == self.ehdr.shnum-1:
self.shdrs[i].name_end = len(self.shstrtab) - 1
self.shdrs[i].name_len = self.shdrs[i].name_end - self.shdrs[i].name
#print "%d name_end - name - name_len: %x - %x = %x" % (i, self.shdrs[i].name_end, self.shdrs[i].name, self.shdrs[i].name_len)
if len(sys.argv) < 2:
print "python fix_elf.py <in_elf>"
sys.exit(0)
print "[.] Opening file %s..." % sys.argv[1]
f = open(sys.argv[1], "rb")
#f = open("ULUS10491.BIN", "rb")
#f = open("NPEZ00311.BIN", "rb")
#f = open("ULUS10567.BIN", "rb")
#f = open("NPUG80248.BIN", "rb")
#f = open("ULES00193.BIN", "rb")
elf_file = ElfFile()
elf_file.load(f)
print "[*] magic: %s" % elf_file.ehdr.magic
print "[*] machine_class: %x" % elf_file.ehdr.machine_class
print "[*] data_encoding: %x" % elf_file.ehdr.data_encoding
print "[*] version: %x" % elf_file.ehdr.version
print "[*] os_abi: %x" % elf_file.ehdr.os_abi
print "[*] abi_version: %x" % elf_file.ehdr.abi_version
print "[*] nident_size: %x" % elf_file.ehdr.nident_size
print "[*] type: 0x%x" % elf_file.ehdr.type
print "[*] machine: %x" % elf_file.ehdr.machine
print "[*] version: %x" % elf_file.ehdr.version
print "[*] entry: 0x%x" % elf_file.ehdr.entry
print "[*] phoff: 0x%x" % elf_file.ehdr.phoff
print "[*] shoff: 0x%x" % elf_file.ehdr.shoff
print "[*] flags: 0x%x" % elf_file.ehdr.flags
print "[*] ehsize: 0x%x" % elf_file.ehdr.ehsize
print "[*] phentsize: 0x%x" % elf_file.ehdr.phentsize
print "[*] phnum: 0x%x" % elf_file.ehdr.phnum
print "[*] shentsize: 0x%x" % elf_file.ehdr.shentsize
print "[*] shnum: 0x%x" % elf_file.ehdr.shnum
print "[*] shstridx: %x" % elf_file.ehdr.shstridx
# Check first name if empty or not to determine fixing
if elf_file.shstrtab[elf_file.shdrs[1].name:elf_file.shdrs[1].name_end].replace('\x00',"") == "":
print "[!] No Section header names found!"
print "[.] attempting to identify required sections..."
PF_WRITE = 0x1
PF_READ = 0x2
PF_EXEC = 0x4
PF_READ_EXEC = PF_READ | PF_EXEC
PF_READ_WRITE = PF_READ | PF_WRITE
to_fix = 5
for i in xrange(elf_file.ehdr.shnum):
if (elf_file.shdrs[i].flags & PF_READ_EXEC) == PF_READ_EXEC and elf_file.shdrs[i].name_len == len(".text"):
print "[!] found .text at section %d" % i
elf_file.shstrtab = elf_file.shstrtab[:elf_file.shdrs[i].name] + ".text" + elf_file.shstrtab[elf_file.shdrs[i].name_end:]
to_fix -= 1
if elf_file.shdrs[i].type == 8 and elf_file.shdrs[i].name_len == len(".bss"):
print "[!] found .bss at section %d" % i
elf_file.shstrtab = elf_file.shstrtab[:elf_file.shdrs[i].name] + ".bss" + elf_file.shstrtab[elf_file.shdrs[i].name_end:]
to_fix -= 1
if elf_file.shdrs[i].type == 1 and elf_file.shdrs[i].flags == 3 and elf_file.shdrs[i].name_len == len(".data"):
print "[!] found .data at section %d" % i
elf_file.shstrtab = elf_file.shstrtab[:elf_file.shdrs[i].name] + ".data" + elf_file.shstrtab[elf_file.shdrs[i].name_end:]
to_fix -= 1
if elf_file.shdrs[i].type == 1 and elf_file.shdrs[i].size == 0x34 and elf_file.shdrs[i].name_len == len(".rodata.sceModuleInfo"):
print "[!] found .rodata.sceModuleInfo at section %d" % i
elf_file.shstrtab = elf_file.shstrtab[:elf_file.shdrs[i].name] + ".rodata.sceModuleInfo" + elf_file.shstrtab[elf_file.shdrs[i].name_end:]
to_fix -= 1
if elf_file.shdrs[i].type == 3 and elf_file.shdrs[i].size > 1 and elf_file.shdrs[i].name_len == len(".shstrtab"):
print "[!] found .shstrtab at section %d" % i
elf_file.shstrtab = elf_file.shstrtab[:elf_file.shdrs[i].name] + ".shstrtab" + elf_file.shstrtab[elf_file.shdrs[i].name_end:]
to_fix -= 1
if to_fix == 0:
print "[.] Writing new file..."
f.seek(0)
data = f.read()
data = data[:elf_file.shstrtab_offset] + elf_file.shstrtab + data[elf_file.shstrtab_offset+len(elf_file.shstrtab):]
open(sys.argv[1] + ".new", "wb").write(data)
else:
print "[!] Error. Could not identify required sections."
print "Section Headers:"
print " [Nr] Name Type Addr Off Size Flg Lk Inf Al"
for i in xrange(elf_file.ehdr.shnum):
print " %02d %-15.15s (%02x) %08x %08x %06x %06x %x" % (i, elf_file.shstrtab[elf_file.shdrs[i].name:elf_file.shdrs[i].name_end].replace('\x00',""),elf_file.shdrs[i].name_len, elf_file.shdrs[i].type,elf_file.shdrs[i].addr,elf_file.shdrs[i].offset,elf_file.shdrs[i].size,elf_file.shdrs[i].flags)
f.close()
print "[.] done."
Download: PSP HD GUI V1.0.0.0 (psphd.zip) / GIT / PSTools Patreon
To quote from xXxTheDarkprogramerxXx (aka @TheDarkprograme): This is a release of my psp chd gui it will repack psp games for ps4 emulation
Currently there is alot more research needed on the current psp emulation on the ps4
But i believe something will come soon to make this emu even better
As Always Please install the .application file in the zip attached and auto updates for this will be done via click once
Please feel free to use the psp menu (layout) as i spent the most time on it and it just looks sexy
Enjoy
XDPx
- PSPClassics.zip (79.6 MB) / PSPHD1.0.0.5.zip (Source Code) / PSTools Patreon
- PSPTools (to decrypt PRX and Eboot Files for PSP emulation on PS4).