예제 #1
0
        public override Stream OpenEntry(ArcFile arc, Entry entry)
        {
            var tent = entry as TacEntry;

            if (null == tent)
            {
                return(base.OpenEntry(arc, entry));
            }
            if (tent.IsPacked)
            {
                var input = arc.File.CreateStream(entry.Offset, entry.Size);
                return(new ZLibStream(input, CompressionMode.Decompress));
            }
            var bf = new Blowfish(tent.Key);

            if (tent.EncryptedSize < tent.Size)
            {
                var header = arc.File.View.ReadBytes(tent.Offset, tent.EncryptedSize);
                bf.Decipher(header, header.Length);
                var rest = arc.File.CreateStream(tent.Offset + tent.EncryptedSize, tent.Size - tent.EncryptedSize);
                return(new PrefixStream(header, rest));
            }
            else if (0 == (tent.Size & 7))
            {
                var input = arc.File.CreateStream(tent.Offset, tent.Size);
                return(new InputCryptoStream(input, bf.CreateDecryptor()));
            }
            else
            {
                var data = arc.File.View.ReadBytes(tent.Offset, tent.Size);
                bf.Decipher(data, data.Length & ~7);
                return(new BinMemoryStream(data));
            }
        }
예제 #2
0
파일: ArcPACK.cs 프로젝트: zxc120/GARbro
        public override Stream OpenEntry(ArcFile arc, Entry entry)
        {
            var larc = arc as LunaArchive;

            if (null == arc || !arc.File.View.AsciiEqual(entry.Offset, "LZSS"))
            {
                return(base.OpenEntry(arc, entry));
            }

            uint   unpacked_size = arc.File.View.ReadUInt32(entry.Offset + 4);
            Stream input         = arc.File.CreateStream(entry.Offset + 8, entry.Size - 8);

            if (larc.Key != null)
            {
                var bf = new Blowfish(larc.Key);
                input = new InputCryptoStream(input, bf.CreateDecryptor());
                return(new LimitStream(input, unpacked_size));
            }
            else
            {
                var lz = new LzssStream(input);
                lz.Config.FrameInitPos = 0xFF0;
                return(lz);
            }
        }
예제 #3
0
            public void WriteToStream(Stream writeTo)
            {
                using (var fs = File.OpenRead(sourceFile))
                    using (var br = new BinaryReader(fs)) {
                        fs.Seek(offset, SeekOrigin.Begin);
                        var encrypted = br.ReadBytes(4).SequenceEqual(new byte[] { 0x4C /*L*/, 0x5A /*Z*/, 0x53 /*S*/, 0x53 /*S*/ });

                        byte[] fileBytesToSave;
                        if (encrypted)
                        {
                            var decryptedSize = br.ReadUInt32();
                            var fileBytes     = br.ReadBytes((int)size);
                            fileBytesToSave = new byte[decryptedSize];
                            using (var r = new BinaryReader(new CryptoStream(new MemoryStream(fileBytes, 0, fileBytes.Length),
                                                                             Blowfish.CreateDecryptor(), CryptoStreamMode.Read))) {
                                r.Read(fileBytesToSave, 0, fileBytesToSave.Length);
                            }
                        }
                        else
                        {
                            //Reset Location, so we don't skip first four bytes, after reading FileMagic at LOC:74
                            br.BaseStream.Seek(offset, SeekOrigin.Begin);
                            fileBytesToSave = br.ReadBytes((int)size);
                        }

                        writeTo.Write(fileBytesToSave, 0, fileBytesToSave.Length);
                    }
            }
예제 #4
0
파일: ArcPAZ.cs 프로젝트: minhrg/GARbro
        internal override Stream DecryptEntry(Stream input, PazEntry entry)
        {
            input = new InputCryptoStream(input, Encryption.CreateDecryptor());
            var key = entry.Key;

            if (null == key)
            {
                return(input);
            }
            var rc4 = new Rc4Transform(key);

            if (Version >= 2)
            {
                uint crc         = Crc32.Compute(key, 0, key.Length);
                int  skip_rounds = (int)(crc >> 12) & 0xFF;
                for (int i = 0; i < skip_rounds; ++i)
                {
                    rc4.NextByte();
                }
            }
            return(new InputCryptoStream(input, rc4));
        }
