Editing SELF File Format

Jump to navigation Jump to search
Warning: You are not logged in. Your IP address will be publicly visible if you make any edits. If you log in or create an account, your edits will be attributed to your username, along with other benefits.

The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then publish the changes below to finish undoing the edit.

Latest revision Your text
Line 1: Line 1:
SELF stands for Signed Executable and Linkable Format. SPRX stands for Signed Playstation Relocatable eXecutable. They are the format used by the executables on the PS3, PS Vita and PS4. PS4 SELF files have a different structure from the PS3/PS Vita ones but contain mostly the same information. See [https://www.psdevwiki.com/ps3/SELF_-_SPRX PS3/PS Vita SELF/SPRX wiki page] and [https://www.psdevwiki.com/ps3/Certified_File PS3/PS Vita Certified File wiki page].
ORBIS SELFs (and PUP entries) have a different structure from the PS3 and PSVita ones.


= SELF Header Structure =
= SELF Header Structure =
Line 10: Line 10:
| 0x4 || 4 || Unknown || Always 00 01 01 12
| 0x4 || 4 || Unknown || Always 00 01 01 12
|-
|-
| 0x8 || 1 || Category || 1 on SELF, 4 on PUP Entry (probably SPP). See [https://www.psdevwiki.com/ps3/Certified_File#Category PS3/PS Vita Category].
| 0x8 || 1 || Content Type || 1 on Self, 4 on PUP Entry
|-
|-
| 0x9 || 1 || [[Program Type]] || First Half denotes version (anything between 0, oldest and F, newest), second Half denotes true type, 4 for Games, 5 for sce_module modules, 6 for Video Apps like Netflix, 8 for System/EX Apps/Executables, 9 for System/EX modules/dlls
| 0x9 || 1 || [[Program Type]] ||
|-
|-
| 0xA || 2 || Padding ||
| 0xA || 2 || Padding ||
Line 18: Line 18:
| 0xC || 2 || Header Size ||
| 0xC || 2 || Header Size ||
|-
|-
| 0xE || 2 || Signature Size || ?Metadata Size?
| 0xE || 2 || Signature Size || Metadata Size?
|-
|-
| 0x10 || 4 || File Size || Size of SELF
| 0x10 || 4 || Size of SELF ||
|-
|-
| 0x14 || 4 || Padding ||
| 0x14 || 4 || Padding ||
|-
|-
| 0x18 || 2 || Number of Segments || 1 Kernel, 2 SL and Secure Modules, 4 Kernel ELFs, 6 .selfs, 2 .sdll, 6 .sprx, 6 ShellCore, 6 eboot.bin, 2 sexe
| 0x18 || 2 || Number of Segments || 1 Kernel, 2 SL and Modules, 4 Kernel ELFs, 6 .selfs, 2 .sdll, 6 .sprx, 6 ShellCore, 6 eboot.bin, 2 sexe
|-
|-
| 0x1A || 2 || Unknown || Always 0x22
| 0x1A || 2 || Unknown || Always 0x22
|-
|-
| 0x1C || 4 || Padding ||  
| 0x1C || 4 || Padding ||  
|-
|}
|}


== SELF Segment Structure ==
== SELF Segment Structure ==


Depending on the number of segments, at offset 0x20 the following structure follows and presents a size multiple of 0x20.
Depending on the number of segments, at 0x20 the following structure follows and presents a size multiple of 0x20.


