SELF File Format

From PS4 Developer wiki
Jump to: navigation, search

ORBIS SELFs (and PUP entries) 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[edit]

Offset Size Description Notes
0 4 Magic 4F 15 3D 1D
0x4 4 Unknown Always 00 01 01 12
0x8 1 Content Type 1 on Self, 4 on PUP Entry
0x9 1 Product Type 0x0 PUP, 0xC K, 0xF SL, 0xE SM, 0x8 EBOOT and ELF and SELF, 0x9 SPRX and SDLL and SEXE, can increase by 0x10 increments for each new revision
0xA 2 Padding
0xC 2 Header Size
0xE 2 Signature Size Metadata Size?
0x10 4 Size of SELF
0x14 4 Padding
0x18 2 Number of Segments 1 K, 2 SL and Modules, 4 K 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[edit]

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

typedef struct
{
 unsigned long long flags; // 0x130006 / 0x00040F
 unsigned long long offset;
 unsigned long long encrypted_compressed_size
 unsigned long long decrypted_decompressed_size ;
} SEGMENT_TABLE;

The Flags ID[edit]

enum SegFlags
{
    SF_ORDR = 0x1,    // ordered?
    SF_ENCR = 0x2,    // encrypted
    SF_SIGN = 0x4,    // signed
    SF_DFLG = 0x8,    // deflated
    SF_BFLG = 0x800,  // block segment
};

The Flags Maths[edit]

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

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

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

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

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

bool IsBlocked()
{
	return (Flags & 0x800) != 0;//0 or 0x800
}

ELF Segment Structure[edit]

After this, follows the ELF Header:

ELF header
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. 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.

Followed by the program header

Program header
Offset Size (bytes) Field Purpose
32-bit 64-bit 32-bit 64-bit
0x00 4 p_type Identifies the type of the segment.
Value Name Meaning
0x00000000 PT_NULL Program header table entry unused
0x00000001 PT_LOAD Loadable segment
0x00000002 PT_DYNAMIC Dynamic linking information
0x00000003 PT_INTERP Interpreter information
0x00000004 PT_NOTE Auxiliary information
0x00000005 PT_SHLIB reserved
0x00000006 PT_PHDR segment containing program header table itself
0x60000000 PT_LOOS see below
0x6FFFFFFF PT_HIOS
0x70000000 PT_LOPROC
0x7FFFFFFF PT_HIPROC

PT_LOOS to PT_HIOS (PT_LOPROC to PT_HIPROC) is an inclusive reserved ranges for operating system (processor) specific semantics.

0x04 4 p_flags Segment-dependent flags (position for 64-bit structure).
0x04 0x08 4 8 p_offset Offset of the segment in the file image.
0x08 0x10 4 8 p_vaddr Virtual address of the segment in memory.
0x0C 0x18 4 8 p_paddr On systems where physical address is relevant, reserved for segment's physical address.
0x10 0x20 4 8 p_filesz Size in bytes of the segment in the file image. May be 0.
0x14 0x28 4 8 p_memsz Size in bytes of the segment in memory. May be 0.
0x18 4 p_flags Segment-dependent flags (position for 32-bit structure).
0x1C 0x30 4 8 p_align 0 and 1 specify no alignment. Otherwise should be a positive, integral power of 2, with p_vaddr equating p_offset modulus p_align.
0x20 0x38 End of Program Header (size)

SCE Special[edit]

Just before the start of the metadata a special section exists which contains the following:

Offset Size Description Notes
0 0x8 AuthID
0x8 0x8 Product Type 0xC SK, 0xF SL, 0xE SM, 0x8 EBOOT and ELF and SELF, 0x9 SPRX and SDLL and SEXE
0x10 0x8 Version_1
0x18 0x8 Version_2
N.A/0x20 0x20 Content ID Only exists if the self is NPDRM
0x20/0x40 0x20 SHA256SUM

Footer Signature (Extra)[edit]

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