Exemple #1
0
        internal Stream OpenEncryptedEntry(AgsiArchive arc, AgsiEntry entry)
        {
            uint enc_size = entry.Size;

            if (enc_size > 1024)
            {
                enc_size = 1032;
            }
            using (var des = DES.Create())
            {
                des.Key     = arc.Key;
                des.Mode    = CipherMode.ECB;
                des.Padding = PaddingMode.Zeros;
                using (var enc = arc.File.CreateStream(entry.Offset, enc_size))
                    using (var dec = new InputCryptoStream(enc, des.CreateDecryptor()))
                    {
                        var output = new byte[enc_size];
                        dec.Read(output, 0, output.Length);
                        int header_size;
                        if (!entry.IsSpecial)
                        {
                            header_size = output.ToInt32(output.Length - 4);
                            if (header_size > entry.UnpackedSize)
                            {
                                throw new InvalidEncryptionScheme();
                            }
                        }
                        else
                        {
                            header_size = (int)entry.UnpackedSize;
                        }
                        if (!entry.IsSpecial && entry.Size > enc_size)
                        {
                            var header = new byte[header_size];
                            Buffer.BlockCopy(output, 0, header, 0, header_size);
                            var input = arc.File.CreateStream(entry.Offset + enc_size, entry.Size - enc_size);
                            return(new PrefixStream(header, input));
                        }
                        else
                        {
                            return(new BinMemoryStream(output, 0, header_size, entry.Name));
                        }
                    }
            }
        }
Exemple #2
0
 bool ReadBlock()
 {
     if (m_position >= m_length)
     {
         return(false);
     }
     m_block_start  = m_position & ~0xFFFL;
     m_block_length = m_view.Read(m_block_start, m_block, 0, 0x1000);
     if (m_block_length != 0x1000)
     {
         return(false);
     }
     using (var decryptor = m_encryption.CreateDecryptor((int)(m_block_start >> 12)))
         using (var enc = new BinMemoryStream(m_block))
             using (var dec = new InputCryptoStream(enc, decryptor))
                 dec.Read(m_block, 0, m_block_length);
     return(true);
 }
Exemple #3
0
 static byte[] CzDecryptData(byte[] data)
 {
     int padded_size = data.Length - 5;
     int original_size = padded_size - (data[padded_size+1] ^ data[padded_size]);
     uint iv_seed = data.ToUInt32 (padded_size+1) ^ CzIvSeed;
     using (var aes = Aes.Create())
     {
         aes.Mode = CipherMode.CBC;
         aes.Padding = PaddingMode.Zeros;
         aes.Key = CzDefaultKey;
         aes.IV = CzCreateIV (iv_seed);
         using (var enc = new MemoryStream (data, 0, padded_size))
         using (var dec = new InputCryptoStream (enc, aes.CreateDecryptor()))
         {
             var original = new byte[original_size];
             dec.Read (original, 0, original_size);
             return original;
         }
     }
 }
Exemple #4
0
        public override ArcFile TryOpen(ArcView file)
        {
            uint flags = file.View.ReadUInt32(4);

            if ((flags & 0x7FFFFFFF) != 0x10000)
            {
                return(null);
            }
            int count = file.View.ReadInt32(8);

            if (!IsSaneCount(count))
            {
                return(null);
            }
            bool           is_encrypted = (flags >> 31) != 0;
            uint           index_size   = (uint)((count * 24 + 31) & -4096) + 0xFE0u;
            uint           names_size   = file.View.ReadUInt32(12);
            var            arc_md5      = file.View.ReadBytes(0x10, 0x10);
            var            index        = new byte[index_size + names_size];
            CsafEncryption enc          = null;

            try
            {
                if (is_encrypted)
                {
                    file.View.Read(0x20, index, 0, index_size);
                    enc = new CsafEncryption(DefaultKey, DefaultIV);
                    using (var decryptor = enc.CreateDecryptor(0))
                        using (var enc_names = file.CreateStream(0x20 + index_size, names_size))
                            using (var dec_names = new InputCryptoStream(enc_names, decryptor))
                            {
                                dec_names.Read(index, (int)index_size, (int)names_size);
                            }
                }
                else
                {
                    file.View.Read(0x20, index, 0, index_size + names_size);
                }
                using (var md5 = MD5.Create())
                {
                    var hash = md5.ComputeHash(index);
                    if (!hash.SequenceEqual(arc_md5))
                    {
                        return(null);
                    }
                    int index_pos = 0x10;
                    int name_pos  = (int)index_size;
                    var dir       = new List <Entry> (count);
                    for (int i = 0; i < count; ++i)
                    {
                        int j;
                        for (j = name_pos; j + 1 < index.Length; j += 2)
                        {
                            if (index[j] == 0 && index[j + 1] == 0)
                            {
                                break;
                            }
                        }
                        int name_length = j - name_pos;
                        var name        = Encoding.Unicode.GetString(index, name_pos, name_length);
//                        hash = md5.ComputeHash (index, name_pos, name_length); // == [index_pos-0x10]
                        name_pos += name_length + 10;

                        var entry = Create <Entry> (name);
                        entry.Offset = (long)index.ToUInt32(index_pos) << 12;
                        entry.Size   = index.ToUInt32(index_pos + 4);
                        index_pos   += 0x18;
                        if (!entry.CheckPlacement(file.MaxOffset))
                        {
                            return(null);
                        }
                        dir.Add(entry);
                    }
                    if (!is_encrypted)
                    {
                        return(new ArcFile(file, this, dir));
                    }
                    var arc = new CsafArchive(file, this, dir, enc);
                    enc = null;
                    return(arc);
                }
            }
            finally
            {
                if (enc != null)
                {
                    enc.Dispose();
                }
            }
        }