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); }
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)); } } } }
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); }