コード例 #1
0
        public NcaFsHeader(BinaryReader reader)
        {
            long start = reader.BaseStream.Position;

            Version                     = reader.ReadInt16();
            FormatType                  = (NcaFormatType)reader.ReadByte();
            HashType                    = (NcaHashType)reader.ReadByte();
            EncryptionType              = (NcaEncryptionType)reader.ReadByte();
            reader.BaseStream.Position += 3;

            switch (HashType)
            {
            case NcaHashType.Sha256:
                Sha256Info = new Sha256Info(reader);
                break;

            case NcaHashType.Ivfc:
                IvfcInfo = new IvfcHeader(reader);
                break;
            }

            if (EncryptionType == NcaEncryptionType.AesCtrEx)
            {
                BktrInfo = new BktrPatchInfo();

                reader.BaseStream.Position = start + 0x100;

                BktrInfo.RelocationHeader = new BktrHeader(reader);
                BktrInfo.EncryptionHeader = new BktrHeader(reader);
            }

            if (FormatType == NcaFormatType.Pfs0)
            {
                Type = SectionType.Pfs0;
            }
            else if (FormatType == NcaFormatType.Romfs)
            {
                if (EncryptionType == NcaEncryptionType.AesCtrEx)
                {
                    Type = SectionType.Bktr;
                }
                else
                {
                    Type = SectionType.Romfs;
                }
            }

            reader.BaseStream.Position = start + 0x140;
            Ctr = reader.ReadBytes(8).Reverse().ToArray();

            reader.BaseStream.Position = start + 512;
        }
コード例 #2
0
        public BktrCryptoStream(Stream baseStream, byte[] key, long offset, long length, long counterOffset, byte[] ctrHi, BktrPatchInfo bktr)
            : base(baseStream, key, offset, length, counterOffset, ctrHi)
        {
            BktrHeader header = bktr.EncryptionHeader;

            byte[] subsectionBytes;
            using (var streamDec = new RandomAccessSectorStream(new Aes128CtrStream(baseStream, key, offset, length, counterOffset, ctrHi)))
            {
                streamDec.Position = header.Offset;
                subsectionBytes    = new byte[header.Size];
                streamDec.Read(subsectionBytes, 0, subsectionBytes.Length);
            }

            using (var reader = new BinaryReader(new MemoryStream(subsectionBytes)))
            {
                AesSubsectionBlock = new AesSubsectionBlock(reader);
            }

            foreach (AesSubsectionBucket bucket in AesSubsectionBlock.Buckets)
            {
                SubsectionEntries.AddRange(bucket.Entries);
            }

            // Add a subsection for the BKTR headers to make things easier
            var headerSubsection = new AesSubsectionEntry
            {
                Offset    = bktr.RelocationHeader.Offset,
                Counter   = (uint)(ctrHi[4] << 24 | ctrHi[5] << 16 | ctrHi[6] << 8 | ctrHi[7]),
                OffsetEnd = long.MaxValue
            };

            SubsectionEntries.Add(headerSubsection);

            for (int i = 0; i < SubsectionEntries.Count - 1; i++)
            {
                SubsectionEntries[i].Next      = SubsectionEntries[i + 1];
                SubsectionEntries[i].OffsetEnd = SubsectionEntries[i + 1].Offset;
            }

            SubsectionOffsets = SubsectionEntries.Select(x => x.Offset).ToList();

            CurrentEntry = GetSubsectionEntry(0);
            UpdateCounterSubsection(CurrentEntry.Counter);
            baseStream.Position = offset;
        }