Пример #1
0
        uint GetContentKey(ArcView file, List<Entry> dir, EncryptionScheme scheme)
        {
            if (null != scheme.ContentKey)
                return scheme.ContentKey.Value;

            if ("system.arc".Equals (Path.GetFileName (file.Name), StringComparison.InvariantCultureIgnoreCase))
            {
                return ReadSysenvSeed (file, dir, scheme.IndexKey);
            }
            else
            {
                var system_arc = VFS.CombinePath (VFS.GetDirectoryName (file.Name), "system.arc");
                using (var arc = VFS.OpenView (system_arc))
                {
                    var header = arc.View.ReadBytes (0, 0x30);
                    Decrypt (header, 0, scheme.IndexKey);
                    using (var arc_file = ReadIndex (arc, header, scheme))
                    {
                        return ReadSysenvSeed (arc, arc_file.Dir, scheme.IndexKey);
                    }
                }
            }
        }
Пример #2
0
 AzArchive ReadIndex(ArcView file, byte[] header, EncryptionScheme scheme)
 {
     int ext_count = LittleEndian.ToInt32 (header, 4);
     int count = LittleEndian.ToInt32 (header, 8);
     uint index_length = LittleEndian.ToUInt32 (header, 12);
     if (ext_count < 1 || ext_count > 8 || !IsSaneCount (count) || index_length >= file.MaxOffset)
         return null;
     var packed_index = file.View.ReadBytes (header.Length, index_length);
     if (packed_index.Length != index_length)
         return null;
     Decrypt (packed_index, header.Length, scheme.IndexKey);
     uint checksum = LittleEndian.ToUInt32 (packed_index, 0);
     if (checksum != Adler32.Compute (packed_index, 4, packed_index.Length-4))
     {
         if (checksum != Crc32.Compute (packed_index, 4, packed_index.Length-4))
             throw new InvalidFormatException ("Index checksum mismatch");
     }
     using (var input = new MemoryStream (packed_index, 4, packed_index.Length-4))
     {
         var dir = ParseIndex (input, count, header.Length + index_length, file.MaxOffset);
         if (null == dir)
             return null;
         uint content_key = GetContentKey (file, dir, scheme);
         return new AzArchive (file, this, dir, scheme.IndexKey, content_key);
     }
 }
Пример #3
0
 public override ArcFile TryOpen(ArcView file)
 {
     byte[] header_encrypted = file.View.ReadBytes (0, 0x30);
     if (header_encrypted.Length < 0x30)
         return null;
     byte[] header = new byte[header_encrypted.Length];
     if (CurrentScheme != null)
     {
         try
         {
             Buffer.BlockCopy (header_encrypted, 0, header, 0, header.Length);
             Decrypt (header, 0, CurrentScheme.IndexKey);
             if (Binary.AsciiEqual (header, 0, "ARC\0"))
             {
                 var arc = ReadIndex (file, header, CurrentScheme);
                 if (null != arc)
                     return arc;
             }
         }
         catch { /* ignore parse errors */ }
     }
     foreach (var scheme in KnownSchemes.Values)
     {
         Buffer.BlockCopy (header_encrypted, 0, header, 0, header.Length);
         Decrypt (header, 0, scheme.IndexKey);
         if (Binary.AsciiEqual (header, 0, "ARC\0"))
         {
             var arc = ReadIndex (file, header, scheme);
             if (null != arc)
                 CurrentScheme = new EncryptionScheme (arc.SysenvKey, arc.RegularKey);
             return arc;
         }
     }
     return null;
 }