SELF File Format
Jump to navigation
Jump to 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
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 | 0xC SK, 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 | |
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 long long flags; // >> 20 to get id unsigned long long offset; unsigned long long encrypted_compressed_size unsigned long long decrypted_decompressed_size ; } SEGMENT_TABLE;
The Flags ID
enum SegFlags { SF_ORDR = 0x1, SF_ENCR = 0x2, // encrypted SF_SIGN = 0x4, // signed SF_DFLG = 0x8, // deflated SF_BFLG = 0x800,// block segment };
ELF Segment Structure
After this, follows the 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 ( ) 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.
It is often set to | ||||||||||||||||||||||||||||||||||||||
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.
| ||||||||||||||||||||||||||||||||||||||
0x12 | 2 | e_machine | Specifies target instruction set architecture. Some examples are:
| ||||||||||||||||||||||||||||||||||||||
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
Offset | Size (bytes) | Field | Purpose | |||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
32-bit | 64-bit | 32-bit | 64-bit | |||||||||||||||||||||||||||||||||||
0x00 | 4 | p_type | Identifies the type of the segment.
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
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 |
Additionally, at the bottom, there is likely a footer signature as well as some extra data (size 0x4D bytes)