Пример #1
0
        public override ArcFile TryOpen(ArcView file)
        {
            var key = FindKey(file);

            if (null == key)
            {
                return(null);
            }
            uint signature_key = key.ToUInt32(0);
            int  count         = (int)(file.View.ReadUInt32(0) ^ signature_key);

            if (!IsSaneCount(count))
            {
                return(null);
            }
            uint index_size = 32 * (uint)count;

            using (var enc = file.CreateStream(0x10, index_size))
                using (var input = new ByteStringEncryptedStream(enc, key))
                    using (var index = new BinaryStream(input, file.Name))
                    {
                        var reader = new IndexReader(file.MaxOffset);
                        var dir    = reader.Read(index, count);
                        if (null == dir)
                        {
                            return(null);
                        }
                        return(new ActressArchive(file, this, dir, key));
                    }
        }
Пример #2
0
 ArcFile ReadIndex(ArcView file, uint[] key, int count)
 {
     using (var input = file.CreateStream(8, (uint)count * 0x80u))
         using (var dec = new ByteStringEncryptedStream(input, GetKeyBytes(key)))
             using (var index = new BinaryStream(dec, file.Name))
             {
                 var dir = new List <Entry> (count);
                 for (int i = 0; i < count; ++i)
                 {
                     var name = index.ReadCString(0x74);
                     if (0 == name.Length)
                     {
                         return(null);
                     }
                     var entry = FormatCatalog.Instance.Create <Pkg2Entry> (name);
                     entry.Size          = index.ReadUInt32();
                     entry.Offset        = index.ReadUInt32();
                     entry.EncryptedSize = index.ReadUInt32();
                     if (!entry.CheckPlacement(file.MaxOffset))
                     {
                         return(null);
                     }
                     dir.Add(entry);
                 }
                 return(new Pkg2Archive(file, this, dir, key));
             }
 }
Пример #3
0
        IBinaryStream UnpackStream(IBinaryStream file)
        {
            Stream input = new ByteStringEncryptedStream(file.AsStream, Key, true);

            input = new ZLibStream(input, CompressionMode.Decompress);
            return(new BinaryStream(input, file.Name));
        }
Пример #4
0
        IBinaryStream OpenJpegStream(IBinaryStream file)
        {
            Stream input = new StreamRegion(file.AsStream, 5, true);

            input = new ByteStringEncryptedStream(input, DefaultKey);
            return(new BinaryStream(input, file.Name));
        }
Пример #5
0
        Stream DecryptImage(LinkArchive arc, LinkEntry entry, uint data_offset)
        {
            var    header = arc.File.View.ReadBytes(entry.Offset, data_offset);
            Stream body   = arc.File.CreateStream(entry.Offset + data_offset, entry.Size - data_offset);

            body = new ByteStringEncryptedStream(body, m_key);
            return(new PrefixStream(header, body));
        }
Пример #6
0
        internal static void UnpackLz(IBinaryStream input, byte[] output, int dst = 0)
        {
            byte id = input.ReadUInt8();

            if (id != 0xC0)
            {
                if ((id ^ DefaultKey[0]) == 0xC0)
                {
                    Stream decrypted = input.AsStream;
                    long   start_pos = input.Position;
                    if (start_pos != 1)
                    {
                        decrypted = new StreamRegion(decrypted, start_pos - 1);
                    }
                    decrypted      = new ByteStringEncryptedStream(decrypted, DefaultKey);
                    input          = new BinaryStream(decrypted, input.Name);
                    input.Position = 1;
                }
                else
                {
                    if (id != 0)
                    {
                        throw new InvalidFormatException();
                    }
                    input.Read(output, 0, output.Length);
                    return;
                }
            }
            int ctl  = 0;
            int mask = 0;

            while (dst < output.Length)
            {
                if (0 == mask)
                {
                    ctl = input.ReadByte();
                    if (-1 == ctl)
                    {
                        break;
                    }
                    mask = 0x80;
                }
                if ((ctl & mask) != 0)
                {
                    int offset = input.ReadUInt8() << 8;
                    offset |= input.ReadUInt8();
                    int count = (offset & 0x1F) + 3;
                    offset = (offset >> 5) + 1;
                    Binary.CopyOverlapped(output, dst - offset, dst, count);
                    dst += count;
                }
                else
                {
                    output[dst++] = Binary.RotByteL(input.ReadUInt8(), 5);
                }
                mask >>= 1;
            }
        }
