Пример #1
0
        ArcFile Open(byte[] basename, ArcView file, EncryptionScheme scheme, Key key)
        {
            uint key1 = scheme.BaseKey.Key1;
            uint key2 = scheme.BaseKey.Key2;

            for (int b = 0, e = basename.Length - 1; e >= 0; ++b, --e)
            {
                key1 ^= basename[e];
                key2 ^= basename[b];
                key1  = Binary.RotR(key1, 7);
                key2  = Binary.RotL(key2, 7);
            }
            if (null != key)
            {
                key1 ^= key.Key1;
                key2 ^= key.Key2;
            }
            uint code       = file.View.ReadUInt32(4) ^ key2;
            int  index_size = (int)(code & 0xffffff);
            byte flags      = (byte)(code >> 24);

            if (0 != (flags & 1))
            {
                index_size = (index_size << 11) - 8;
            }
            if (index_size < 5 || index_size >= file.MaxOffset)
            {
                return(null);
            }
            var index = new byte[index_size];

            if (index_size != file.View.Read(8, index, 0, (uint)index_size))
            {
                return(null);
            }
            scheme.DecryptIndex(index, index_size, key2);
            var lpk_info = new LpkInfo
            {
                AlignedOffset = 0 != (flags & 1),
                Flag1         = 0 != (flags & 2),
                IsEncrypted   = 0 != (flags & 4),
                PackedEntries = 0 != (flags & 8),
                WholeCrypt    = 0 != (flags & 0x10),
                Key           = key1
            };
            var reader = new IndexReader(lpk_info);
            var dir    = reader.Read(index);

            if (null == dir)
            {
                return(null);
            }
            // this condition is fishy, probably patch files have additional bitflag set
            if (lpk_info.WholeCrypt && Binary.AsciiEqual(basename, "PATCH"))
            {
                lpk_info.WholeCrypt = false;
            }
            return(new LuciArchive(file, this, dir, scheme, reader.Info));
        }
Пример #2
0
 public IndexReader(LpkInfo info)
 {
     if (!info.Flag1)
     {
         throw new NotSupportedException("Not supported LPK index format");
     }
     m_info    = info;
     EntrySize = m_info.PackedEntries ? 13 : 9;
 }
Пример #3
0
 public LuciArchive(ArcView arc, ArchiveFormat impl, ICollection <Entry> dir, EncryptionScheme scheme, LpkInfo info)
     : base(arc, impl, dir)
 {
     Info   = info;
     Scheme = scheme;
 }
Пример #4
0
 public LuciArchive(ArcView arc, ArchiveFormat impl, ICollection<Entry> dir, EncryptionScheme scheme, LpkInfo info)
     : base(arc, impl, dir)
 {
     Info = info;
     Scheme = scheme;
 }
Пример #5
0
 public IndexReader(LpkInfo info)
 {
     if (!info.Flag1)
         throw new NotSupportedException ("Not supported LPK index format");
     m_info = info;
     EntrySize = m_info.PackedEntries ? 13 : 9;
 }
Пример #6
0
 ArcFile Open(byte[] basename, ArcView file, EncryptionScheme scheme, Key key)
 {
     uint key1 = scheme.BaseKey.Key1;
     uint key2 = scheme.BaseKey.Key2;
     for (int b = 0, e = basename.Length-1; e >= 0; ++b, --e)
     {
         key1 ^= basename[e];
         key2 ^= basename[b];
         key1 = Binary.RotR (key1, 7);
         key2 = Binary.RotL (key2, 7);
     }
     if (null != key)
     {
         key1 ^= key.Key1;
         key2 ^= key.Key2;
     }
     uint code = file.View.ReadUInt32 (4) ^ key2;
     int index_size = (int)(code & 0xffffff);
     byte flags = (byte)(code >> 24);
     if (0 != (flags & 1))
         index_size = (index_size << 11) - 8;
     if (index_size < 5 || index_size >= file.MaxOffset)
         return null;
     var index = new byte[index_size];
     if (index_size != file.View.Read (8, index, 0, (uint)index_size))
         return null;
     DecryptIndex (index, index_size, key2, scheme.RotatePattern);
     var lpk_info = new LpkInfo
     {
         AlignedOffset = 0 != (flags & 1),
         Flag1         = 0 != (flags & 2),
         IsEncrypted   = 0 != (flags & 4),
         PackedEntries = 0 != (flags & 8),
         WholeCrypt    = 0 != (flags & 0x10),
         Key           = key1
     };
     var reader = new IndexReader (lpk_info);
     var dir = reader.Read (index);
     if (null == dir)
         return null;
     // this condition is fishy, probably patch files have additional bitflag set
     if (lpk_info.WholeCrypt && Binary.AsciiEqual (basename, "PATCH"))
         lpk_info.WholeCrypt = false;
     return new LuciArchive (file, this, dir, scheme, reader.Info);
 }