Beispiel #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;
     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);
 }
Beispiel #2
0
 public LuciArchive(ArcView arc, ArchiveFormat impl, ICollection<Entry> dir, EncryptionScheme scheme, LpkInfo info)
     : base(arc, impl, dir)
 {
     Info = info;
     Scheme = scheme;
 }
Beispiel #3
0
 public override ArcFile TryOpen(ArcView file)
 {
     string name = Path.GetFileName (file.Name).ToUpperInvariant();
     if (string.IsNullOrEmpty (name))
         return null;
     Key file_key = null;
     var basename = Encodings.cp932.GetBytes (Path.GetFileNameWithoutExtension (name));
     if (name != "SCRIPT.LPK")
         CurrentFileMap.TryGetValue (name, out file_key);
     try
     {
         var arc = Open (basename, file, CurrentScheme, file_key);
         if (null != arc)
             return arc;
     }
     catch { /* unknown encryption, ignore parse errors */ }
     var new_scheme = QueryEncryptionScheme();
     if (new_scheme == CurrentScheme && !CurrentScheme.ImportGameInit)
         return null;
     CurrentScheme = new_scheme;
     if (name != "SCRIPT.LPK" && CurrentScheme.ImportGameInit)
     {
         if (0 == CurrentFileMap.Count)
             ImportKeys (file.Name);
     }
     if (CurrentFileMap.Count > 0 && !CurrentFileMap.TryGetValue (name, out file_key))
         return null;
     return Open (basename, file, CurrentScheme, file_key);
 }