Ejemplo n.º 1
0
        /// <summary>
        /// Read from a stream and get an NCCH header, if possible
        /// </summary>
        /// <param name="reader">BinaryReader representing the input stream</param>
        /// <param name="readSignature">True if the RSA signature is read, false otherwise</param>
        /// <returns>NCCH header object, null on error</returns>
        public static NCCHHeader Read(BinaryReader reader, bool readSignature)
        {
            NCCHHeader header = new NCCHHeader();

            try
            {
                if (readSignature)
                {
                    header.RSA2048Signature = reader.ReadBytes(0x100);
                }

                if (new string(reader.ReadChars(4)) != NCCHMagicNumber)
                {
                    return(null);
                }

                header.ContentSizeInMediaUnits = reader.ReadUInt32();
                header.PartitionId             = reader.ReadBytes(8).Reverse().ToArray();
                header.MakerCode                 = reader.ReadUInt16();
                header.Version                   = reader.ReadUInt16();
                header.VerificationHash          = reader.ReadUInt32();
                header.ProgramId                 = reader.ReadBytes(8);
                header.Reserved1                 = reader.ReadBytes(0x10);
                header.LogoRegionHash            = reader.ReadBytes(0x20);
                header.ProductCode               = reader.ReadBytes(0x10);
                header.ExtendedHeaderHash        = reader.ReadBytes(0x20);
                header.ExtendedHeaderSizeInBytes = reader.ReadUInt32();
                header.Reserved2                 = reader.ReadBytes(4);
                header.Flags = NCCHHeaderFlags.Read(reader);
                header.PlainRegionOffsetInMediaUnits   = reader.ReadUInt32();
                header.PlainRegionSizeInMediaUnits     = reader.ReadUInt32();
                header.LogoRegionOffsetInMediaUnits    = reader.ReadUInt32();
                header.LogoRegionSizeInMediaUnits      = reader.ReadUInt32();
                header.ExeFSOffsetInMediaUnits         = reader.ReadUInt32();
                header.ExeFSSizeInMediaUnits           = reader.ReadUInt32();
                header.ExeFSHashRegionSizeInMediaUnits = reader.ReadUInt32();
                header.Reserved3 = reader.ReadBytes(4);
                header.RomFSOffsetInMediaUnits         = reader.ReadUInt32();
                header.RomFSSizeInMediaUnits           = reader.ReadUInt32();
                header.RomFSHashRegionSizeInMediaUnits = reader.ReadUInt32();
                header.Reserved4           = reader.ReadBytes(4);
                header.ExeFSSuperblockHash = reader.ReadBytes(0x20);
                header.RomFSSuperblockHash = reader.ReadBytes(0x20);

                return(header);
            }
            catch
            {
                return(null);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Read from a stream and get an NCSD header, if possible
        /// </summary>
        /// <param name="reader">BinaryReader representing the input stream</param>
        /// <param name="development">True if development cart, false otherwise</param>
        /// <returns>NCSD header object, null on error</returns>
        public static NCSDHeader Read(BinaryReader reader, bool development)
        {
            NCSDHeader header = new NCSDHeader();

            try
            {
                header.RSA2048Signature = reader.ReadBytes(0x100);

                if (new string(reader.ReadChars(4)) != NCSDMagicNumber)
                {
                    return(null);
                }

                header.ImageSizeInMediaUnits = reader.ReadUInt32();
                header.MediaId             = reader.ReadBytes(8);
                header.PartitionsFSType    = (FilesystemType)reader.ReadUInt64();
                header.PartitionsCryptType = reader.ReadBytes(8);

                header.PartitionsTable = new PartitionTableEntry[8];
                for (int i = 0; i < 8; i++)
                {
                    header.PartitionsTable[i] = PartitionTableEntry.Read(reader);
                }

                if (header.PartitionsFSType == FilesystemType.Normal ||
                    header.PartitionsFSType == FilesystemType.None)
                {
                    header.ExheaderHash         = reader.ReadBytes(0x20);
                    header.AdditionalHeaderSize = reader.ReadUInt32();
                    header.SectorZeroOffset     = reader.ReadUInt32();
                    header.PartitionFlags       = reader.ReadBytes(8);

                    header.PartitionIdTable = new byte[8][];
                    for (int i = 0; i < 8; i++)
                    {
                        header.PartitionIdTable[i] = reader.ReadBytes(8);
                    }

                    header.Reserved1       = reader.ReadBytes(0x20);
                    header.Reserved2       = reader.ReadBytes(0xE);
                    header.FirmUpdateByte1 = reader.ReadByte();
                    header.FirmUpdateByte2 = reader.ReadByte();

                    header.CARD2WritableAddressMediaUnits = reader.ReadBytes(4);
                    header.CardInfoBytemask  = reader.ReadBytes(4);
                    header.Reserved3         = reader.ReadBytes(0x108);
                    header.TitleVersion      = reader.ReadUInt16();
                    header.CardRevision      = reader.ReadUInt16();
                    header.Reserved4         = reader.ReadBytes(0xCEC); // Incorrectly documented as 0xCEE
                    header.CardSeedKeyY      = reader.ReadBytes(0x10);
                    header.EncryptedCardSeed = reader.ReadBytes(0x10);
                    header.CardSeedAESMAC    = reader.ReadBytes(0x10);
                    header.CardSeedNonce     = reader.ReadBytes(0xC);
                    header.Reserved5         = reader.ReadBytes(0xC4);
                    header.BackupHeader      = NCCHHeader.Read(reader, readSignature: false);

                    if (development)
                    {
                        header.CardDeviceReserved1 = reader.ReadBytes(0x200);
                        header.TitleKey            = reader.ReadBytes(0x10);
                        header.CardDeviceReserved2 = reader.ReadBytes(0xF0);
                    }
                }
                else if (header.PartitionsFSType == FilesystemType.FIRM)
                {
                    header.Unknown      = reader.ReadBytes(0x5E);
                    header.EncryptedMBR = reader.ReadBytes(0x42);
                }

                return(header);
            }
            catch
            {
                return(null);
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Read from a stream and get a CIA header, if possible
        /// </summary>
        /// <param name="reader">BinaryReader representing the input stream</param>
        /// <returns>CIA header object, null on error</returns>
        public static CIAHeader Read(BinaryReader reader)
        {
            CIAHeader header = new CIAHeader();

            try
            {
                header.HeaderSize           = reader.ReadInt32();
                header.Type                 = reader.ReadUInt16();
                header.Version              = reader.ReadUInt16();
                header.CertificateChainSize = reader.ReadInt32();
                header.TicketSize           = reader.ReadInt32();
                header.TMDFileSize          = reader.ReadInt32();
                header.MetaSize             = reader.ReadInt32();
                header.ContentSize          = reader.ReadInt64();
                header.ContentIndex         = reader.ReadBytes(0x2000);
                if (reader.BaseStream.Position % 64 != 0)
                {
                    reader.BaseStream.Seek(64 - (reader.BaseStream.Position % 64), SeekOrigin.Current);
                }

                header.CertificateChain    = new Certificate[3];
                header.CertificateChain[0] = Certificate.Read(reader); // CA
                header.CertificateChain[1] = Certificate.Read(reader); // Ticket
                header.CertificateChain[2] = Certificate.Read(reader); // TMD
                if (reader.BaseStream.Position % 64 != 0)
                {
                    reader.BaseStream.Seek(64 - (reader.BaseStream.Position % 64), SeekOrigin.Current);
                }

                header.Ticket = Ticket.Read(reader, header.TicketSize);
                if (reader.BaseStream.Position % 64 != 0)
                {
                    reader.BaseStream.Seek(64 - (reader.BaseStream.Position % 64), SeekOrigin.Current);
                }

                header.TMDFileData = TitleMetadata.Read(reader, header.TMDFileSize);
                if (reader.BaseStream.Position % 64 != 0)
                {
                    reader.BaseStream.Seek(64 - (reader.BaseStream.Position % 64), SeekOrigin.Current);
                }

                long startingPosition     = reader.BaseStream.Position;
                List <NCCHHeader> headers = new List <NCCHHeader>();
                while (reader.BaseStream.Position < startingPosition + header.ContentSize)
                {
                    long       initPosition = reader.BaseStream.Position;
                    NCCHHeader ncchHeader   = NCCHHeader.Read(reader, readSignature: true);
                    if (ncchHeader == null)
                    {
                        break;
                    }

                    headers.Add(ncchHeader);
                    reader.BaseStream.Seek(initPosition + ncchHeader.ContentSizeInMediaUnits * 0x200, SeekOrigin.Begin);
                }

                header.Partitions = headers.ToArray();
                if (header.MetaSize > 0)
                {
                    header.MetaFileData = MetaFile.Read(reader);
                }

                return(header);
            }
            catch
            {
                return(null);
            }
        }