示例#1
0
        public Ini1(Stream stream)
        {
            StreamSource = new SharedStreamSource(stream);
            Stream initStream = StreamSource.CreateStream();

            var reader = new BinaryReader(initStream);

            Magic = reader.ReadAscii(4);
            if (Magic != "INI1")
            {
                throw new InvalidDataException("Invalid INI1 file!");
            }

            Size     = reader.ReadInt32();
            KipCount = reader.ReadInt32();

            Kips = new Kip[KipCount];
            int offset = 0x10;

            for (int i = 0; i < KipCount; i++)
            {
                // How to get the KIP's size the lazy way
                var kip = new Kip(StreamSource.CreateStream(offset));

                Kips[i] = new Kip(StreamSource.CreateStream(offset, kip.Size));

                offset += kip.Size;
            }
        }
示例#2
0
        public Savefile(Keyset keyset, Stream file, IntegrityCheckLevel integrityCheckLevel)
        {
            SavefileSource = new SharedStreamSource(file);

            Header = new Header(keyset, SavefileSource);
            FsLayout layout = Header.Layout;

            DataRemapStorage = new RemapStorage(SavefileSource.CreateStream(layout.FileMapDataOffset, layout.FileMapDataSize),
                                                Header.FileRemap, Header.FileMapEntries);

            DuplexData = InitDuplexStream(DataRemapStorage, Header);

            MetaRemapStorage = new RemapStorage(DuplexData, Header.MetaRemap, Header.MetaMapEntries);

            Stream journalTable = MetaRemapStorage.OpenStream(layout.JournalTableOffset, layout.JournalTableSize);

            MappingEntry[] journalMap = JournalStream.ReadMappingEntries(journalTable, Header.Journal.MainDataBlockCount);

            Stream journalData = DataRemapStorage.OpenStream(layout.JournalDataOffset,
                                                             layout.JournalDataSizeB + layout.SizeReservedArea);
            var journalStream = new JournalStream(journalData, journalMap, (int)Header.Journal.BlockSize);

            JournalStreamSource = new SharedStreamSource(journalStream);

            IvfcStream = InitIvfcStream(integrityCheckLevel);

            SaveFs = new SaveFs(IvfcStream, MetaRemapStorage.OpenStream(layout.FatOffset, layout.FatSize), Header.Save);

            IvfcStreamSource = new SharedStreamSource(IvfcStream);
        }
示例#3
0
文件: Romfs.cs 项目: robwilkes/LibHac
        public Romfs(Stream stream)
        {
            StreamSource = new SharedStreamSource(stream);

            byte[] dirMetaTable;
            byte[] fileMetaTable;
            using (var reader = new BinaryReader(StreamSource.CreateStream(), Encoding.Default, true))
            {
                Header = new RomfsHeader(reader);
                reader.BaseStream.Position = Header.DirMetaTableOffset;
                dirMetaTable = reader.ReadBytes((int)Header.DirMetaTableSize);
                reader.BaseStream.Position = Header.FileMetaTableOffset;
                fileMetaTable = reader.ReadBytes((int)Header.FileMetaTableSize);
            }

            using (var reader = new BinaryReader(new MemoryStream(dirMetaTable)))
            {
                int position = 0;
                while (position + 20 < Header.DirMetaTableSize)
                {
                    var dir = new RomfsDir(reader)
                    {
                        Offset = position
                    };
                    Directories.Add(dir);
                    if (dir.ParentDirOffset == position)
                    {
                        RootDir = dir;
                    }
                    position = (int)reader.BaseStream.Position;
                }
            }

            using (var reader = new BinaryReader(new MemoryStream(fileMetaTable)))
            {
                int position = 0;
                while (position + 20 < Header.FileMetaTableSize)
                {
                    var file = new RomfsFile(reader)
                    {
                        Offset = position
                    };
                    Files.Add(file);
                    position = (int)reader.BaseStream.Position;
                }
            }

            SetReferences();
            RomfsEntry.ResolveFilenames(Files);
            RomfsEntry.ResolveFilenames(Directories);
            FileDict = Files.ToDictionary(x => x.FullPath, x => x);
        }
