SELF File Format

From Vita Developer wiki
Revision as of 23:25, 21 September 2016 by Cfwprophet (talk | contribs) (→‎Struct)
Jump to navigation Jump to search


SELF stands for Signed Executable and Linkable Format.

It is the format used by the executables on the PS3 (SCE Header Version 2), PS Vita (SCE Header Version 3) It consists of an elf whose sections might be encrypted using AES CTR and signed using ECDSA + HMAC-SHA1 It has a specific header here called SCE header where it stores all the parameters for this process

File Format

Notes:

  • Numbers are stored in little endian format.

SELF/SCE Header

Struct

typedef struct {
  uint32_t magic;                 /* 53434500 = SCE\0 */
  uint32_t version;               /* header version 3*/
  uint16_t sdk_type;              /* */
  uint16_t header_type;           /* 1 self, 2 unknown, 3 pkg */
  uint32_t metadata_offset;       /* metadata offset */
  uint64_t header_len;            /* self header length */
  uint64_t elf_filesize;          /* ELF file length */
  uint64_t self_filesize;         /* SELF file length */
  uint64_t unknown;               /* UNKNOWN */
  uint64_t self_offset;           /* SELF offset */
  uint64_t appinfo_offset;        /* app info offset */
  uint64_t elf_offset;            /* ELF #1 offset */
  uint64_t phdr_offset;           /* program header offset */
  uint64_t shdr_offset;           /* section header offset */
  uint64_t section_info_offset;   /* section info offset */
  uint64_t sceversion_offset;     /* version offset */
  uint64_t controlinfo_offset;    /* control info offset */
  uint64_t controlinfo_size;      /* control info size */
  uint64_t padding;               
} __attribute__((packed)) SELF;

Table

field offset type notes
magic 0x0 u32 Must be "SCE\0"
version 0x4 u32 This must be 3
sdk_type 0x8 u16 This corresponds to the revision of the key to decrypt
header_type 0xA u16 1 self, 2 rvk, 3 pkg, 4 spp
metadata_offset 0xC u32 Offset to the checksums. Must be at least 20 bytes before the end of the header
header_len 0x10 u64 This is the length of the header (including the fake elf headers)
Encrypted size 0x18 u64 The size of the encrypted part of the self file.
File size 0x20 u64 The size of the encrypted part of the self file.
unknown 0x28 u64 Must be 0
self_offset 0x30 u64 SELF Offset
App_info_offset 0x38 u64 An offset in the header, usually at 0x80. See App info header.
elf_offset 0x40 u64 offset to the elf header
phdr_offset 0x48 u64 offset to phdr
shdr_offset 0x50 u64 offset to shdr
encrypted phdr sizes/offsets table offset 0x58 u64 Offset to a table which maps phdr entries to the actual offset/size within the encrypted fself.

Because fselfs can be compressed, they might not match the values listed within the elf.

sceversion header 0x60 u64 Offset to a header which contains some version information, including an offset to the .sceversion section of the encrypted elf.
Control Information 0x68 u64 several information containers
Control Information Size 0x70 u64

comments

The real ELF data is located after the SCE header (see header size).

App Info

Struct

typedef struct {
  uint64_t authid;                /* auth id */
  uint32_t vendor_id;             /* vendor id */
  uint32_t self_type;             /* app type
                                  * 0x0D - ,
  uint64_t version;               /* app version */
  uint64_t padding;               /* UNKNOWN */
} __attribute__((packed)) APP_INFO;

Table

field offset type notes
authid 0x00 u64
unknown 0x08 u32
app_type 0x0c u32
                         *0x08 SDK Debug? 0.945.040 
*0x0D --
app_version 0x10 u64

Comments

Aligned to 0x10 bytes.

ELF Header

Struct

 typedef struct {
   uint8_t e_ident[16];              /* ELF identification */
   uint16_t e_type;                  /* object file type */
   uint16_t e_machine;               /* machine type */
   uint32_t e_version;               /* object file version */
   uint64_t e_entry;                 /* entry point address */
   uint64_t e_phoff;                 /* program header offset */
   uint64_t e_shoff;                 /* section header offset */
   uint16_t e_flags;                 /* processor-specific flags */
   uint32_t e_ehsize;                /* ELF header size */
   uint16_t e_phentsize;             /* size of program header entry */
   uint16_t e_phnum;                 /* number of program header entries */
   uint16_t e_shentsize;             /* size of section header entry */
   uint16_t e_shnum;                 /* number of section header entries */
   uint16_t e_shstrndx;              /* section name string table index */
 } __attribute__((packed)) ELF;