<pre>
<pre>
typedef struct {
typedef struct
{
  unsigned long long flags; // 0x130006 / 0x00040F / 0x000006 / 0x110006
  unsigned long long flags; // 0x130006 / 0x00040F / 0x000006 / 0x110006
  unsigned long long offset;
  unsigned long long offset;
Line 47: Line 49:


<pre>
<pre>
enum SegFlags {
enum SegFlags
{
     SF_ORDR = 0x1,    // ordered?
     SF_ORDR = 0x1,    // ordered?
     SF_ENCR = 0x2,    // encrypted
     SF_ENCR = 0x2,    // encrypted
Line 59: Line 62:


<pre>
<pre>
uint32_t Id() {
uint32_t Id()
{
return Flags >> 20; //0 or 1
return Flags >> 20; //0 or 1
}
}


bool IsOrdered() {
bool IsOrdered()
{
return (Flags & 1) != 0;//0 or 1
return (Flags & 1) != 0;//0 or 1
}
}


bool IsEncrypted() {
bool IsEncrypted()
{
return (Flags & 2) != 0;//0 or 2
return (Flags & 2) != 0;//0 or 2
}
}


bool IsSigned() {
bool IsSigned()
{
return (Flags & 4) != 0;//0 or 4
return (Flags & 4) != 0;//0 or 4
}
}


bool IsCompressed() {
bool IsCompressed()
{
return (Flags & 8) != 0;//0 or 8
return (Flags & 8) != 0;//0 or 8
}
}


bool IsBlocked() {
bool IsBlocked()
{
return (Flags & 0x800) != 0;//0 or 0x800
return (Flags & 0x800) != 0;//0 or 0x800
}
}
Line 147: Line 156:
|0x11||[[CloudABI]]
|0x11||[[CloudABI]]
|}
|}
Notes: It is often set to <code>0</code> regardless of the target platform.
It is often set to <code>0</code> regardless of the target platform.
The PS4 uses the same ABI identifier as FreeBSD.
|-
|-
| colspan="2" | 0x08 || colspan="2" | 1 || <tt>e_ident[EI_ABIVERSION]</tt>
| colspan="2" | 0x08 || colspan="2" | 1 || <tt>e_ident[EI_ABIVERSION]</tt>
Line 154: Line 162:
|-
|-
| colspan="2" | 0x09 || colspan="2" | 7 || <tt>e_ident[EI_PAD]</tt>
| colspan="2" | 0x09 || colspan="2" | 7 || <tt>e_ident[EI_PAD]</tt>
|Padding
|currently unused
|-
|-
| colspan="2" | 0x10 || colspan="2" | 2 || <tt>e_type</tt>
| colspan="2" | 0x10 || colspan="2" | 2 || <tt>e_type</tt>
Line 160: Line 168:
{| class="wikitable"
{| class="wikitable"
|-
|-
!Value!!Type!!Notes
!Value!!Type
|-
|-
|0x00||ET_NONE||
|0x00||ET_NONE
|-
|-
|0x01||ET_REL||
|0x01||ET_REL
|-
|-
|0x02||ET_EXEC||
|0x02||ET_EXEC
|-
|-
|0x03||ET_DYN||
|0x03||ET_DYN
|-
|-
|0x04||ET_CORE||
|0x04||ET_CORE
|-
|-
|0xfe00||ET_SCE_EXEC||eboot without ASLR
|0xfe00||ET_LOOS
|-
|-
|0xfe01||ET_SCE_REPLAY_EXEC||
|0xfeff||ET_HIOS
|-
|-
|0xfe10||ET_SCE_DYNEXEC||eboot with ASLR
|0xff00||ET_LOPROC
|-
|-
|0xfe18||ET_SCE_DYNAMIC||
|0xffff||ET_HIPROC
|-
|0xfeff||ET_HIOS||
|-
|0xff00||ET_LOPROC||
|-
|0xffff||ET_HIPROC||
|}  
|}  
|-
|-
Line 321: Line 323:
|}
|}


= Program Identification Header =
= SCE Special =


Program Identification Header is located just before the SELF segments certifications.
Just before the start of the metadata a special section exists which contains the following:


