Example #1
0
        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();
        }
Example #2
0
        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());
        }