示例#4
0
        public Kip(Stream stream)
        {
            StreamSource = new SharedStreamSource(stream);
            Header       = new KipHeader(StreamSource.CreateStream());

            Size = HeaderSize;

            for (int index = 0; index < Header.Sections.Length; index++)
            {
                int sectionSize = Header.Sections[index].CompressedSize;
                SectionOffsets[index] = Size;
                Size += sectionSize;
            }
        }
示例#5
0
        public Nso(Stream stream)
        {
            StreamSource = new SharedStreamSource(stream);
            var reader = new BinaryReader(StreamSource.CreateStream());

            if (reader.ReadAscii(4) != "NSO0")
            {
                throw new InvalidDataException("NSO magic is incorrect!");
            }
            reader.ReadUInt32(); // Version
            reader.ReadUInt32(); // Reserved/Unused
            var flags         = new BitArray(new[] { (int)reader.ReadUInt32() });
            var textSection   = new NsoSection(StreamSource);
            var rodataSection = new NsoSection(StreamSource);
            var dataSection   = new NsoSection(StreamSource);

            textSection.IsCompressed   = flags[0];
            rodataSection.IsCompressed = flags[1];
            dataSection.IsCompressed   = flags[2];
            textSection.CheckHash      = flags[3];
            rodataSection.CheckHash    = flags[4];
            dataSection.CheckHash      = flags[5];

            textSection.ReadSegmentHeader(reader);
            reader.ReadUInt32(); // Module offset (TODO)
            rodataSection.ReadSegmentHeader(reader);
            reader.ReadUInt32(); // Module file size
            dataSection.ReadSegmentHeader(reader);
            BssSize = reader.ReadUInt32();
            reader.Read(BuildId, 0, 0x20);
            textSection.CompressedSize   = reader.ReadUInt32();
            rodataSection.CompressedSize = reader.ReadUInt32();
            dataSection.CompressedSize   = reader.ReadUInt32();
            reader.ReadBytes(0x1C); // Padding
            RodataRelativeExtents = new[]
            {
                new RodataRelativeExtent(reader), new RodataRelativeExtent(reader), new RodataRelativeExtent(reader)
            };

            reader.Read(textSection.Hash, 0, 0x20);
            reader.Read(rodataSection.Hash, 0, 0x20);
            reader.Read(dataSection.Hash, 0, 0x20);

            Sections = new[] { textSection, rodataSection, dataSection };
            reader.Close();
        }
示例#6
0
        public Package2(Keyset keyset, Stream stream)
        {
            StreamSource = new SharedStreamSource(stream);
            SharedStream headerStream = StreamSource.CreateStream(0, 0x200);

            KeyRevision = FindKeyGeneration(keyset, headerStream);
            Key         = keyset.Package2Keys[KeyRevision];

            Header = new Package2Header(headerStream, Key);

            PackageSize = BitConverter.ToInt32(Header.Counter, 0) ^ BitConverter.ToInt32(Header.Counter, 8) ^
                          BitConverter.ToInt32(Header.Counter, 12);

            HeaderVersion = Header.Counter[4] ^ Header.Counter[6] ^ Header.Counter[7];

            if (PackageSize != 0x200 + Header.SectionSizes[0] + Header.SectionSizes[1] + Header.SectionSizes[2])
            {
                throw new InvalidDataException("Package2 Header is corrupt!");
            }
        }
示例#7
0
        public Package1(Keyset keyset, Stream stream)
        {
            StreamSource = new SharedStreamSource(stream);
            var reader = new BinaryReader(stream);

            BuildHash = reader.ReadBytes(0x10);
            BuildDate = reader.ReadAscii(0xE);
            Field1E   = reader.ReadUInt16();

            reader.BaseStream.Position = 0x3FE0;
            Pk11Size = reader.ReadInt32();

            reader.BaseStream.Position += 0xC;
            Counter = reader.ReadBytes(0x10);

            // Try decrypting the PK11 blob with all known package1 keys
            Stream encStream = StreamSource.CreateStream(0x4000, Pk11Size);
            var    decBuffer = new byte[0x10];

            for (int i = 0; i < 0x20; i++)
            {
                var dec = new Aes128CtrStream(encStream, keyset.Package1Keys[i], Counter);
                dec.Read(decBuffer, 0, 0x10);

                if (BitConverter.ToUInt32(decBuffer, 0) == Pk11Magic)
                {
                    KeyRevision = i;

                    dec.Position = 0;
                    Pk11         = new Pk11(new RandomAccessSectorStream(dec));

                    return;
                }
            }

            throw new InvalidDataException("Failed to decrypt PK11! Is the correct key present?");
        }