예제 #5
0
파일: ArcPAZ.cs 프로젝트: minhrg/GARbro
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.Name.HasExtension(".paz"))
            {
                return(null);
            }
            uint signature = file.View.ReadUInt32(0);
            // XXX encryption is queried for every .paz file
            var  scheme       = QueryEncryption(file.Name, signature);
            uint start_offset = scheme.Version > 0 ? 0x20u : 0u;
            uint index_size   = file.View.ReadUInt32(start_offset);

            start_offset += 4;
            byte xor_key = (byte)(index_size >> 24);

            if (xor_key != 0)
            {
                index_size ^= (uint)(xor_key << 24 | xor_key << 16 | xor_key << 8 | xor_key);
            }
            if (0 != (index_size & 7) || index_size + start_offset >= file.MaxOffset)
            {
                return(null);
            }

            var  arc_list   = new List <Entry>();
            var  arc_dir    = VFS.GetDirectoryName(file.Name);
            long max_offset = file.MaxOffset;

            for (char suffix = 'A'; suffix <= 'Z'; ++suffix)
            {
                var part_name = VFS.CombinePath(arc_dir, file.Name + suffix);
                if (!VFS.FileExists(part_name))
                {
                    break;
                }
                var part = VFS.FindFile(part_name);
                arc_list.Add(part);
                max_offset += part.Size;
            }
            var    arc_name = Path.GetFileNameWithoutExtension(file.Name).ToLowerInvariant();
            bool   is_audio = AudioPazNames.Contains(arc_name);
            bool   is_video = VideoPazNames.Contains(arc_name);
            Stream input    = file.CreateStream(start_offset, index_size);

            byte[]       video_key = null;
            List <Entry> dir;

            try
            {
                if (xor_key != 0)
                {
                    input = new XoredStream(input, xor_key);
                }
                var enc = new Blowfish(scheme.ArcKeys[arc_name].IndexKey);
                input = new InputCryptoStream(input, enc.CreateDecryptor());
                using (var index = new ArcView.Reader(input))
                {
                    int count = index.ReadInt32();
                    if (!IsSaneCount(count))
                    {
                        return(null);
                    }
                    if (is_video)
                    {
                        video_key = index.ReadBytes(0x100);
                    }

                    dir = new List <Entry> (count);
                    for (int i = 0; i < count; ++i)
                    {
                        var name  = index.BaseStream.ReadCString();
                        var entry = FormatCatalog.Instance.Create <PazEntry> (name);
                        entry.Offset       = index.ReadInt64();
                        entry.UnpackedSize = index.ReadUInt32();
                        entry.Size         = index.ReadUInt32();
                        entry.AlignedSize  = index.ReadUInt32();
                        if (!entry.CheckPlacement(max_offset))
                        {
                            return(null);
                        }
                        entry.IsPacked = index.ReadInt32() != 0;
                        if (string.IsNullOrEmpty(entry.Type) && is_audio)
                        {
                            entry.Type = "audio";
                        }
                        if (scheme.Version > 0)
                        {
                            string password = "";
                            if (!entry.IsPacked && scheme.TypeKeys != null)
                            {
                                password = scheme.GetTypePassword(name, is_audio);
                            }
                            if (!string.IsNullOrEmpty(password) || is_video)
                            {
                                password  = string.Format("{0} {1:X08} {2}", name.ToLowerInvariant(), entry.UnpackedSize, password);
                                entry.Key = Encodings.cp932.GetBytes(password);
                            }
                        }
                        dir.Add(entry);
                    }
                }
            }
            finally
            {
                input.Dispose();
            }
            List <ArcView> parts = null;

            if (arc_list.Count > 0)
            {
                parts = new List <ArcView> (arc_list.Count);
                try
                {
                    foreach (var arc_entry in arc_list)
                    {
                        var arc_file = VFS.OpenView(arc_entry);
                        parts.Add(arc_file);
                    }
                }
                catch
                {
                    foreach (var part in parts)
                    {
                        part.Dispose();
                    }
                    throw;
                }
            }
            if (is_video)
            {
                if (scheme.Version < 1)
                {
                    var table = new byte[0x100];
                    for (int i = 0; i < 0x100; ++i)
                    {
                        table[video_key[i]] = (byte)i;
                    }
                    video_key = table;
                }
                return(new MovPazArchive(file, this, dir, scheme.Version, xor_key, video_key, parts));
            }
            return(new PazArchive(file, this, dir, scheme.Version, xor_key, scheme.ArcKeys[arc_name].DataKey, parts));
        }