コード例 #1
0
ファイル: ArcCSAF.cs プロジェクト: ziyuejun/GARbro
 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);
 }
コード例 #2
0
ファイル: ArcCSAF.cs プロジェクト: ziyuejun/GARbro
        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();
                }
            }
        }