SELF - SPRX: Difference between revisions
(Created page with "Will be Updated Soon") |
No edit summary |
||
Line 1: | Line 1: | ||
File Format | |||
Notes: | |||
* Numbers are stored in big endian format. | |||
SELF Header | |||
typedef struct | |||
{ | |||
uint32_t magic; // "SCE\0" | |||
uint32_t version; // 2 | |||
uint16_t attribute; // 0x8000 - fself | |||
uint16_t category; | |||
uint32_t metadataInfoOffset; | |||
uint64_t fileOffset; | |||
uint64_t fileSize; | |||
uint64_t unknown06; | |||
uint64_t programInfoOffset; | |||
uint64_t elfHeaderOffset; | |||
uint64_t elfProgramHeadersOffset; | |||
uint64_t elfSectionHeadersOffset; | |||
uint64_t sInfoOffset; | |||
uint64_t versionInfoOffset; | |||
uint64_t controlInfoOffset; | |||
uint64_t controlInfoSize; | |||
uint64_t unknown15; | |||
} | |||
SELFHEADER_t; | |||
Program Info | |||
typedef struct | |||
{ | |||
uint64_t programAuthId; | |||
uint64_t unknown01; | |||
uint16_t programVersion[4]; | |||
uint64_t unknown03; | |||
} | |||
PROGRAMINFO_t; | |||
ELF Header | |||
Notes: | |||
* e_type: ET_PS3PRX=0xFFA4 | |||
* EI_OSABI: ELFOSABI_CELL_LV2=0x66 | |||
ELF Program Headers | |||
Segment Information | |||
typedef struct | |||
{ | |||
uint64_t dataOffset; | |||
uint64_t dataSize; | |||
uint32_t compressed; //1:NO, 2:YES | |||
uint32_t unknown03; | |||
uint32_t unknown04; | |||
uint32_t encrypted; //0:NA, 1:YES, 2:NO | |||
} | |||
SEGMENTINFO_t; | |||
Notes: | |||
* There is one Segment Information for each ELF Program Header. | |||
Control Information | |||
typedef struct | |||
{ | |||
uint32_t unknown00; | |||
uint32_t unknown01; | |||
uint32_t unknown02; | |||
uint32_t unknown03; | |||
uint32_t controlFlags[8]; | |||
uint32_t unknown05; | |||
uint32_t unknown06; | |||
uint32_t unknown07; | |||
uint32_t unknown08; | |||
char digest[64]; | |||
uint32_t unknown10; | |||
uint32_t unknown11; | |||
} | |||
CONTROLINFO_t; | |||
Metadata Information | |||
typedef struct | |||
{ | |||
uint8_t unknown00[32]; | |||
uint8_t key[32]; | |||
uint8_t ivec[32]; | |||
} | |||
METADATAINFO_t; | |||
Notes: | |||
* The key and ivec fields are encrypted using AES256CBC. | |||
* This is not present if it is an FSELF. | |||
Metadata Header | |||
typedef struct | |||
{ | |||
uint64_t signatureInputLength; | |||
uint32_t unknown02; | |||
uint32_t sectionCount; | |||
uint32_t keyCount; | |||
uint32_t signatureInfoSize; | |||
uint32_t unknown06; | |||
uint32_t unknown07; | |||
} | |||
METADATAHEADER_t; | |||
Notes: | |||
* The metadata header is located after the metadata info in the SELF file. | |||
* It is decrypted using AES128CTR with the key and ivec entries from the metadata information. | |||
* The signature input length is the number of bytes which are used to generate the SHA-1 which is used to generate the ECDSA signature. | |||
The length should be eveything from the beginning until the signature itself. The decrypted version of the input data is used. | |||
* This is only present if the metadata Information is present. | |||
Metadata Section Headers | |||
typedef struct | |||
{ | |||
uint64_t dataOffset; | |||
uint64_t dataSize; | |||
uint32_t unknown02; | |||
uint32_t programIndex; | |||
uint32_t unknown04; | |||
uint32_t sha1Index; | |||
uint32_t encrypted; //1:NO, 3:YES | |||
uint32_t keyIndex; | |||
uint32_t ivecIndex; | |||
uint32_t compressed; //1:NO, 2:YES | |||
} | |||
METADATASECTIONHEADER_t; | |||
Notes: | |||
* The metadata section headers are located after the metadata header in the SELF file. | |||
* The number of sections is indicated by the sectionCount entry in the metadata header. | |||
* They are decrypted using AES128CTR with the key and ivec entries from the metadata information. | |||
* Section data is decrypted using AES128CTR with the key and ivec from the metadata keys specified by keyIndex and ivecIndex. | |||
* Section data will also need to be uncompressed using zlib. | |||
* The dataOffsets of the metadata section headers match in general the segment information dataOffsets. | |||
* This is only present if the metadata header is present. | |||
Metadata Keys | |||
typedef uint8_t METADATAKEY_t [16]; | |||
Notes: | |||
* The metadata keys are located after the metadata section headers in the SELF file. | |||
* The number of keys is indicated by the keyCount entry in the metadata header. | |||
* They are decrypted using AES128CTR with the key and ivec entries from the metadata information. | |||
* If the sha1Index points to a key, then key[sha1Index] and key[sha1Index+1] form the 160-bit hash. key[sha1Index+2] | |||
to key[key[sha1Index+6] form the 512-bit key for the HMAC-SHA1. | |||
The HMAC-SHA1 is calculated on the decrypted data and before the decompression. | |||
Signature Information | |||
typedef struct | |||
{ | |||
uint32_t unknown00; | |||
uint32_t signatureSize; | |||
uint64_t unknown02; | |||
uint64_t unknown03; | |||
uint64_t unknown04; | |||
uint64_t unknown05; | |||
uint32_t unknown06; | |||
uint32_t unknown07; | |||
} | |||
SIGNATUREINFO_t; | |||
Notes: | |||
* The signature information is located after the metadata keys in the SELF file. | |||
* It is only present if the signatureInfoSize in the metadata header is not zero. | |||
* It is decrypted using AES128CTR with the key and ivec entries from the metadata information. | |||
Signature | |||
typedef struct | |||
{ | |||
uint8_t r[21]; | |||
uint8_t s[21]; | |||
uint8_t padding[6]; | |||
} | |||
SIGNATURE_t; | |||
Notes: | |||
* The signature is located after the the signature information in the SELF file. | |||
* It is even present if the signature information is not present. | |||
* It is decrypted using AES128CTR with the key and ivec entries from the metadata information. | |||
Extracting an ELF | |||
ELF Header | |||
Elf64_Ehdr elfHeader; | |||
fseek ( selfFile, fix64 ( selfHeader.elfHeaderOffset ), SEEK_SET ); | |||
fread ( &elfHeader, sizeof ( Elf64_Ehdr ), 1, selfFile ); | |||
fseek ( elfFile, 0, SEEK_SET ); | |||
fwrite ( &elfHeader, sizeof ( Elf64_Ehdr ), 1, elfFile ); | |||
Section Headers | |||
Elf64_Shdr elfSectionHeaders[100]; | |||
fseek ( selfFile, fix64 ( selfHeader.elfSectionHeadersOffset ), SEEK_SET ); | |||
fread ( elfSectionHeaders, sizeof ( Elf64_Shdr ), fix16 ( elfHeader.e_shnum ), selfFile ); | |||
fseek ( elfFile, fix64 ( elfHeader.e_shoff ), SEEK_SET ); | |||
fwrite ( elfSectionHeaders, sizeof ( Elf64_Shdr ), fix16 ( elfHeader.e_shnum ), elfFile ); | |||
Section Data | |||
Notes: | |||
* Unknown, manually copying the data over works for now. | |||
* There should be a section data offset somewhere. | |||
Program Headers | |||
Elf64_Phdr elfProgramHeaders[100]; | |||
fseek ( selfFile, fix64 ( selfHeader.elfProgramHeadersOffset ), SEEK_SET ); | |||
fread ( elfProgramHeaders, sizeof ( Elf64_Phdr ), fix16 ( elfHeader.e_phnum ), selfFile ); | |||
fseek ( elfFile, fix64 ( elfHeader.e_phoff ), SEEK_SET ); | |||
fwrite ( elfProgramHeaders, sizeof ( Elf64_Phdr ), fix16 ( elfHeader.e_phnum ), elfFile ); | |||
Program Data | |||
Notes: | |||
* Load the metadata information and decrypt the key and ivec entries using AES256CBC using erk and riv. | |||
* Load the metadata header and decrypt it using AES128CTR with the key and ivec entries from the metadata information. | |||
* Load sectionCount metadata section headers and decrypt them using AES128CTR with the key and ivec entries from the metadata information. | |||
* Load keyCount metadata keys and decrypt them using AES128CTR with the key and ivec entries from the metadata information. | |||
* For each metadata section: | |||
o In the SELF file, fseek to dataOffset and read in dataSize bytes. | |||
o Decrypt the data using AES128CTR with the key and ivec from the metadata keys specified by keyIndex and ivecIndex from the | |||
metadata section header. | |||
o Uncompress the data using zlib. | |||
o Write it to the ELF file as the program section specified by sectionIndex in the metadata section header. | |||
source:[http://ps3wiki.lan.st/index.php?title=SELF_File_Format_and_Decryption] |
Revision as of 22:10, 24 February 2011
File Format
Notes:
* Numbers are stored in big endian format.
SELF Header
typedef struct {
uint32_t magic; // "SCE\0" uint32_t version; // 2 uint16_t attribute; // 0x8000 - fself uint16_t category; uint32_t metadataInfoOffset; uint64_t fileOffset; uint64_t fileSize; uint64_t unknown06; uint64_t programInfoOffset; uint64_t elfHeaderOffset; uint64_t elfProgramHeadersOffset; uint64_t elfSectionHeadersOffset; uint64_t sInfoOffset; uint64_t versionInfoOffset; uint64_t controlInfoOffset; uint64_t controlInfoSize; uint64_t unknown15;
} SELFHEADER_t;
Program Info
typedef struct {
uint64_t programAuthId; uint64_t unknown01; uint16_t programVersion[4]; uint64_t unknown03;
} PROGRAMINFO_t;
ELF Header
Notes:
* e_type: ET_PS3PRX=0xFFA4 * EI_OSABI: ELFOSABI_CELL_LV2=0x66
ELF Program Headers
Segment Information
typedef struct {
uint64_t dataOffset; uint64_t dataSize; uint32_t compressed; //1:NO, 2:YES uint32_t unknown03; uint32_t unknown04; uint32_t encrypted; //0:NA, 1:YES, 2:NO
} SEGMENTINFO_t;
Notes:
* There is one Segment Information for each ELF Program Header.
Control Information
typedef struct {
uint32_t unknown00; uint32_t unknown01; uint32_t unknown02; uint32_t unknown03; uint32_t controlFlags[8]; uint32_t unknown05; uint32_t unknown06; uint32_t unknown07; uint32_t unknown08; char digest[64]; uint32_t unknown10; uint32_t unknown11;
} CONTROLINFO_t;
Metadata Information
typedef struct {
uint8_t unknown00[32]; uint8_t key[32]; uint8_t ivec[32];
} METADATAINFO_t;
Notes:
* The key and ivec fields are encrypted using AES256CBC. * This is not present if it is an FSELF.
Metadata Header
typedef struct {
uint64_t signatureInputLength; uint32_t unknown02; uint32_t sectionCount; uint32_t keyCount; uint32_t signatureInfoSize; uint32_t unknown06; uint32_t unknown07;
} METADATAHEADER_t;
Notes:
* The metadata header is located after the metadata info in the SELF file. * It is decrypted using AES128CTR with the key and ivec entries from the metadata information. * The signature input length is the number of bytes which are used to generate the SHA-1 which is used to generate the ECDSA signature. The length should be eveything from the beginning until the signature itself. The decrypted version of the input data is used. * This is only present if the metadata Information is present.
Metadata Section Headers
typedef struct {
uint64_t dataOffset; uint64_t dataSize; uint32_t unknown02; uint32_t programIndex; uint32_t unknown04; uint32_t sha1Index; uint32_t encrypted; //1:NO, 3:YES uint32_t keyIndex; uint32_t ivecIndex; uint32_t compressed; //1:NO, 2:YES
} METADATASECTIONHEADER_t;
Notes:
* The metadata section headers are located after the metadata header in the SELF file. * The number of sections is indicated by the sectionCount entry in the metadata header. * They are decrypted using AES128CTR with the key and ivec entries from the metadata information. * Section data is decrypted using AES128CTR with the key and ivec from the metadata keys specified by keyIndex and ivecIndex. * Section data will also need to be uncompressed using zlib. * The dataOffsets of the metadata section headers match in general the segment information dataOffsets. * This is only present if the metadata header is present.
Metadata Keys
typedef uint8_t METADATAKEY_t [16];
Notes:
* The metadata keys are located after the metadata section headers in the SELF file. * The number of keys is indicated by the keyCount entry in the metadata header. * They are decrypted using AES128CTR with the key and ivec entries from the metadata information. * If the sha1Index points to a key, then key[sha1Index] and key[sha1Index+1] form the 160-bit hash. key[sha1Index+2] to key[key[sha1Index+6] form the 512-bit key for the HMAC-SHA1. The HMAC-SHA1 is calculated on the decrypted data and before the decompression.
Signature Information
typedef struct {
uint32_t unknown00; uint32_t signatureSize; uint64_t unknown02; uint64_t unknown03; uint64_t unknown04; uint64_t unknown05; uint32_t unknown06; uint32_t unknown07;
} SIGNATUREINFO_t;
Notes:
* The signature information is located after the metadata keys in the SELF file. * It is only present if the signatureInfoSize in the metadata header is not zero. * It is decrypted using AES128CTR with the key and ivec entries from the metadata information.
Signature
typedef struct {
uint8_t r[21]; uint8_t s[21]; uint8_t padding[6];
} SIGNATURE_t;
Notes:
* The signature is located after the the signature information in the SELF file. * It is even present if the signature information is not present. * It is decrypted using AES128CTR with the key and ivec entries from the metadata information.
Extracting an ELF ELF Header
Elf64_Ehdr elfHeader;
fseek ( selfFile, fix64 ( selfHeader.elfHeaderOffset ), SEEK_SET ); fread ( &elfHeader, sizeof ( Elf64_Ehdr ), 1, selfFile );
fseek ( elfFile, 0, SEEK_SET ); fwrite ( &elfHeader, sizeof ( Elf64_Ehdr ), 1, elfFile );
Section Headers
Elf64_Shdr elfSectionHeaders[100];
fseek ( selfFile, fix64 ( selfHeader.elfSectionHeadersOffset ), SEEK_SET ); fread ( elfSectionHeaders, sizeof ( Elf64_Shdr ), fix16 ( elfHeader.e_shnum ), selfFile );
fseek ( elfFile, fix64 ( elfHeader.e_shoff ), SEEK_SET ); fwrite ( elfSectionHeaders, sizeof ( Elf64_Shdr ), fix16 ( elfHeader.e_shnum ), elfFile );
Section Data
Notes:
* Unknown, manually copying the data over works for now. * There should be a section data offset somewhere.
Program Headers
Elf64_Phdr elfProgramHeaders[100];
fseek ( selfFile, fix64 ( selfHeader.elfProgramHeadersOffset ), SEEK_SET ); fread ( elfProgramHeaders, sizeof ( Elf64_Phdr ), fix16 ( elfHeader.e_phnum ), selfFile );
fseek ( elfFile, fix64 ( elfHeader.e_phoff ), SEEK_SET ); fwrite ( elfProgramHeaders, sizeof ( Elf64_Phdr ), fix16 ( elfHeader.e_phnum ), elfFile );
Program Data
Notes:
* Load the metadata information and decrypt the key and ivec entries using AES256CBC using erk and riv. * Load the metadata header and decrypt it using AES128CTR with the key and ivec entries from the metadata information. * Load sectionCount metadata section headers and decrypt them using AES128CTR with the key and ivec entries from the metadata information. * Load keyCount metadata keys and decrypt them using AES128CTR with the key and ivec entries from the metadata information. * For each metadata section: o In the SELF file, fseek to dataOffset and read in dataSize bytes. o Decrypt the data using AES128CTR with the key and ivec from the metadata keys specified by keyIndex and ivecIndex from the metadata section header. o Uncompress the data using zlib. o Write it to the ELF file as the program section specified by sectionIndex in the metadata section header.
source:[1]