示例#8
0
        public Savefile(Keyset keyset, Stream file, bool enableIntegrityChecks)
        {
            SavefileSource = new SharedStreamSource(file);

            using (var reader = new BinaryReader(SavefileSource.CreateStream(), Encoding.Default, true))
            {
                Header = new Header(keyset, reader);
                FsLayout layout = Header.Layout;

                FileRemap = new RemapStream(
                    SavefileSource.CreateStream(layout.FileMapDataOffset, layout.FileMapDataSize),
                    Header.FileMapEntries, Header.FileRemap.MapSegmentCount);

                FileRemapSource = new SharedStreamSource(FileRemap);

                var duplexLayers = new DuplexFsLayerInfo[3];

                duplexLayers[0] = new DuplexFsLayerInfo
                {
                    DataA = new MemoryStream(Header.DuplexMasterA),
                    DataB = new MemoryStream(Header.DuplexMasterB),
                    Info  = Header.Duplex.Layers[0]
                };

                duplexLayers[1] = new DuplexFsLayerInfo
                {
                    DataA = FileRemapSource.CreateStream(layout.DuplexL1OffsetA, layout.DuplexL1Size),
                    DataB = FileRemapSource.CreateStream(layout.DuplexL1OffsetB, layout.DuplexL1Size),
                    Info  = Header.Duplex.Layers[1]
                };

                duplexLayers[2] = new DuplexFsLayerInfo
                {
                    DataA = FileRemapSource.CreateStream(layout.DuplexDataOffsetA, layout.DuplexDataSize),
                    DataB = FileRemapSource.CreateStream(layout.DuplexDataOffsetB, layout.DuplexDataSize),
                    Info  = Header.Duplex.Layers[2]
                };

                DuplexL1A   = FileRemapSource.CreateStream(layout.DuplexL1OffsetA, layout.DuplexL1Size);
                DuplexL1B   = FileRemapSource.CreateStream(layout.DuplexL1OffsetB, layout.DuplexL1Size);
                DuplexDataA = FileRemapSource.CreateStream(layout.DuplexDataOffsetA, layout.DuplexDataSize);
                DuplexDataB = FileRemapSource.CreateStream(layout.DuplexDataOffsetB, layout.DuplexDataSize);
                JournalData = FileRemapSource.CreateStream(layout.JournalDataOffset, layout.JournalDataSizeB + layout.SizeReservedArea);

                DuplexData      = new LayeredDuplexFs(duplexLayers, Header.Layout.DuplexIndex == 1);
                MetaRemap       = new RemapStream(DuplexData, Header.MetaMapEntries, Header.MetaRemap.MapSegmentCount);
                MetaRemapSource = new SharedStreamSource(MetaRemap);

                JournalTable = MetaRemapSource.CreateStream(layout.JournalTableOffset, layout.JournalTableSize);
                JournalBitmapUpdatedPhysical = MetaRemapSource.CreateStream(layout.JournalBitmapUpdatedPhysicalOffset, layout.JournalBitmapUpdatedPhysicalSize);
                JournalBitmapUpdatedVirtual  = MetaRemapSource.CreateStream(layout.JournalBitmapUpdatedVirtualOffset, layout.JournalBitmapUpdatedVirtualSize);
                JournalBitmapUnassigned      = MetaRemapSource.CreateStream(layout.JournalBitmapUnassignedOffset, layout.JournalBitmapUnassignedSize);
                JournalLayer1Hash            = MetaRemapSource.CreateStream(layout.IvfcL1Offset, layout.IvfcL1Size);
                JournalLayer2Hash            = MetaRemapSource.CreateStream(layout.IvfcL2Offset, layout.IvfcL2Size);
                JournalLayer3Hash            = MetaRemapSource.CreateStream(layout.IvfcL3Offset, layout.IvfcL3Size);
                JournalFat      = MetaRemapSource.CreateStream(layout.FatOffset, layout.FatSize);
                AllocationTable = new AllocationTable(JournalFat);

                MappingEntry[] journalMap = JournalStream.ReadMappingEntries(JournalTable, Header.Journal.MainDataBlockCount);

                SharedStream journalData = FileRemapSource.CreateStream(layout.JournalDataOffset,
                                                                        layout.JournalDataSizeB + layout.SizeReservedArea);
                JournalStream       = new JournalStream(journalData, journalMap, (int)Header.Journal.BlockSize);
                JournalStreamSource = new SharedStreamSource(JournalStream);

                IvfcStream       = InitIvfcStream(enableIntegrityChecks);
                IvfcStreamSource = new SharedStreamSource(IvfcStream);

                ReadFileInfo();
                var dictionary = new Dictionary <string, FileEntry>();
                foreach (FileEntry entry in Files)
                {
                    dictionary[entry.FullPath] = entry;
                }

                FileDict = dictionary;
            }
        }
