예제 #1
0
        private Stream OpenV3Entry(ArcFile arc, PakEntry entry)
        {
            uint enc_size = Math.Min(entry.Size, 0x10u);

            if (0 == enc_size)
            {
                return(Stream.Null);
            }
            var  buf = arc.File.View.ReadBytes(entry.Offset, enc_size);
            uint key = entry.Key;

            for (int i = 0; i < buf.Length; ++i)
            {
                buf[i] ^= (byte)key;
                key     = Binary.RotR(key, 8);
            }
            if (enc_size == entry.Size)
            {
                return(new BinMemoryStream(buf, entry.Name));
            }
            return(new PrefixStream(buf, arc.File.CreateStream(entry.Offset + enc_size, entry.Size - enc_size)));
        }
예제 #2
0
        private List <Entry> OpenPakV3(ArcView file)
        {
            if (0x110 > file.View.Reserve(4, 0x110))
            {
                return(null);
            }

            uint size_xor = file.View.ReadUInt32(0x104);

            if (0x64 != size_xor)
            {
                return(null);
            }
            byte[] name_buf = file.View.ReadBytes(4, 0x100);
            int    name_len = 0;

            for (int i = 0; i < name_buf.Length; ++i)
            {
                if (0 == name_buf[i])
                {
                    break;
                }
                if (name_buf[i] >= 0x80 || name_buf[i] < 0x20)
                {
                    return(null);
                }
                ++name_len;
            }
            if (0 == name_len || name_len > 0x10)
            {
                return(null);
            }

            uint header_key = GetKey(name_buf, name_len);
            uint unpacked   = file.View.ReadUInt32(0x108) ^ header_key;
            int  count      = (int)(file.View.ReadUInt32(0x10c) ^ header_key);

            if (!IsSaneCount(count))
            {
                return(null);
            }

            var  dir         = new List <Entry> (count);
            uint header_size = file.View.ReadUInt32(0x110) ^ size_xor;
            long base_offset = 0x114 + header_size;
            var  input       = file.CreateStream(0x114, header_size);

            using (var header_stream = new ZLibStream(input, CompressionMode.Decompress))
                using (var header = new BinaryReader(header_stream, Encoding.ASCII, true))
                {
                    for (int i = 0; i < count; ++i)
                    {
                        name_len = header.ReadInt32();
                        if (name_len <= 0 || name_len > name_buf.Length)
                        {
                            return(null);
                        }
                        if (name_len != header.Read(name_buf, 0, name_len))
                        {
                            return(null);
                        }
                        uint key    = GetKey(name_buf, name_len);
                        uint offset = header.ReadUInt32() ^ key;
                        uint size   = header.ReadUInt32() ^ key;
                        uint val1   = header.ReadUInt32() ^ key;
                        uint val2   = header.ReadUInt32() ^ key;
                        uint val3   = header.ReadUInt32() ^ key;

                        var entry = new PakEntry {
                            Name   = Encodings.cp932.GetString(name_buf, 0, name_len),
                            Offset = base_offset + offset,
                            Size   = size,
                            Key    = key,
                        };
                        if (!entry.CheckPlacement(file.MaxOffset))
                        {
                            return(null);
                        }
                        entry.Type = FormatCatalog.Instance.GetTypeFromName(entry.Name);
                        dir.Add(entry);
                    }
                    return(dir);
                }
        }