public IList<IArchiveFileInfo> Load(Stream input) { using var br = new BinaryReaderX(input, true); // Read sections var sections = ApkSection.ReadAll(input); // Read pack header var packHeader = sections.FirstOrDefault(x => x.Type == ApkSection.PackHeader).As<ApkPackHeader>(); _headerIdent = packHeader.headerIdent; // Read entries var entries = sections.FirstOrDefault(x => x.Type == ApkSection.PackToc).As<ApkToc>().entries; // Read strings using var stringBr = new BinaryReaderX(sections.FirstOrDefault(x => x.Type == ApkSection.StringTable).Data, true); var stringHeader = stringBr.ReadType<ApkStringHeader>(); stringBr.BaseStream.Position = stringHeader.tableOffset; var stringOffsets = stringBr.ReadMultiple<int>(stringHeader.stringCount); var strings = new List<string>(); foreach (var stringOffset in stringOffsets) { stringBr.BaseStream.Position = stringHeader.dataOffset + stringOffset; strings.Add(stringBr.ReadCStringASCII()); } _name = strings[packHeader.stringIndex]; return ApkSupport.EnumerateFiles(new List<Stream> { input }, entries[0], UPath.Root, new List<ApkPackHeader> { packHeader }, strings, entries).ToArray(); }
public IList <IArchiveFileInfo> Load(Stream input, IList <Stream> apkStreams) { using var br = new BinaryReaderX(input, true); // Validate APK streams var tempApkStreams = new List <Stream>(); foreach (var apkStream in apkStreams) { using var apkBr = new BinaryReaderX(apkStream, true); if (apkBr.ReadString(8) == ApkSection.StartSection) { apkStream.Position = 0; tempApkStreams.Add(apkStream); } } apkStreams = tempApkStreams; // Read sections var sections = ApkSection.ReadAll(input); // Read pack headers _apkHeaders = sections .Where(x => x.Type == ApkSection.PackHeader) .Select(x => x.As <ApkPackHeader>()) .ToArray(); // Order streams to pack headers var combinedHeaderStreams = new List <(ApkPackHeader, Stream)>(); foreach (var apkStream in apkStreams) { var apkHeader = ApkSection.ReadAll(apkStream).FirstOrDefault(x => x.Type == ApkSection.PackHeader).As <ApkPackHeader>(); combinedHeaderStreams.Add((apkHeader, apkStream)); } apkStreams = new List <Stream>(); foreach (var apkHeader in _apkHeaders) { apkStreams.Add(combinedHeaderStreams.FirstOrDefault(x => x.Item1.headerIdent.SequenceEqual(apkHeader.headerIdent)).Item2); } // Read entries _entries = sections.FirstOrDefault(x => x.Type == ApkSection.PackToc).As <ApkToc>().entries; // Read strings using var stringBr = new BinaryReaderX(sections.FirstOrDefault(x => x.Type == ApkSection.StringTable).Data, true); var stringHeader = stringBr.ReadType <ApkStringHeader>(); stringBr.BaseStream.Position = stringHeader.tableOffset; var stringOffsets = stringBr.ReadMultiple <int>(stringHeader.stringCount); _strings = new List <string>(); foreach (var stringOffset in stringOffsets) { stringBr.BaseStream.Position = stringHeader.dataOffset + stringOffset; _strings.Add(stringBr.ReadCStringASCII()); } return(ApkSupport.EnumerateFiles(apkStreams, _entries[0], UPath.Root, _apkHeaders, _strings, _entries).ToArray()); }