Example #1
0
        private FileSet ReadFileSet(Stream stream, string name)
        {
            FileSet fileSet = new FileSet(name);

            using (BinaryReader reader = new BinaryReader(stream)) {
                SectionSet fileSetSections = SectionIO.ReadAll(reader);

                PACKFSHD fileSetHeader    = fileSetSections.Get <PACKFSHD>();
                GENESTRT fileSetNameTable = fileSetSections.Get <GENESTRT>();

                foreach (PACKFSHD.FileEntry fEntry in fileSetHeader.Files)
                {
                    string fName   = fileSetNameTable.Strings[(int)fEntry.NameIndex];
                    byte[] rawData = new byte[fEntry.CompressedSize];
                    stream.Seek((long)fEntry.Offset, SeekOrigin.Begin);
                    stream.Read(rawData);

                    if (fEntry.Unknown != 0x2)
                    {
                        throw new Exception("Unsupported value of unknown file set file entry field: " + fEntry.Unknown);
                    }

                    fileSet.Files.Add(new File(fName, rawData, true, fEntry.UncompressedSize));
                }
            }

            return(fileSet);
        }
Example #2
0
        public APK(Stream stream)
        {
            using (BinaryReader reader = new BinaryReader(stream)) {
                SectionSet sections = SectionIO.ReadAll(reader);

                // TODO: Figure out what hash is calculated from and validate hash.
                PACKHEDR hedr      = sections.Get <PACKHEDR>();
                GENESTRT nameTable = sections.Get <GENESTRT>();
                this.Name = nameTable.Strings[(int)hedr.NameIndex];

                PACKTOC toc = sections.Get <PACKTOC>();
                this.RootDirectory = this.BuildContentTree(stream, nameTable, toc, (PACKTOC.DirectoryEntry)toc.Entries[0]);

                PACKFSLS fileSetList = sections.Get <PACKFSLS>();
                foreach (PACKFSLS.FileSetEntry entry in fileSetList.FileSets)
                {
                    stream.Seek((long)entry.Offset, SeekOrigin.Begin);
                    byte[] fileSetData = reader.ReadBytes((int)entry.Size);
                    string fileSetName = nameTable.Strings[(int)entry.NameIndex];

                    if (!Enumerable.SequenceEqual(new MD5CryptoServiceProvider().ComputeHash(fileSetData), entry.Hash))
                    {
                        throw new Exception("Hash mismatch in file set \"" + fileSetName + "\".");
                    }

                    using (MemoryStream fileSetStream = new MemoryStream(fileSetData)) {
                        this.FileSets.Add(this.ReadFileSet(fileSetStream, fileSetName));
                    }
                }
            }
        }
Example #3
0
        public GOP(Stream stream)
        {
            SectionSet sections = SectionIO.ReadAll(stream);

            GOPGMET  met  = sections.Get <GOPGMET>();
            GOPGREC  rec  = sections.Get <GOPGREC>();
            GENESTRT strt = sections.Get <GENESTRT>();
            GOPGDAT  dat  = sections.Get <GOPGDAT>();

            foreach (GOPGREC.ElementInfo elementInfo in rec.Elements)
            {
                Element element = new Element();
                element.Name    = strt.Strings[elementInfo.NameIndex];
                element.Type    = elementInfo.Type;
                element.Unknown = elementInfo.Unknown;

                this.Elements.Add(element);
            }

            this.Records = new string[dat.Records.Count, rec.Elements.Count + 1];

            int recordIndex = 0;

            foreach (GOPGDAT.Record record in dat.Records)
            {
                this.Records[recordIndex, 0] = record.Index.ToString();
                using (MemoryStream dataStream = new MemoryStream(record.Data)) {
                    using (BinaryReader dataReader = new BinaryReader(dataStream)) {
                        for (int i = 0; i < rec.Elements.Count; i++)
                        {
                            GOPGREC.ElementInfo elementInfo = rec.Elements[i];
                            dataStream.Seek(elementInfo.Offset, SeekOrigin.Begin);
                            this.Records[recordIndex, i + 1] = ReadElement(dataReader, elementInfo, strt);
                        }
                    }
                }

                recordIndex++;
            }

            this.RootMetric = ConvertToParsedMetric(met.Root, strt);
        }