-
-
Save n-west/3ea8b74815b3d2f158a3 to your computer and use it in GitHub Desktop.
Xperia SIN Structure analysis
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ========================================================== | |
// Sony Xperia SIN (Firmware flashable files) analysis | |
// | |
// Author: zxz0O0 | |
// Started: 2014-06-05 | |
// Notes: Numbers are big endian | |
// Credits: Androxyde | |
// ========================================================== | |
struct SinFile | |
{ | |
SinHeader sinheader; | |
SinDataHeader sindataheader; | |
byte[??] data; //until eof | |
} | |
struct SinHeader | |
{ | |
byte Version; //The following was done on version 0x03 | |
byte[3] magic; //0x53, 0x49, 0x4E -> SIN | |
int SinHeaderLength; | |
int SinType; //not sure, if correct -> 0x20 for loader.sin, 0x24 for gpt table, 0x27 for MMCF partitions | |
byte[8] unknown; | |
int SinHeaderHashLength; //seems this does not exist anymore in newer sinv3 files with compression | |
SinHeaderHash[(SinHeaderHashLength / 0x24)] Hashes; //first one has size of SIN Data Header, others usually have 0x800 | |
//dataSize of all Hashes + SinHeaderLength should equal size of file | |
byte[??] unknown2; | |
byte[0x100] RSASig; //RSA2048 Signature of a hash, probably SHA256 of SinHeader (excluding signature of course) | |
//not sure what is verifying the RSA signature, probably it's TZ (trust zone) | |
} | |
struct SinHeaderHash | |
{ | |
int dataSize; | |
byte[0x20] SHA256; //SHA256 is calculated from data after SinHeader over the length of dataSize | |
//it's a data flow, i.e. the next data follows the last data (no need for start address) | |
} | |
struct SinDataHeader | |
{ | |
byte[4] MMCFmagic; //0x4D, 0x4D, 0x43, 0x46 -> MMCF | |
int mmcfLength; //mmcfLength + 4 (the length itself) + 4 (the magic) = SinDataHeader length | |
byte[4] GPTPmagic; //0x47, 0x50, 0x54, 0x50 -> GPTP | |
int GPTPsize; //usually 0x18 | |
byte[0x10] GPTGUID; //GPT Unique partition GUID | |
BlockInfoHeader[??] blockinformation; | |
//we do not know the actually size as BIH size is variable (compressed / uncompressed) | |
} | |
struct BlockInfoHeader | |
{ | |
byte[4] magic; | |
//0x4C, 0x5A, 0x34, 0x41 -> LZ4A (compressed) | |
//0x41, 0x44, 0x44, 0x52 -> ADDR (uncompressed) | |
int BIHLength; //0x54 for LZ4A and 0x44 for ADDR | |
long dataStart; | |
long blockSize; //only for LZ4A | |
long dataLength; | |
long dataDest; //Address of destination in new file, everything else in the file is 0xFF (kind of 'compression') | |
long destLength; //only for LZ4A, should be the same as blockSize | |
int HashType; //not sure about that, if correct 2 = SHA256 | |
byte[0x20] SHA256; //again SHA256 hash, probably for verifying in the destination | |
} | |
// And that is the reason why we can not create custom firmwares for Xperia. If you still don't understand, RSA is an asymmetric function. | |
// This means it's using a private key to create the signature and a public key to read it. So even if we find the public key | |
// (which is somewhere on the device), we can never find or guess the private key. Therefore we can not create a valid signature. | |
//Yes I know that the syntax is not correct in C# |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment