SELF File Format

From PS4 Developer wiki
Jump to navigation Jump to search

ORBIS SELFs from PS4 have a somewhat different structure from the ones we see on vita and ps3. The structure is documented as follows:

SELF Header Structure

Offset Size Description Notes
0 4 Magic 4F 15 3D 1D
0x4 4 Unknown Always 00 01 01 12
0x8 1 Unknown Always 1
0x9 1 Key Type 0xC SK, 0xF SL, 0xE SM, 0x8 EBOOT and ELF and SELF, 0x9 SPRX and SDLL and SEXE
0xA 2 Padding
0xC 2 MetaData Offset
0xE 2 MetaData Size
0x10 4 Size of SELF
0x14 4 Padding
0x18 2 Number of Segments 1 SK, 2 SL and Modules, 4 SK Elfs, 6 .selfs, 2 .sdll, 6 .sprx, 6 ShellCore, 6 eboot.bin, 2 sexe
0x1A 2 Unknown Always 0x22
0x1C 4 Padding

Self Segment Structure

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

typedef struct
{
 unsigned short unknown_1; 
 unsigned short unknown_2;
 unsigned int padding;
 unsigned long long offset;
 unsigned long long encrypted_compressed_size
 unsigned long long decrypted_decompressed_size ;
} SEGMENT_TABLE;

ELF Segment Structure

After this, follows the ELF Header:

ELF header[1]
Offset Size (bytes) Field Purpose
32-bit 64-bit 32-bit 64-bit
0x00 4 e_ident[EI_MAG0] through e_ident[EI_MAG3] 0x7F followed by ELF(45 4c 46) in ASCII; these four bytes constitute the magic number.
0x04 1 e_ident[EI_CLASS] This byte is set to either 1 or 2 to signify 32- or 64-bit format, respectively.
0x05 1 e_ident[EI_DATA] This byte is set to either 1 or 2 to signify little or big endianness, respectively. This affects interpretation of multi-byte fields starting with offset 0x10.
0x06 1 e_ident[EI_VERSION] Set to 1 for the original version of ELF.
0x07 1 e_ident[EI_OSABI] Identifies the target operating system ABI.
Value ABI
0x00 System V
0x01 HP-UX
0x02 NetBSD
0x03 Linux
0x04 GNU Hurd
0x06 Solaris
0x07 AIX
0x08 IRIX
0x09 FreeBSD
0x0A Tru64
0x0B Novell Modesto
0x0C OpenBSD
0x0D OpenVMS
0x0E NonStop Kernel
0x0F AROS
0x10 Fenix OS
0x11 CloudABI

It is often set to 0 regardless of the target platform.

0x08 1 e_ident[EI_ABIVERSION] Further specifies the ABI version. Its interpretation depends on the target ABI. Linux kernel (after at least 2.6) has no definition of it.[2] In that case, offset and size of EI_PAD are 8.
0x09 7 e_ident[EI_PAD] currently unused
0x10 2 e_type Identifies object file type.
Value Type
0x00 ET_NONE
0x01 ET_REL
0x02 ET_EXEC
0x03 ET_DYN
0x04 ET_CORE
0xfe00 ET_LOOS
0xfeff ET_HIOS
0xff00 ET_LOPROC
0xffff ET_HIPROC
0x12 2 e_machine Specifies target instruction set architecture. Some examples are:
Value ISA
0x00 No specific instruction set
0x02 SPARC
0x03 x86
0x08 MIPS
0x14 PowerPC
0x16 S390
0x28 ARM
0x2A SuperH
0x32 IA-64
0x3E x86-64
0xB7 AArch64
0xF3 RISC-V
0x14 4 e_version Set to 1 for the original version of ELF.
0x18 4 8 e_entry This is the memory address of the entry point from where the process starts executing. This field is either 32 or 64 bits long depending on the format defined earlier.
0x1C 0x20 4 8 e_phoff Points to the start of the program header table. It usually follows the file header immediately, making the offset 0x34 or 0x40 for 32- and 64-bit ELF executables, respectively.
0x20 0x28 4 8 e_shoff Points to the start of the section header table.
0x24 0x30 4 e_flags Interpretation of this field depends on the target architecture.
0x28 0x34 2 e_ehsize Contains the size of this header, normally 64 Bytes for 64-bit and 52 Bytes for 32-bit format.
0x2A 0x36 2 e_phentsize Contains the size of a program header table entry.
0x2C 0x38 2 e_phnum Contains the number of entries in the program header table.
0x2E 0x3A 2 e_shentsize Contains the size of a section header table entry.
0x30 0x3C 2 e_shnum Contains the number of entries in the section header table.
0x32 0x3E 2 e_shstrndx Contains index of the section header table entry that contains the section names.