Ejemplo n.º 1
0
        public PfsHeader(BinaryReader reader)
        {
            Magic           = reader.ReadAscii(4);
            NumFiles        = reader.ReadInt32();
            StringTableSize = reader.ReadInt32();
            Reserved        = reader.ReadInt32();

            switch (Magic)
            {
            case "PFS0":
                Type = PfsType.Pfs0;
                break;

            case "HFS0":
                Type = PfsType.Hfs0;
                break;

            default:
                throw new InvalidDataException($"Invalid Partition FS type \"{Magic}\"");
            }

            int entrysize         = GetFileEntrySize(Type);
            int stringTableOffset = 16 + entrysize * NumFiles;

            HeaderSize = stringTableOffset + StringTableSize;

            Files = new PfsFileEntry[NumFiles];
            for (int i = 0; i < NumFiles; i++)
            {
                Files[i] = new PfsFileEntry(reader, Type)
                {
                    Index = i
                };
            }

            for (int i = 0; i < NumFiles; i++)
            {
                reader.BaseStream.Position = stringTableOffset + Files[i].StringTableOffset;
                Files[i].Name = reader.ReadAsciiZ();
            }


            if (Type == PfsType.Hfs0)
            {
                for (int i = 0; i < NumFiles; i++)
                {
                    reader.BaseStream.Position = HeaderSize + Files[i].Offset;
                    Files[i].HashValidity      = Crypto.CheckMemoryHashTable(reader.ReadBytes(Files[i].HashedRegionSize), Files[i].Hash, 0, Files[i].HashedRegionSize);
                }
            }
        }
Ejemplo n.º 2
0
        public XciHeader(Keyset keyset, Stream stream)
        {
            using (var reader = new BinaryReader(stream, Encoding.Default, true))
            {
                Signature = reader.ReadBytes(SignatureSize);
                Magic     = reader.ReadAscii(4);
                if (Magic != HeaderMagic)
                {
                    throw new InvalidDataException("Invalid XCI file: Header magic invalid.");
                }

                reader.BaseStream.Position = SignatureSize;
                byte[] sigData = reader.ReadBytes(SignatureSize);
                reader.BaseStream.Position = SignatureSize + 4;

                SignatureValidity = Crypto.Rsa2048Pkcs1Verify(sigData, Signature, _xciHeaderPubk);

                RomAreaStartPage    = reader.ReadInt32();
                BackupAreaStartPage = reader.ReadInt32();
                byte keyIndex = reader.ReadByte();
                KekIndex          = (byte)(keyIndex >> 4);
                TitleKeyDecIndex  = (byte)(keyIndex & 7);
                GameCardSize      = (GameCardSize)reader.ReadByte();
                CardHeaderVersion = reader.ReadByte();
                Flags             = (GameCardAttribute)reader.ReadByte();
                PackageId         = reader.ReadUInt64();
                ValidDataEndPage  = reader.ReadInt64();
                AesCbcIv          = reader.ReadBytes(Crypto.Aes128Size);
                Array.Reverse(AesCbcIv);
                RootPartitionOffset     = reader.ReadInt64();
                RootPartitionHeaderSize = reader.ReadInt64();
                RootPartitionHeaderHash = reader.ReadBytes(Crypto.Sha256DigestSize);
                InitialDataHash         = reader.ReadBytes(Crypto.Sha256DigestSize);
                SelSec      = reader.ReadInt32();
                SelT1Key    = reader.ReadInt32();
                SelKey      = reader.ReadInt32();
                LimAreaPage = reader.ReadInt32();

                if (keyset != null && !keyset.XciHeaderKey.IsEmpty())
                {
                    byte[] encHeader = reader.ReadBytes(EncryptedHeaderSize);
                    var    decHeader = new byte[EncryptedHeaderSize];
                    Crypto.DecryptCbc(keyset.XciHeaderKey, AesCbcIv, encHeader, decHeader, EncryptedHeaderSize);

                    using (var decreader = new BinaryReader(new MemoryStream(decHeader)))
                    {
                        FwVersion      = decreader.ReadUInt64();
                        AccCtrl1       = (CardClockRate)decreader.ReadInt32();
                        Wait1TimeRead  = decreader.ReadInt32();
                        Wait2TimeRead  = decreader.ReadInt32();
                        Wait1TimeWrite = decreader.ReadInt32();
                        Wait2TimeWrite = decreader.ReadInt32();
                        FwMode         = decreader.ReadInt32();
                        UppVersion     = decreader.ReadInt32();
                        decreader.BaseStream.Position += 4;
                        UppHash = decreader.ReadBytes(8);
                        UppId   = decreader.ReadUInt64();
                    }
                }

                ImageHash = Crypto.ComputeSha256(sigData, 0, sigData.Length);

                reader.BaseStream.Position = RootPartitionOffset;
                PartitionFsHeaderValidity  = Crypto.CheckMemoryHashTable(reader.ReadBytes((int)RootPartitionHeaderSize), RootPartitionHeaderHash, 0, (int)RootPartitionHeaderSize);
            }
        }