Exemple #1
0
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32(12);

            if (!IsSaneCount(count))
            {
                return(null);
            }
            int key1index = file.View.ReadUInt16(4);
            int key2index = file.View.ReadUInt16(6);

            if (key2index != 0 && key1index == 0)
            {
                return(null);
            }
            uint index_size = file.View.ReadUInt32(8) - 0x10;

            if (index_size < 0x40 || index_size >= file.MaxOffset)
            {
                return(null);
            }
            var index = new byte[index_size];

            if (index.Length != file.View.Read(0x10, index, 0, index_size))
            {
                return(null);
            }

            /*
             * var key_src = KnownKey;
             * if (key1index >= key_src.Item1.Length || key2index >= key_src.Item2.Length)
             *  return null;
             * byte index_key = (byte)(key_src.Item1[key1index] + key_src.Item2[key2index]);
             */
            var key = GuessKey(file, index);

            if (null == key)
            {
                throw new UnknownEncryptionScheme();
            }
            Decrypt(index, 0, index.Length, key.Value);

            int  current_offset = 0;
            uint next_offset    = LittleEndian.ToUInt32(index, current_offset + 0x1C);
            var  dir            = new List <Entry> (count);

            for (int i = 0; i < count; ++i)
            {
                string name  = Binary.GetCString(index, current_offset, 0x0E);
                var    entry = new MrgEntry
                {
                    Name   = name,
                    Type   = FormatCatalog.Instance.GetTypeFromName(name),
                    Offset = next_offset,
                    Method = index[current_offset + 0x12],
                };
                next_offset = LittleEndian.ToUInt32(index, current_offset + 0x3C);
                entry.Size  = next_offset - (uint)entry.Offset;
                if (entry.Offset < index_size || !entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                entry.IsPacked     = entry.Method != 0;
                entry.UnpackedSize = LittleEndian.ToUInt32(index, current_offset + 0x0E);
                dir.Add(entry);
                current_offset += 0x20;
            }
            return(new ArcFile(file, this, dir));
        }
Exemple #2
0
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32 (12);
            if (!IsSaneCount (count))
                return null;
            int key1index = file.View.ReadUInt16 (4);
            int key2index = file.View.ReadUInt16 (6);
            if (key2index != 0 && key1index == 0)
                return null;
            uint index_size = file.View.ReadUInt32 (8) - 0x10;
            if (index_size < 0x40 || index_size >= file.MaxOffset)
                return null;
            var index = new byte[index_size];
            if (index.Length != file.View.Read (0x10, index, 0, index_size))
                return null;
            /*
            var key_src = KnownKey;
            if (key1index >= key_src.Item1.Length || key2index >= key_src.Item2.Length)
                return null;
            byte index_key = (byte)(key_src.Item1[key1index] + key_src.Item2[key2index]);
            */
            var key = GuessKey (file, index);
            if (null == key)
                throw new UnknownEncryptionScheme();
            Decrypt (index, 0, index.Length, key.Value);

            int current_offset = 0;
            uint next_offset = LittleEndian.ToUInt32 (index, current_offset+0x1C);
            var dir = new List<Entry> (count);
            for (int i = 0; i < count; ++i)
            {
                string name = Binary.GetCString (index, current_offset, 0x0E);
                var entry = new MrgEntry
                {
                    Name = name,
                    Type = FormatCatalog.Instance.GetTypeFromName (name),
                    Offset = next_offset,
                    Method = index[current_offset+0x12],
                };
                next_offset = LittleEndian.ToUInt32 (index, current_offset+0x3C);
                entry.Size = next_offset - (uint)entry.Offset;
                if (entry.Offset < index_size || !entry.CheckPlacement (file.MaxOffset))
                    return null;
                entry.IsPacked = entry.Method != 0;
                entry.UnpackedSize = LittleEndian.ToUInt32 (index, current_offset+0x0E);
                dir.Add (entry);
                current_offset += 0x20;
            }
            return new ArcFile (file, this, dir);
        }