Table

Name of the variable Offset Size Notes
e_ident[0]
,e_ident[1]
,e_ident[2]
,e_ident[3]
elf_offset+(0,1,2,3) 0x4 Magic
e_ident[4] elf_offset+4 0x1 Class Type [ELFCLASS32 = 1][ELFCLASS64 = 2]
e_ident[5] elf_offset+5 0x1 Data Type [ELFDATA2LSB (i.e. le) = 1][ELFDATA2MSB (i.e. be) = 2]
e_ident[6]->e_ident[15] elf_offset+(6->15) 0x1 they are all zeros
e_type elf_offset+0x10 0x2 PRX=0xFE00 EXEC=0x0002
e_machine elf_offset+0x12 0x2 seems to be 0x28 as machine type
e_version elf_offset+0x14 0x4 elf version

Comments

See Specifications here: ELF Header ELF-64 Object File Format

Notes:

  • e_type: ET_PSVPRX=0xFE00
  • e_type: ET_PSVELF=0x0002

ELF Program Headers

Struct

 typedef struct {
   uint32_t p_type;                  /* type of segment */
   uint32_t p_flags;                 /* segment attributes */
   uint64_t p_offset;                /* offset in file */
   uint64_t p_vaddr;                 /* virtual address in memory */
   uint64_t p_paddr;                 /* reserved */
   uint64_t p_filesz;                /* size of segment in file */
   uint64_t p_memsz;                 /* size of segment in memory */
   uint64_t p_align;                 /* alignment of segment */
 } __attribute__((packed)) ELF_PHDR;

Table

Comments

See Spec here: ELF Program Headers

ELF Section Headers

Struct

 typedef struct {
   uint32_t sh_name;                 /* section name */
   uint32_t sh_type;                 /* section type */
   uint64_t sh_flags;                /* section attributes */
   uint64_t sh_addr;                 /* virtual address in memory */
   uint64_t sh_offset;               /* offset in file */
   uint64_t sh_size;                 /* size of section */
   uint32_t sh_link;                 /* link to other section */
   uint32_t sh_info;                 /* miscellaneous information */
   uint64_t sh_addralign;            /* address alignment boundary */
   uint64_t sh_entsize;              /* size of entries, if section has table */
 } __attribute__((packed)) ELF_SHDR;

Table

Comments

Segment Information

Struct

typedef struct {

 uint64_t offset;
 uint64_t size;
 uint32_t compressed; // 2=compressed
 uint32_t unknown1;
 uint32_t encrypted; // 1=encrypted
 uint32_t unknown2;

} __attribute__((packed)) SECTION_INFO;

Table

field offset type notes
Encrypted Data Offset 0x00 u64
Encrypted Data Size 0x08 u64
Compression 0x10 u32
unknown 0x14 u32
Encryption 0x18 u32
unknown 0x1C u32

Comments

There is one of these entries for each phdr entry in the elf file so that the ps3 knows where to decrypt the data from. (because it might also be compressed.)

Notes:

  • There is one Segment Information for each ELF Program Header.

SCE Version Info

Struct

typedef struct {

 uint32_t unknown1;
 uint32_t unknown2;
 uint32_t unknown3;
 uint32_t unknown4;

} __attribute__((packed)) SCEVERSION_INFO;

Table

Comment

Control Information

Struct

typedef struct {

 uint32_t type; // 4== ; 6==;7==
 uint32_t size;
 uint64_t unknown; // 0;1
 union {
   // type 4 0x50 bytes
   struct {
     uint8_t digest1[20]; //hash digest, same for every file
     uint8_t digest2[20]; //sha1 hash digest calculated of .elf file...
     uint8_t digest3[12]; //
     uint64_t padding;
   } file_digest50;
   // type 6 0x110 bytes
   struct {
     uint32_t unknown1; // 0x00000001
     uint8_t unknown2[252];
   } file_digest110;
   // type 7 0x50 bytes
   struct {
     uint64_t unknown1;
     uint64_t unknown2;
     uint64_t unknown3;
     uint64_t unknown4;
     uint64_t unknown5;
     uint64_t unknown6;
     uint64_t unknown7;
     uint64_t unknown8;
   } file_digest50_2;
 };

} __attribute__((packed)) CONTROL_INFO;

Table

Comments