{| class="wikitable"
{| class="wikitable"
Line 332: Line 334:
| 0x8 || 0x8 || [[Program Type]] ||
| 0x8 || 0x8 || [[Program Type]] ||
|-
|-
| 0x10 || 0x8 || Program Version ||
| 0x10 || 0x8 || Version 1 ||
|-
|-
| 0x18 || 0x8 || System Software Version || Requested minimum version.
| 0x18 || 0x8 || Version 2 ||
|-
|-
| N.A/0x20 || 0x20 || Content ID || Only exists if the SELF is protected by NPDRM.
| N.A/0x20 || 0x20 || Content ID || Only exists if the SELF is NPDRM
|-
|-
| 0x20/0x40 || 0x20 || Digest || SHA-256 of the decrypted elf (for example, on 7.55 retail decrypted/mmapped elf libc.sprx hash is 67c19a2b053ee386819dcd316d21c4381b35bd3de283ce7ca2e143c86b34f79a)
| 0x20/0x40 || 0x20 || Digest || SHA-256 of the decrypted elf (for example, on 7.55 retail decrypted/mmapped elf libc.sprx hash is 67c19a2b053ee386819dcd316d21c4381b35bd3de283ce7ca2e143c86b34f79a)
|}
|}


= Segment Certification =
= Footer Signature (Extra) =
 
From leaked decrypted PS4 6.00b1 Kernel (containing only one segment) the following information can be deduced:
 
{| class="wikitable"
! Offset !! Size !! Description !! Notes
|-
| 0 || 0x10 || AES Key || AES128CBC Key for Segment 1
|-
| 0x10 || 0x10 || AES IV || AES128CBC IV for Segment 1
|-
| 0x20 || 0x20 || HMAC Hash || SHA256HMAC Hash for Segment 1 (decrypted but compressed in this case) (without extra at footer)
|-
| 0x40 || 0x10 || HMAC Key || SHA256HMAC Key for Segment 1
|-
| 0x50 || 0x40 || License + BMP Header || ???
|-
| 0x90 || 0x20 || BMP Entries || 2 (0x10) Entries (first entry is NULL)
|-
| 0xB0 || 0x100 || RSA Signature || RSA Signature of the Segment Certification
|}
 
= Footer Signature =
 
Additionally, at the bottom of a SELF, there is likely a footer RSA signature as well as some extra data (relative size).
 
= Tools =
 
== Official tools ==
 
To document.
 
== Unofficial tools ==
 
=== SELF Decrypter on PS4 ===
 
[https://github.com/AlexAltea/orbital/blob/master/tools/dumper/source/self_decrypter.c PS4 SELF Decrypter on PS4 by AlexAltea]
 
As PS4 SELF decryption keys are not publicly known, to decrypt SELFs, one can use his PS4 as a blackbox. There are some conditions: the SELF must have valid signatures, it must have a required FW version lower than the FW version of the PS4 being used, and for System SELFs the SELF key_revision must be according to the PS4 FW version. There are exceptions like in first PS4 firmwares where some SELF checks were missing and allowed to decrypt SELFs that did not meet such requirements.
 
=== make_fself by flatz (2018) ===
 
* https://wololo.net/ps4-fpkg-writeup-by-flatz
 
=== make_fself.py (2018-2020) ===
 
* https://github.com/OpenOrbis/OpenOrbis-PS4-Toolchain/blob/master/scripts/make_fself.py
 
* https://github.com/nikolaevich23/PKGi-PS4/blob/master/make_fself.py
 
=== make_fself_gui by cfwprpht (2018) ===
 
* https://github.com/cfwprpht/make_fself_gui
 
=== free-ps2-pub-gen by cfwprpht (2018) ===
 
* https://github.com/cfwprpht/free-ps2-pub-gen
 
=== ps4_unfself by SocraticBliss (2020-2024) ===
 
* https://github.com/SocraticBliss/ps4_unfself
 
=== SELF backport tools ===


To be documented.
Additionally, at the bottom, there is likely a footer signature as well as some extra data (relative size).




{{File Formats}}
{{File Formats}}
<noinclude>[[Category:Main]]</noinclude>
<noinclude>[[Category:Main]]</noinclude>
Please note that all contributions to PS4 Developer wiki are considered to be released under the GNU Free Documentation License 1.2 (see PS4 Developer wiki:Copyrights for details). If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource. Do not submit copyrighted work without permission!

To protect the wiki against automated edit spam, we kindly ask you to solve the following hCaptcha:

Cancel Editing help (opens in new window)