示例#9
0
        public Header(Keyset keyset, SharedStreamSource streamSource)
        {
            var reader = new BinaryReader(streamSource.CreateStream());

            reader.BaseStream.Position = 0;
            Data = reader.ReadBytes(0x4000);
            reader.BaseStream.Position = 0;

            Cmac = reader.ReadBytes(0x10);

            reader.BaseStream.Position = 0x100;
            Layout = new FsLayout(reader);

            reader.BaseStream.Position = 0x300;
            Duplex = new DuplexHeader(reader);

            reader.BaseStream.Position = 0x344;
            Ivfc = new IvfcHeader(reader);

            reader.BaseStream.Position = 0x408;
            Journal = new JournalHeader(reader);

            reader.BaseStream.Position = 0x608;
            Save = new SaveHeader(reader);

            reader.BaseStream.Position = 0x650;
            FileRemap = new RemapHeader(reader);
            reader.BaseStream.Position = 0x690;
            MetaRemap = new RemapHeader(reader);

            reader.BaseStream.Position = 0x6D8;
            ExtraData = new ExtraData(reader);

            reader.BaseStream.Position = Layout.IvfcMasterHashOffsetA;
            MasterHashA = reader.ReadBytes((int)Layout.IvfcMasterHashSize);
            reader.BaseStream.Position = Layout.IvfcMasterHashOffsetB;
            MasterHashB = reader.ReadBytes((int)Layout.IvfcMasterHashSize);

            MasterHash = streamSource.CreateStream(Layout.IvfcMasterHashOffsetA, Layout.IvfcMasterHashSize);

            reader.BaseStream.Position = Layout.DuplexMasterOffsetA;
            DuplexMasterA = reader.ReadBytes((int)Layout.DuplexMasterSize);
            reader.BaseStream.Position = Layout.DuplexMasterOffsetB;
            DuplexMasterB = reader.ReadBytes((int)Layout.DuplexMasterSize);

            reader.BaseStream.Position = Layout.FileMapEntryOffset;
            FileMapEntries             = new MapEntry[FileRemap.MapEntryCount];
            for (int i = 0; i < FileRemap.MapEntryCount; i++)
            {
                FileMapEntries[i] = new MapEntry(reader);
            }

            reader.BaseStream.Position = Layout.MetaMapEntryOffset;
            MetaMapEntries             = new MapEntry[MetaRemap.MapEntryCount];
            for (int i = 0; i < MetaRemap.MapEntryCount; i++)
            {
                MetaMapEntries[i] = new MapEntry(reader);
            }

            HeaderHashValidity = Crypto.CheckMemoryHashTable(Data, Layout.Hash, 0x300, 0x3d00);
            SignatureValidity  = ValidateSignature(keyset);
        }