Пример #7
0
        List <Entry> ReadIndex(ArcView file, byte[] key = null)
        {
            bool is_encrypted = key != null;
            uint index_offset = file.View.ReadUInt32(file.MaxOffset - 4);

            if (index_offset >= file.MaxOffset)
            {
                return(null);
            }
            int index_size = file.View.ReadInt32(index_offset);

            if (index_size <= 0)
            {
                return(null);
            }
            var    index = new byte[index_size];
            Stream input = file.CreateStream(index_offset + 4);

            if (is_encrypted)
            {
                input = new ByteStringEncryptedStream(input, key);
            }
            using (var packed = BinaryStream.FromStream(input, ""))
                LzUnpack(packed, index);
            var  dir       = new List <Entry>();
            int  index_pos = 0;
            uint offset    = LittleEndian.ToUInt32(index, index_pos);

            while (index_pos < index.Length)
            {
                index_pos += 4;
                int name_length = index[index_pos];
                if (0 == name_length)
                {
                    break;
                }
                bool is_packed = index[index_pos + 1] != 0;
                index_pos   += 6;
                name_length *= 2;
                var name = Encoding.Unicode.GetString(index, index_pos, name_length);
                index_pos += name_length;
                uint next_offset = LittleEndian.ToUInt32(index, index_pos);
                var  entry       = FormatCatalog.Instance.Create <PackedEntry> (name);
                entry.Offset   = offset;
                entry.Size     = next_offset - offset;
                entry.IsPacked = is_packed;
                if (!entry.CheckPlacement(index_offset))
                {
                    return(null);
                }
                dir.Add(entry);
                offset = next_offset;
            }
            return(dir);
        }
Пример #8
0
        public override Stream OpenEntry(ArcFile arc, Entry entry)
        {
            var    emic  = arc as EmicArchive;
            Stream input = arc.File.CreateStream(entry.Offset, entry.Size);

            if (null != emic)
            {
                input = new ByteStringEncryptedStream(input, entry.Offset, emic.Key);
            }
            return(input);
        }
Пример #9
0
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32(0);

            if (!IsSaneCount(count))
            {
                return(null);
            }
            if (0 != (file.View.ReadInt32(4) | file.View.ReadInt32(8) | file.View.ReadInt32(12)))
            {
                return(null);
            }
            const int     entry_size   = 0x20;
            uint          index_length = (uint)(count * entry_size);
            IBinaryStream input        = file.CreateStream(0x10, index_length);

            try
            {
                uint   first_offset  = 0x10u + index_length;
                uint   actual_offset = input.Signature;
                byte[] key           = null;
                if (actual_offset != first_offset)
                {
                    key = FindKey(first_offset, actual_offset);
                    if (null == key)
                    {
                        return(null);
                    }
                    var decrypted = new ByteStringEncryptedStream(input.AsStream, key);
                    input = new BinaryStream(decrypted, file.Name);
                }
                var reader = new IndexReader(file.MaxOffset);
                var dir    = reader.Read(input, count);
                if (null == dir)
                {
                    return(null);
                }
                if (null == key)
                {
                    return(new ArcFile(file, this, dir));
                }
                else
                {
                    return(new ActressArchive(file, this, dir, key));
                }
            }
            finally
            {
                input.Dispose();
            }
        }
Пример #10
0
        protected override ImageData GetImageData()
        {
            m_input.Position = 0x10;
            var pixels = new byte[Info.Width * Info.Height * 4];

            using (var lzs = new ByteStringEncryptedStream(m_input.AsStream, m_key, true))
                using (var input = new LzssStream(lzs))
                {
                    if (pixels.Length != input.Read(pixels, 0, pixels.Length))
                    {
                        throw new InvalidFormatException();
                    }
                    var format = m_has_alpha ? PixelFormats.Bgra32 : PixelFormats.Bgr32;
                    return(ImageData.Create(Info, format, null, pixels));
                }
        }
Пример #11
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.Name.HasExtension(".pkg"))
            {
                return(null);
            }
            uint key = file.View.ReadUInt32(0x84);  // last bytes of the first entry name

            if (key != file.View.ReadUInt32(0x10C)) // keys of the first two entries supposed to be the same
            {
                return(null);
            }
            int count = (int)(file.View.ReadUInt32(4) ^ key);

            if (!IsSaneCount(count))
            {
                return(null);
            }
            var key_bytes = new byte[4];

            LittleEndian.Pack(key, key_bytes, 0);
            using (var input = file.CreateStream())
                using (var dec = new ByteStringEncryptedStream(input, key_bytes))
                    using (var index = new BinaryStream(dec, file.Name))
                    {
                        index.Position = 8;
                        var dir = new List <Entry> (count);
                        for (int i = 0; i < count; ++i)
                        {
                            var name  = index.ReadCString(0x80);
                            var entry = FormatCatalog.Instance.Create <Entry> (name);
                            entry.Size   = index.ReadUInt32();
                            entry.Offset = index.ReadUInt32();
                            if (!entry.CheckPlacement(file.MaxOffset))
                            {
                                return(null);
                            }
                            dir.Add(entry);
                        }
                        return(new PkgArchive(file, this, dir, key_bytes));
                    }
        }
