Beispiel #1
0
 public CsafStream(CsafArchive arc)
 {
     m_length     = arc.File.MaxOffset;
     m_view       = arc.File.CreateFrame();
     m_encryption = arc.Encryption;
 }
Beispiel #2
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();
                }
            }
        }
Beispiel #3
0
 public CsafArchive(ArcView arc, ArchiveFormat impl, ICollection <Entry> dir, CsafEncryption enc)
     : base(arc, impl, dir)
 {
     Encryption = enc;
 }