Пример #12
0
        public override SoundInput TryOpen(IBinaryStream file)
        {
            if (!file.Name.HasAnyOfExtensions(RequiredExtensions))
            {
                return(null);
            }
            var ext = Path.GetExtension(file.Name).TrimStart('.').ToLowerInvariant();

            byte[] key;
            if (!DefaultKeys.TryGetValue(ext, out key))
            {
                return(null);
            }
            var    header     = file.ReadHeader(0x14);
            int    fmt_length = header.ToInt32(0x10);
            int    data_pos   = 0x14 + fmt_length;
            var    wav_header = file.ReadHeader(data_pos + 8).ToArray();
            Stream data       = new StreamRegion(file.AsStream, file.Position);

            data = new ByteStringEncryptedStream(data, key);
            data = new PrefixStream(wav_header, data);
            return(new WaveInput(data));
        }
Пример #13
0
        public override ArcFile TryOpen(ArcView file)
        {
            long idx_offset = file.MaxOffset - 32;

            if (idx_offset <= 0)
            {
                return(null);
            }
            if (!file.View.AsciiEqual(idx_offset, "STKFile0PIDX") ||
                !file.View.AsciiEqual(idx_offset + 16, "STKFile0PACKFILE"))
            {
                return(null);
            }
            uint idx_size = file.View.ReadUInt32(idx_offset + 12);

            if (idx_size > idx_offset)
            {
                return(null);
            }
            idx_offset -= idx_size;
            var key = QueryKey(file.Name);

            if (null == key)
            {
                return(null);
            }
            Stream input = file.CreateStream(idx_offset, idx_size);

            input          = new ByteStringEncryptedStream(input, key);
            input.Position = 4;
            using (input = new ZLibStream(input, CompressionMode.Decompress))
                using (var index = new BinaryStream(input, file.Name))
                {
                    var name_buffer = new byte[0x100];
                    var dir         = new List <Entry>();
                    while (index.PeekByte() != -1)
                    {
                        int name_length = index.ReadUInt16() * 2;
                        if (0 == name_length)
                        {
                            break;
                        }
                        if (name_length > name_buffer.Length)
                        {
                            name_buffer = new byte[name_length];
                        }
                        index.Read(name_buffer, 0, name_length);
                        var name  = Encoding.Unicode.GetString(name_buffer, 0, name_length);
                        var entry = Create <GpkEntry> (name);

                        index.ReadInt32();
                        index.ReadInt16();
                        entry.Offset = index.ReadUInt32();
                        entry.Size   = index.ReadUInt32();
                        if (!entry.CheckPlacement(file.MaxOffset))
                        {
                            return(null);
                        }
                        index.ReadInt32();
                        entry.UnpackedSize = index.ReadUInt32();
                        entry.IsPacked     = entry.UnpackedSize != 0;
                        int header_length = index.ReadUInt8();
                        if (header_length > 0)
                        {
                            entry.Header = index.ReadBytes(header_length);
                        }
                        dir.Add(entry);
                    }
                    if (0 == dir.Count)
                    {
                        return(null);
                    }
                    return(new ArcFile(file, this, dir));
                }
        }
Пример #14
0
        public override ArcFile TryOpen(ArcView file)
        {
            byte[] key;
            int    count        = file.View.ReadInt32(0x28);
            uint   is_encrypted = file.View.ReadUInt32(4);

            if (IsSaneCount(count) && is_encrypted <= 1)
            {
                key = file.View.ReadBytes(8, 0x20);
                for (int i = 0; i < key.Length; ++i)
                {
                    key[i] ^= 0xAA;
                }
            }
            else
            {
                count        = file.View.ReadInt32(4);
                is_encrypted = file.View.ReadUInt32(8);
                if (!IsSaneCount(count) || is_encrypted > 1)
                {
                    return(null);
                }
                key = file.View.ReadBytes(0xC, 0x20);
                for (int i = 0; i < key.Length; ++i)
                {
                    key[i] ^= 0xAB;
                }
            }
            Stream input = file.CreateStream();

            if (1 == is_encrypted)
            {
                input = new ByteStringEncryptedStream(input, 0, key);
            }
            using (var reader = new BinaryReader(input))
            {
                input.Position = 0x2C;
                var index_buf = new byte[0x108];
                var dir       = new List <Entry> (count);
                for (int i = 0; i < count; ++i)
                {
                    int name_len = reader.ReadInt32();
                    if (name_len <= 0 || name_len > index_buf.Length) // file name is too long
                    {
                        return(null);
                    }
                    if (name_len != reader.Read(index_buf, 0, name_len))
                    {
                        return(null);
                    }
                    string name  = Binary.GetCString(index_buf, 0, name_len);
                    var    entry = FormatCatalog.Instance.Create <Entry> (name);
                    entry.Size   = reader.ReadUInt32();
                    entry.Offset = reader.ReadUInt32();
                    if (!entry.CheckPlacement(file.MaxOffset))
                    {
                        return(null);
                    }
                    dir.Add(entry);
                }
                if (1 == is_encrypted)
                {
                    return(new EmicArchive(file, this, dir, key));
                }
                else
                {
                    return(new ArcFile(file, this, dir));
                }
            }
        }