Beispiel #1
0
        public override ArcFile TryOpen(ArcView file)
        {
            long index_end = file.MaxOffset - 4;
            uint index_size = file.View.ReadUInt32 (index_end);
            if (0 == index_size || index_size >= index_end)
                return null;

            long index_offset = index_end - index_size;
            if (index_size > file.View.Reserve (index_offset, index_size))
                return null;

            var dir = new List<Entry>();
            while (index_offset < index_end)
            {
                uint name_len = file.View.ReadByte (index_offset++);
                if (0 == name_len)
                    break;
                if (name_len+14 > index_end-index_offset)
                    return null;
                string name = file.View.ReadString (index_offset, name_len);
                index_offset += name_len+6;
                var entry = FormatCatalog.Instance.Create<Entry> (name);
                entry.Size = file.View.ReadUInt32 (index_offset);
                entry.Offset = file.View.ReadUInt32 (index_offset+4);
                if (!entry.CheckPlacement (index_offset))
                    return null;
                dir.Add (entry);
                index_offset += 8;
            }
            if (0 == dir.Count)
                return null;
            return new ArcFile (file, this, dir);
        }
Beispiel #2
0
 public override ArcFile TryOpen(ArcView file)
 {
     if (!file.Name.EndsWith (".pb", StringComparison.InvariantCultureIgnoreCase))
         return null;
     int count = file.View.ReadInt32 (0);
     if (count <= 0 || count > 0xfff)
         return null;
     var dir = new List<Entry> (count);
     int index_offset = 0x10;
     bool is_voice = Path.GetFileName (file.Name).Equals ("voice.pb", StringComparison.InvariantCultureIgnoreCase);
     int data_offset = index_offset + 8 * count;
     for (int i = 0; i < count; ++i)
     {
         uint offset = file.View.ReadUInt32 (index_offset);
         Entry entry;
         if (!is_voice)
             entry = AutoEntry.Create (file, offset, i.ToString ("D4"));
         else
             entry = new Entry { Name = string.Format ("{0:D4}.pb", i), Type = "archive", Offset = offset };
         entry.Size = file.View.ReadUInt32 (index_offset + 4);
         if (offset < data_offset || !entry.CheckPlacement (file.MaxOffset))
             return null;
         dir.Add (entry);
         index_offset += 8;
     }
     return new ArcFile (file, this, dir);
 }
Beispiel #3
0
 public override ArcFile TryOpen(ArcView file)
 {
     int count = file.View.ReadInt32 (0);
     if (!IsSaneCount (count))
         return null;
     long index_offset = 4;
     const int name_length = 0x20;
     uint index_size = (uint)(count * (name_length + 8));
     if (index_size > file.View.Reserve (index_offset, index_size))
         return null;
     var dir = new List<Entry>();
     for (int i = 0; i < count; ++i)
     {
         string name = file.View.ReadString (index_offset, (uint)name_length);
         if (0 == name.Length)
             return null;
         index_offset += name_length;
         var entry = FormatCatalog.Instance.Create<Entry> (name);
         entry.Offset = file.View.ReadUInt32 (index_offset);
         entry.Size   = file.View.ReadUInt32 (index_offset+4);
         if (entry.Offset < index_size+4 || !entry.CheckPlacement (file.MaxOffset))
             return null;
         dir.Add (entry);
         index_offset += 8;
     }
     return new ArcFile (file, this, dir);
 }
Beispiel #4
0
        public override ArcFile TryOpen(ArcView file)
        {
            uint index_offset = file.View.ReadUInt32 (4);
            if (index_offset >= file.MaxOffset)
                return null;
            int count = file.View.ReadInt32 (index_offset);
            if (!IsSaneCount (count))
                return null;
            index_offset += 4;
            uint index_size = (uint)(count * 0x88);
            if (index_size > file.View.Reserve (index_offset, index_size))
                return null;

            var dir = new List<Entry> (count);
            for (int i = 0; i < count; ++i)
            {
                string name = file.View.ReadString (index_offset+8, 0x80);
                var entry = FormatCatalog.Instance.Create<Entry> (name);
                entry.Offset = file.View.ReadUInt32 (index_offset);
                entry.Size   = file.View.ReadUInt32 (index_offset+4);
                if (!entry.CheckPlacement (file.MaxOffset))
                    return null;
                dir.Add (entry);
                index_offset += 0x88;
            }
            return new ArcFile (file, this, dir);
        }
Beispiel #5
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.Name.EndsWith (".vpk", StringComparison.InvariantCultureIgnoreCase))
                return null;
            var vtb_name = Path.ChangeExtension (file.Name, "vtb");
            if (!VFS.FileExists (vtb_name))
                return null;
            var vtb_entry = VFS.FindFile (vtb_name);
            int count = (int)(vtb_entry.Size / 0x0C) - 1;
            if (!IsSaneCount (count))
                return null;

            using (var vtb = VFS.OpenView (vtb_entry))
            {
                vtb.View.Reserve (0, (uint)vtb.MaxOffset);
                uint index_offset = 0;
                uint next_offset = vtb.View.ReadUInt32 (8);
                var dir = new List<Entry> (count);
                for (int i = 0; i < count; ++i)
                {
                    string name = vtb.View.ReadString (index_offset, 8) + ".vaw";
                    var entry = FormatCatalog.Instance.Create<Entry> (name);
                    entry.Offset = next_offset;
                    index_offset += 0xC;
                    next_offset = vtb.View.ReadUInt32 (index_offset+8);
                    entry.Size = next_offset - (uint)entry.Offset;
                    if (!entry.CheckPlacement (file.MaxOffset))
                        return null;
                    dir.Add (entry);
                }
                return new ArcFile (file, this, dir);
            }
        }
Beispiel #6
0
        public override ArcFile TryOpen(ArcView file)
        {
            int signature = file.View.ReadInt16 (0);
            if (0x4656 != signature && 0x4C56 != signature)
                return null;
            int version = file.View.ReadInt16 (2);
            int count = file.View.ReadInt16 (4);
            if (!IsSaneCount (count))
                return null;
            int entry_size = file.View.ReadInt16 (6);
            int index_size = file.View.ReadInt32 (8);
            if (entry_size <= 0 || index_size <= 0 || file.MaxOffset != file.View.ReadUInt32 (0xC))
                return null;
            if (version >= 0x0200)
                return OpenV2 (file, count, entry_size, index_size);

            int index_offset = 0x10;
            var dir = new List<Entry> (count);
            for (int i = 0; i < count; ++i)
            {
                var name = file.View.ReadString (index_offset, 0x13);
                var entry = FormatCatalog.Instance.Create<PackedEntry> (name);
                entry.Offset = file.View.ReadUInt32 (index_offset+0x13);
                entry.Size   = file.View.ReadUInt32 (index_offset+0x17);
                entry.UnpackedSize = file.View.ReadUInt32 (index_offset+0x1B);
                entry.IsPacked     = 0 != file.View.ReadByte (index_offset+0x1F);
                if (!entry.CheckPlacement (file.MaxOffset))
                    return null;
                dir.Add (entry);
                index_offset += entry_size;
            }
            return new ArcFile (file, this, dir);
        }
Beispiel #7
0
        public override ArcFile TryOpen(ArcView file)
        {
            uint height = file.View.ReadUInt32 (4);
            uint width  = file.View.ReadUInt32 (8);
            int count   = file.View.ReadInt32 (12);
            if (!IsSaneCount (count))
                return null;
            uint dir_size = file.View.ReadUInt32 (20);
            uint cur_offset = 24;
            uint data_offset = cur_offset + dir_size;
            uint data_size = file.View.ReadUInt32 (data_offset);
            data_offset += 4;

            var dir = new List<Entry> (count);
            for (int i = 0; i < count; ++i)
            {
                var entry = new LwgImageEntry();
                entry.PosX = file.View.ReadInt32 (cur_offset);
                entry.PosY = file.View.ReadInt32 (cur_offset+4);
                entry.BPP = file.View.ReadByte (cur_offset+8);
                entry.Offset = data_offset + file.View.ReadUInt32 (cur_offset+9);
                entry.Size = file.View.ReadUInt32 (cur_offset+13);

                uint name_length = file.View.ReadByte (cur_offset+17);
                string name = file.View.ReadString (cur_offset+18, name_length);
                entry.Name = name + ".wcg";
                cur_offset += 18+name_length;
                if (cur_offset > dir_size+24)
                    return null;
                if (entry.CheckPlacement (data_offset + data_size))
                    dir.Add (entry);
            }
            return new ArcFile (file, this, dir);
        }
Beispiel #8
0
 public override ArcFile TryOpen(ArcView file)
 {
     int count = file.View.ReadInt32 (4);
     if (!IsSaneCount (count))
         return null;
     uint index_offset = 8;
     var base_name = Path.GetFileNameWithoutExtension (file.Name);
     var dir = new List<Entry> (count);
     for (int i = 0; i < count; ++i)
     {
         var offset = file.View.ReadUInt32 (index_offset);
         var size   = file.View.ReadUInt32 (index_offset+4);
         if (0 != size)
         {
             var name = string.Format ("{0}#{1:D4}", base_name, i);
             var entry = AutoEntry.Create (file, offset, name);
             entry.Size = size;
             if (!entry.CheckPlacement (file.MaxOffset))
                 return null;
             dir.Add (entry);
         }
         index_offset += 8;
     }
     return new ArcFile (file, this, dir);
 }
Beispiel #9
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.View.AsciiEqual (4, "OggS"))
                return null;

            uint current_offset = 0;
            uint first_size = file.View.ReadUInt32 (current_offset);
            if (first_size >= file.MaxOffset)
                return null;

            var dir = new List<Entry>();
            int n = 0;
            while (current_offset < file.MaxOffset)
            {
                uint size = file.View.ReadUInt32 (current_offset);
                if (current_offset + 4 + (long)size > file.MaxOffset)
                    return null;
                if (file.View.AsciiEqual (current_offset+4, "OggS"))
                {
                    var entry = new Entry {
                        Name    = string.Format ("{0:D5}.ogg", n++),
                        Type    = "audio",
                        Offset  = current_offset + 4,
                        Size    = size,
                    };
                    dir.Add (entry);
                }
                current_offset += 4+size;
            }
            return new ArcFile (file, this, dir);
        }
Beispiel #10
0
        public override ArcFile TryOpen(ArcView file)
        {
            #pragma warning disable 219
            string type;
            if (file.View.AsciiEqual (0, "M2TYPE_WAV"))
                type = "wave";
            else if (file.View.AsciiEqual (0, "M2T_BMP"))
                type = "bmp_";
            else if (file.View.AsciiEqual (0, "M2T_WORD"))
                type = "word";
            else
                return null;
            #pragma warning restore 219

            uint index_size = file.View.ReadUInt32 (file.MaxOffset-12);
            long index_offset = file.MaxOffset-0x14-index_size;
            int count = file.View.ReadInt32 (file.MaxOffset-8);
            if (index_offset <= 0 || count <= 0 || count > 0xfffff)
                return null;
            file.View.Reserve (index_offset, index_size);
            var dir = new List<Entry> (count);
            for (int i = 0; i < count; ++i)
            {
                var name = file.View.ReadString (index_offset, 0x10);
                var entry = FormatCatalog.Instance.Create<Entry> (name);
                entry.Offset = file.View.ReadUInt32 (index_offset+0x10);
                entry.Size   = file.View.ReadUInt32 (index_offset+0x14);
                if (!entry.CheckPlacement (file.MaxOffset))
                    return null;
                dir.Add (entry);
                index_offset += 0x18;
            }
            return new ArcFile (file, this, dir);
        }
Beispiel #11
0
        public override ArcFile TryOpen(ArcView file)
        {
            int version = file.View.ReadByte (4) - '0';
            if (version < 0 || !file.View.AsciiEqual (5, "0__"))
                return null;
            int count = file.View.ReadInt32 (0xC);
            if (!IsSaneCount (count))
                return null;

            uint index_offset = 0x10;
            var dir = new List<Entry> (count);
            for (int i = 0; i < count; ++i)
            {
                var name = file.View.ReadString (index_offset, 0x100);
                if (string.IsNullOrWhiteSpace (name))
                    return null;
                index_offset += 0x100;
                var entry = FormatCatalog.Instance.Create<Entry> (name);
                entry.Offset = file.View.ReadInt64 (index_offset);
                entry.Size   = file.View.ReadUInt32 (index_offset+8);
                if (!entry.CheckPlacement (file.MaxOffset))
                    return null;
                dir.Add (entry);
                index_offset += 0x10;
            }
            return new ArcFile (file, this, dir);
        }
Beispiel #12
0
 public override ArcFile TryOpen(ArcView file)
 {
     int count = file.View.ReadInt32 (4);
     if (!IsSaneCount (count))
         return null;
     uint data_offset = file.View.ReadUInt32 (8);
     if (data_offset < 0x10 + count * 0x20)
         return null;
     if (data_offset > file.View.Reserve (0, data_offset))
         return null;
     uint index_offset = 0x10;
     var dir = new List<Entry> (count);
     for (int i = 0; i < count; ++i)
     {
         var name = file.View.ReadString (index_offset, 0x18);
         var entry = FormatCatalog.Instance.Create<Entry> (name);
         entry.Size   = file.View.ReadUInt32 (index_offset+0x18);
         entry.Offset = file.View.ReadUInt32 (index_offset+0x1C);
         if (entry.Offset < data_offset || !entry.CheckPlacement (file.MaxOffset))
             return null;
         dir.Add (entry);
         index_offset += 0x20;
     }
     return new ArcFile (file, this, dir);
 }
Beispiel #13
0
        public override ArcFile TryOpen(ArcView file)
        {
            uint signature = file.View.ReadUInt32 (0);
            if (0x44474d != (signature & 0xffffff)) // 'MGD'
                return null;
            int count = file.View.ReadInt16 (0x20);
            if (count <= 0)
                return null;
            int flag = file.View.ReadUInt16 (3);
            var dir = new List<Entry> (count);
            int index_offset = 0x22;
            byte[] name_buf = new byte[16];
            for (uint i = 0; i < count; ++i)
            {
                int name_size = file.View.ReadByte (index_offset+1);
                if (0 == name_size)
                    return null;
                if (name_size > name_buf.Length)
                    Array.Resize (ref name_buf, name_size);
                file.View.Read (index_offset+2, name_buf, 0, (uint)name_size);
                if (100 == flag)
                    Decrypt (name_buf, 0, name_size);
                string name = Encodings.cp932.GetString (name_buf, 0, name_size);
                index_offset += 2 + name_size;

                uint offset = file.View.ReadUInt32 (index_offset+4);
                var entry = AutoEntry.Create (file, offset, name);
                entry.Size = file.View.ReadUInt32 (index_offset);
                if (!entry.CheckPlacement (file.MaxOffset))
                    return null;
                dir.Add (entry);
                index_offset += 8;
            }
            return new ArcFile (file, this, dir);
        }
Beispiel #14
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.View.AsciiEqual (0, "BSS-Composition\0"))
                return null;
            int count = file.View.ReadByte (0x11);
            if (0 == count)
                return null;

            string base_name = Path.GetFileNameWithoutExtension (file.Name);
            var dir = new List<Entry> (count);
            uint current_offset = 0x20;
            for (int i = 0; i < count; ++i)
            {
                var entry = new Entry {
                    Name    = string.Format ("{0}#{1:D3}.bsg", base_name, i),
                    Type    = "image",
                    Offset  = current_offset,
                    Size    = 0x40 + file.View.ReadUInt32 (current_offset+0x36),
                };
                if (!entry.CheckPlacement (file.MaxOffset))
                    return null;
                dir.Add (entry);
                current_offset += entry.Size;
            }
            return new ArcFile (file, this, dir);
        }
Beispiel #15
0
 public override ArcFile TryOpen(ArcView file)
 {
     int count = file.View.ReadInt32 (8);
     if (!IsSaneCount (count))
         return null;
     uint base_offset = file.View.ReadUInt32 (0x0c);
     uint index_offset = 0x10;
     uint index_size = 4u * (uint)count;
     if (base_offset >= file.MaxOffset || base_offset < (index_offset+index_size))
         return null;
     if (index_size > file.View.Reserve (index_offset, index_size))
         return null;
     var index = new List<uint> (count);
     for (int i = 0; i < count; ++i)
     {
         uint offset = file.View.ReadUInt32 (index_offset);
         if (offset != 0xffffffff)
             index.Add (base_offset + offset);
         index_offset += 4;
     }
     var dir = new List<Entry> (index.Count);
     for (int i = 0; i < index.Count; ++i)
     {
         long offset = index[i];
         string name = file.View.ReadString (offset, 0x20);
         var entry = FormatCatalog.Instance.Create<Entry> (name);
         entry.Offset = offset + 0x24;
         entry.Size   = file.View.ReadUInt32 (offset+0x20);
         dir.Add (entry);
     }
     return new ArcFile (file, this, dir);
 }
Beispiel #16
0
        public override ArcFile TryOpen(ArcView file)
        {
            uint index_offset = file.View.ReadUInt32 (0);
            int count = file.View.ReadInt32 (4);
            if (index_offset < 8 || index_offset >= file.MaxOffset || !IsSaneCount (count))
                return null;
            uint index_size = (uint)count * 0x28u;
            if (index_size > file.MaxOffset - index_offset)
                return null;
            var index = file.View.ReadBytes (index_offset, index_size);
            // last byte of the first filename presumably is zero
            byte key = index[0x1F];
            for (int i = 0; i < index.Length; ++i)
                index[i] ^= key;

            int current = 0;
            var dir = new List<Entry> (count);
            for (int i = 0; i < count; ++i)
            {
                int name_offset = '\\' == index[current] ? 1 : 0;
                var name = Binary.GetCString (index, current+name_offset, 0x20-name_offset);
                if (0 == name.Length)
                    return null;
                var entry = FormatCatalog.Instance.Create<Entry> (name);
                entry.Offset = LittleEndian.ToUInt32 (index, current+0x20);
                entry.Size   = LittleEndian.ToUInt32 (index, current+0x24);
                if (!entry.CheckPlacement (file.MaxOffset))
                    return null;
                dir.Add (entry);
                current += 0x28;
            }
            return new ArcFile (file, this, dir);
        }
Beispiel #17
0
        public override ArcFile TryOpen(ArcView file)
        {
            uint skip = file.View.ReadUInt32 (4);
            if (skip >= file.MaxOffset)
                return null;

            var dir = new List<Entry> (1);
            dir.Add (new Entry {
                Name = Path.GetFileNameWithoutExtension (file.Name)+".mpg",
                Type = "video",
                Offset = 8+skip,
                Size = (uint)(file.MaxOffset-(8+skip)),
            });
            return new ArcFile (file, this, dir);
        }
Beispiel #18
0
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt16 (0);
            if (!IsSaneCount (count))
                return null;

            var dir = new List<Entry> (count);
            for (int i = 0; i < count; ++i)
            {
                var entry = FormatCatalog.Instance.Create<Entry> (name);
                if (!entry.CheckPlacement (file.MaxOffset))
                    return null;
                dir.Add (entry);
            }
            return new ArcFile (file, this, dir);
        }
Beispiel #19
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (file.MaxOffset > uint.MaxValue)
                return null;
            int dir_size = file.View.ReadUInt16 (0);
            if (dir_size < 0x20 || 0 != (dir_size & 0xf) || dir_size + 2 >= file.MaxOffset)
                return null;
            byte first = file.View.ReadByte (2);
            if (0 == first)
                return null;
            file.View.Reserve (0, (uint)dir_size + 2);
            int dir_offset = 2;

            uint next_offset = file.View.ReadUInt32 (dir_offset+12);
            if (next_offset > file.MaxOffset || next_offset < dir_size+2)
                return null;
            var encoding = Encodings.cp932.WithFatalFallback();
            byte[] name_raw = new byte[12];

            int count = dir_size / 0x10 - 1;
            var dir = new List<Entry> (count);
            for (int i = 0; i < count; ++i)
            {
                file.View.Read (dir_offset, name_raw, 0, 12);
                int name_length = name_raw.Length;
                while (name_length > 0 && 0 == name_raw[name_length-1])
                    --name_length;
                if (0 == name_length)
                    return null;
                uint offset = next_offset;
                dir_offset += 0x10;
                next_offset = file.View.ReadUInt32 (dir_offset+12);
                if (next_offset > file.MaxOffset || next_offset < offset)
                    return null;
                string name = encoding.GetString (name_raw, 0, name_length).ToLowerInvariant();
                var entry = FormatCatalog.Instance.Create<Entry> (name);
                entry.Offset = offset;
                entry.Size = next_offset - offset;
                dir.Add (entry);
            }
            return new ArcFile (file, this, dir);
        }
Beispiel #20
0
 public override ArcFile TryOpen(ArcView file)
 {
     int count = file.View.ReadInt32 (0);
     if (count <= 0 || count > 0xfffff)
         return null;
     long index_offset = 4;
     uint index_size = (uint)(0xc * count);
     if (index_size > file.View.Reserve (index_offset, index_size))
         return null;
     var dir = new List<Entry>();
     for (int i = 0; i < count; ++i)
     {
         var entry = new Entry {
             Offset = file.View.ReadUInt32 (index_offset+4),
             Size   = file.View.ReadUInt32 (index_offset+8)
         };
         if (entry.Offset < index_size || !entry.CheckPlacement (file.MaxOffset))
             return null;
         dir.Add (entry);
         index_offset += 12;
     }
     byte[] name_buf = new byte[260];
     foreach (var entry in dir)
     {
         uint max_len = Math.Min (260u, file.View.Reserve (index_offset, 260));
         uint n;
         for (n = 0; n < max_len; ++n)
         {
             byte b = file.View.ReadByte (index_offset+n);
             if (0 == b)
                 break;
             name_buf[n] = b;
         }
         if (0 == n || max_len == n)
             return null;
         entry.Name = Encodings.cp932.GetString (name_buf, 0, (int)n);
         entry.Type = FormatCatalog.Instance.GetTypeFromName (entry.Name);
         index_offset += n+1;
     }
     return new ArcFile (file, this, dir);
 }
Beispiel #21
0
        public override ArcFile TryOpen(ArcView file)
        {
            var first_offset = file.View.ReadUInt32 (8);
            if (first_offset <= 0x14 || first_offset >= file.MaxOffset || first_offset > int.MaxValue)
                return null;
            int index_size = (int)(first_offset - 4);
            var count = index_size / 0x10;
            if (count * 0x10 != index_size)
                return null;

            string base_name = Path.GetFileNameWithoutExtension (file.Name);
            uint index_offset = 4;
            uint last_offset = 0;
            var dir = new List<Entry> (count);
            for (int i = 0; i < count; ++i)
            {
                var offset = file.View.ReadUInt32 (index_offset+4);
                if (0 == offset)
                    break;
                if (offset <= last_offset)
                    return null;
                string name = string.Format ("{0}#{1:D4}", base_name, i);
                var entry = new AutoEntry (name, () => {
                    uint signature = file.View.ReadUInt32 (offset);
                    if (0 == signature) return null;
                    return FormatCatalog.Instance.LookupSignature (signature).FirstOrDefault();
                });
                entry.Offset = offset;
                entry.Size = file.View.ReadUInt32 (index_offset);
                if (!entry.CheckPlacement (file.MaxOffset))
                    return null;
                dir.Add (entry);
                last_offset = offset;
                index_offset += 0x10;
            }
            if (0 == dir.Count)
                return null;
            return new ArcFile (file, this, dir);
        }
Beispiel #22
0
 public override ArcFile TryOpen(ArcView file)
 {
     if (file.View.ReadUInt16 (4) != '7')
         return null;
     string base_name = Path.GetFileNameWithoutExtension (file.Name);
     uint offset = 0xC;
     var dir = new List<Entry>();
     uint size = file.View.ReadUInt32 (offset);
     offset += 4;
     var entry = new Entry {
         Name = string.Format ("{0}#0.dat", base_name),
         Offset = offset,
         Size = size,
     };
     if (!entry.CheckPlacement (file.MaxOffset))
         return null;
     dir.Add (entry);
     offset += size;
     int n = 1;
     while (offset < file.MaxOffset)
     {
         size = file.View.ReadUInt32 (offset);
         if (0 == size)
             break;
         offset += 4;
         entry = new Entry {
             Name = string.Format ("{0}#{1}", base_name, n++),
             Type = "image",
             Offset = offset,
             Size = size,
         };
         if (!entry.CheckPlacement (file.MaxOffset))
             break;
         DetectFileType (file, entry);
         dir.Add (entry);
         offset += size;
     }
     return new ArcFile (file, this, dir);
 }
Beispiel #23
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.Name.EndsWith (".vol", StringComparison.InvariantCultureIgnoreCase))
                return null;
            uint first_offset = file.View.ReadUInt32 (0);
            if (first_offset < 0x10 || 0 != (first_offset & 0xF) || first_offset >= file.MaxOffset)
                return null;
            int count = (int)(first_offset /4);
            if (!IsSaneCount (count))
                return null;

            var offset_table = new List<uint> (count);
            offset_table.Add (first_offset);
            uint index_offset = 4;
            for (int i = 1; i < count; ++i)
            {
                uint offset = file.View.ReadUInt32 (index_offset);
                if (offset < offset_table[i-1] || offset > file.MaxOffset)
                    return null;
                offset_table.Add (offset);
                if (offset == file.MaxOffset)
                    break;
                index_offset += 4;
            }
            var base_name = Path.GetFileNameWithoutExtension (file.Name);
            var dir = new List<Entry> (offset_table.Count-1);
            for (int i = 0; i < offset_table.Count-1; ++i)
            {
                uint size = offset_table[i+1] - offset_table[i];
                if (0 == size)
                    continue;
                var name = string.Format ("{0}#{1:D4}", base_name, i);
                var entry = AutoEntry.Create (file, offset_table[i], name);
                entry.Size = size;
                dir.Add (entry);
            }
            return new ArcFile (file, this, dir);
        }
Beispiel #24
0
        public override ArcFile TryOpen (ArcView file)
        {
            int count = file.View.ReadInt32 (0);
            if (!IsSaneCount (count) || count * 10 >= file.MaxOffset)
                return null;

            uint index_offset = 4;
            byte[] name_buffer = new byte[0x100];
            var dir = new List<Entry> (count);
            for (int i = 0; i < count; ++i)
            {
                byte name_length = file.View.ReadByte (index_offset++);
                if (0 == name_length)
                    return null;
                if (name_length != file.View.Read (index_offset, name_buffer, 0, name_length))
                    return null;
                index_offset += name_length;
                byte key = (byte)(name_length+1);
                for (int j = 0; j < name_length; ++j)
                {
                    name_buffer[j] -= key--;
                    if (name_buffer[j] < 0x20)
                        return null;
                }
                string name = Encodings.cp932.GetString (name_buffer, 0, name_length);

                var entry = FormatCatalog.Instance.Create<PackedEntry> (name);
                entry.Offset = Binary.BigEndian (file.View.ReadUInt32 (index_offset));
                entry.Size   = Binary.BigEndian (file.View.ReadUInt32 (index_offset+4));
                index_offset += 8;
                if (entry.Offset < index_offset || !entry.CheckPlacement (file.MaxOffset))
                    return null;
                if (name.EndsWith (".scr", StringComparison.InvariantCultureIgnoreCase))
                    entry.IsPacked = true;
                dir.Add (entry);
            }
            return new ArcFile (file, this, dir);
        }
Beispiel #25
0
 public override ArcFile TryOpen(ArcView file)
 {
     if (!file.View.AsciiEqual (4, "ARCHIVED"))
         return null;
     int count = file.View.ReadInt16 (0x0c);
     if (count <= 0)
         return null;
     file.View.Reserve (0x10, (uint)count*0x20u);
     int index_offset = 0x10;
     var dir = new List<Entry> (count);
     for (int i = 0; i < count; ++i)
     {
         var name = file.View.ReadString (index_offset, 0x0c);
         var entry = FormatCatalog.Instance.Create<Entry> (name);
         entry.Offset = file.View.ReadUInt32 (index_offset+0x10);
         entry.Size = file.View.ReadUInt32 (index_offset+0x14);
         if (!entry.CheckPlacement (file.MaxOffset))
             return null;
         dir.Add (entry);
         index_offset += 0x20;
     }
     return new ArcFile (file, this, dir);
 }
Beispiel #26
0
 public override ArcFile TryOpen(ArcView file)
 {
     if ('c' != file.View.ReadInt16 (4))
         return null;
     int version = file.View.ReadInt16 (8);
     if (version < 1 || version > 3)
         return null;
     int count = file.View.ReadInt16 (0xA);
     if (!IsSaneCount (count))
         return null;
     uint index_offset = file.View.ReadUInt32 (0xC);
     if (index_offset >= file.MaxOffset)
         return null;
     var reader = new IndexReader (file);
     List<Entry> dir = null;
     if (version > 1)
         dir = reader.ReadV2 (count, index_offset);
     if (null == dir)
         dir = reader.ReadV1 (count, index_offset);
     if (null == dir)
         return null;
     return new ArcFile (file, this, dir);
 }
Beispiel #27
0
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32 (0);
            if (!IsSaneCount (count))
                return null;

            uint index_size = (uint)count * 0x20;
            if (index_size > file.View.Reserve (4, (uint)index_size))
                return null;
            int first_offset = file.View.ReadInt32 (0x1C);
            byte key = (byte)count;
            first_offset ^= key | key << 8 | key << 16 | key << 24;
            if (first_offset != 0)
                return null;

            var index = new byte[index_size];
            file.View.Read (4, index, 0, index_size);
            for (int i = 0; i < index.Length; ++i)
                index[i] ^= key;

            long base_offset = 4 + index_size;
            int index_offset = 0;
            var dir = new List<Entry> (count);
            for (int i = 0; i < count; ++i)
            {
                var name = Binary.GetCString (index, index_offset, 0x18);
                var entry = FormatCatalog.Instance.Create<Entry> (name);
                entry.Offset = base_offset + LittleEndian.ToUInt32 (index, index_offset+0x18);
                entry.Size   = LittleEndian.ToUInt32 (index, index_offset+0x1C);
                if (!entry.CheckPlacement (file.MaxOffset))
                    return null;
                dir.Add (entry);
                index_offset += 0x20;
            }
            return new ArcFile (file, this, dir);
        }
Beispiel #28
0
        public override ArcFile TryOpen(ArcView file)
        {
            string index_name = Path.ChangeExtension (file.Name, ".dll");
            if (index_name == file.Name || !VFS.FileExists (index_name))
                return null;
            var index_entry = VFS.FindFile (index_name);
            if (index_entry.Size < 12)
                return null;
            int count = file.View.ReadInt32 (0);
            if (!IsSaneCount (count) || (count & 0xFFFF) == 0x5A4D) // 'MZ'
                return null;

            var base_name = Path.GetFileNameWithoutExtension (file.Name);
            using (var idx = VFS.OpenView (index_entry))
            {
                var dir = new List<Entry> (count);
                uint index_offset = 4;
                int i = 0;
                uint last_offset = 3;
                while (index_offset+8 <= idx.MaxOffset)
                {
                    uint offset = idx.View.ReadUInt32 (index_offset);
                    if (offset <= last_offset)
                        return null;
                    var name = string.Format ("{0}#{1:D5}", base_name, i++);
                    var entry = AutoEntry.Create (file, offset, name);
                    entry.Size = idx.View.ReadUInt32(index_offset+4);
                    if (!entry.CheckPlacement (file.MaxOffset))
                        return null;
                    dir.Add (entry);
                    last_offset = offset;
                    index_offset += 8;
                }
                return new ArcFile (file, this, dir);
            }
        }
Beispiel #29
0
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32(0);

            if (!IsSaneCount(count))
            {
                return(null);
            }
            uint index_size      = (uint)count * 12;
            uint name_index_size = file.View.ReadUInt32(4);

            if (8L + index_size + name_index_size >= file.MaxOffset)
            {
                return(null);
            }

            uint index_offset = 8;

            file.View.Reserve(index_offset, index_size + name_index_size);
            uint   names_base = index_offset + index_size;
            var    dir        = new List <Entry> (count);
            string entry_type = null;
            string arc_name   = Path.GetFileNameWithoutExtension(file.Name).ToLowerInvariant();

            if ("voice" == arc_name || "bgm" == arc_name)
            {
                entry_type = "audio";
            }
            for (int i = 0; i < count; ++i)
            {
                uint filename_offset = file.View.ReadUInt32(index_offset);
                if (filename_offset >= name_index_size)
                {
                    return(null);
                }
                var name = file.View.ReadString(names_base + filename_offset, name_index_size - filename_offset);
                if (0 == name.Length)
                {
                    return(null);
                }
                var entry = new Entry {
                    Name   = name,
                    Offset = file.View.ReadUInt32(index_offset + 4),
                    Size   = file.View.ReadUInt32(index_offset + 8),
                };
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                if (entry_type != null)
                {
                    entry.Type = entry_type;
                }
                dir.Add(entry);
                index_offset += 12;
            }
            if (null == entry_type)
            {
                foreach (var entry in dir)
                {
                    var signature = file.View.ReadUInt32(entry.Offset);
                    if (0 == signature)
                    {
                        continue;
                    }
                    var res = FormatCatalog.Instance.LookupSignature(signature).FirstOrDefault();
                    if (null == res)
                    {
                        continue;
                    }
                    entry.Type = res.Type;
                    var ext = res.Extensions.FirstOrDefault();
                    if (!string.IsNullOrEmpty(ext))
                    {
                        entry.Name += '.' + ext;
                    }
                }
            }
            return(new ArcFile(file, this, dir));
        }
Beispiel #30
0
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32(0x14);

            if (!IsSaneCount(count))
            {
                return(null);
            }
            long index_offset = 0x2A;

            if (!file.View.AsciiEqual(index_offset, "NAME"))
            {
                return(null);
            }
            var addr_offset = file.View.ReadInt64(index_offset + 4);

            index_offset += 0xE;
            if (!file.View.AsciiEqual(index_offset, "NIDX"))
            {
                return(null);
            }
            index_offset += 4;
            var nidx_offsets = new uint[count]; // name offsets

            for (int i = 0; i < count; ++i)
            {
                nidx_offsets[i] = file.View.ReadUInt32(index_offset + 2);
                index_offset   += 8;
            }
            if (!file.View.AsciiEqual(index_offset, "EIDX"))
            {
                return(null);
            }
            index_offset += 4 + 8 * count;
            if (!file.View.AsciiEqual(index_offset, "CINF"))
            {
                return(null);
            }
            index_offset += 4;
            var name_buffer = new byte[0x40];
            var dir         = new List <Entry> (count);

            for (int i = 0; i < count; ++i)
            {
                index_offset += 6;
                ushort name_length = file.View.ReadUInt16(index_offset);
                if (name_length > name_buffer.Length)
                {
                    name_buffer = new byte[name_length];
                }
                file.View.Read(index_offset + 4, name_buffer, 0, name_length);
                index_offset += 6 + name_length;
                var name  = DecryptName(name_buffer, name_length);
                var entry = FormatCatalog.Instance.Create <Entry> (name);
                dir.Add(entry);
            }
            index_offset = addr_offset;
            if (!file.View.AsciiEqual(index_offset, "ADDR"))
            {
                return(null);
            }
            index_offset += 4;
            for (int i = 0; i < count; ++i)
            {
                dir[i].Offset = file.View.ReadInt64(index_offset + 2);
                index_offset += 12;
            }
            foreach (var entry in dir)
            {
                if (!file.View.AsciiEqual(entry.Offset, "FILE"))
                {
                    continue;
                }
                entry.Size    = file.View.ReadUInt32(entry.Offset + 0x18);
                entry.Offset += 0x22;
            }
            dir = dir.Where(entry => entry.Size != 0).ToList();
            if (0 == dir.Count)
            {
                return(null);
            }
            return(new ArcFile(file, this, dir));
        }
Beispiel #31
0
 public NitroPak(ArcView arc, ArchiveFormat impl, ICollection <Entry> dir, int version)
     : base(arc, impl, dir)
 {
     Version = version;
 }
Beispiel #32
0
 public DatIndexReader(byte[] toc, ArcView file) : base(toc, file)
 {
 }
Beispiel #33
0
 public IndexReader(ArcView file)
 {
     m_file = file;
 }
Beispiel #34
0
 public LibPReader(ArcView file, IMalieDecryptor decryptor, byte[] header, LibScheme scheme)
     : base(file, decryptor, header)
 {
     m_base_offset = 0;
     m_scheme      = scheme;
 }
Beispiel #35
0
        public override ArcFile TryOpen(ArcView file)
        {
            int version = file.View.ReadByte(3) - 0x30;
            int count   = file.View.ReadInt32(4);

            if (!IsSaneCount(count))
            {
                return(null);
            }
            var  name_buf     = new byte[32];
            var  dir          = new List <Entry> (count);
            long index_offset = 8;
            uint next_offset  = file.View.ReadUInt32(index_offset);

            for (int i = 0; i < count; ++i)
            {
                uint offset      = next_offset;
                uint size        = file.View.ReadUInt32(index_offset + 4);
                int  name_length = file.View.ReadByte(index_offset + 8);
                if (name_length > name_buf.Length)
                {
                    name_buf = new byte[name_length];
                }
                file.View.Read(index_offset + 9, name_buf, 0, (uint)name_length);
                if (i + 1 == count)
                {
                    next_offset = (uint)file.MaxOffset;
                }
                else
                {
                    next_offset = file.View.ReadUInt32(index_offset + 9 + name_length);
                }
                if (0 != offset && offset != file.MaxOffset)
                {
                    if (2 == version)
                    {
                        for (int j = 0; j < name_length; ++j)
                        {
                            name_buf[j] ^= 0xff;
                        }
                    }
                    uint packed_size;
                    if (0 == next_offset)
                    {
                        packed_size = size;
                    }
                    else if (next_offset >= offset)
                    {
                        packed_size = next_offset - offset;
                    }
                    else
                    {
                        return(null);
                    }
                    string name  = Encodings.cp932.GetString(name_buf, 0, name_length);
                    var    entry = new PackedEntry
                    {
                        Name         = name,
                        Type         = FormatCatalog.Instance.GetTypeFromName(name),
                        Offset       = offset,
                        Size         = packed_size,
                        UnpackedSize = size,
                    };
                    if (!entry.CheckPlacement(file.MaxOffset))
                    {
                        return(null);
                    }
                    dir.Add(entry);
                }
                index_offset += 9 + name_length;
            }
            if (2 == version)
            {
                return(new AstArchive(file, this, dir));
            }
            else
            {
                return(new ArcFile(file, this, dir));
            }
        }
Beispiel #36
0
 public ResourcesAssetsDeserializer(ArcView file)
 {
     m_res_name = file.Name;
 }
Beispiel #37
0
 public UnityResourcesAsset(ArcView arc, ArchiveFormat impl, ICollection <Entry> dir, IDictionary <string, ArcView> res_map)
     : base(arc, impl, dir)
 {
     ResourceMap = res_map;
 }
Beispiel #38
0
 public IndexReader(byte[] toc, ArcView file)
 {
     m_index      = new BinMemoryStream(toc);
     m_max_offset = file.MaxOffset;
 }
Beispiel #39
0
 public SteinsGateEncryptedStream(ArcView file, long offset, uint size)
 {
     m_stream         = file.CreateStream(offset, size);
     m_should_dispose = true;
     m_base_pos       = 0;
 }
Beispiel #40
0
 public CherryPak(ArcView arc, ArchiveFormat impl, ICollection <Entry> dir)
     : base(arc, impl, dir)
 {
 }
Beispiel #41
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (0 != file.View.ReadUInt32 (4) || 0xCCAE01FF != file.View.ReadUInt32 (0xA))
                return null;
            uint first_offset = file.View.ReadUInt32 (0x12);
            int count = (int)(first_offset - 0x12) / 6;
            if (!IsSaneCount (count))
                return null;
            var base_name = Path.GetFileNameWithoutExtension (file.Name);

            uint next_offset = first_offset;
            uint index_offset = 0x12;
            var dir = new List<Entry> (count);
            for (int i = 0; i < count; ++i)
            {
                var entry = new Entry {
                    Name = string.Format ("{0}#{1:D4}.ogg", base_name, i),
                    Type = "audio",
                    Offset = next_offset,
                };
                index_offset += 6;
                next_offset = i+1 == count ? (uint)file.MaxOffset : file.View.ReadUInt32 (index_offset);
                entry.Size = (uint)(next_offset - entry.Offset);
                if (!entry.CheckPlacement (file.MaxOffset))
                    return null;
                dir.Add (entry);
            }
            return new ArcFile (file, this, dir);
        }
Beispiel #42
0
 public YpfArchive(ArcView arc, ArchiveFormat impl, ICollection <Entry> dir, uint script_key)
     : base(arc, impl, dir)
 {
     ScriptKey = script_key;
 }
Beispiel #43
0
 public AstArchive(ArcView arc, ArchiveFormat impl, ICollection <Entry> dir)
     : base(arc, impl, dir)
 {
 }
Beispiel #44
0
 public PckArchive(ArcView arc, ArchiveFormat impl, ICollection <Entry> dir, byte[] key)
     : base(arc, impl, dir)
 {
     Encryption = new Blowfish(key);
 }
Beispiel #45
0
 public Reader(ArcView file)
 {
     m_view = file.View;
 }
Beispiel #46
0
 public TocUnpacker(ArcView file, bool should_dispose = false)
 {
     m_file           = file;
     m_should_dispose = should_dispose;
 }
Beispiel #47
0
 public MalieArchive(ArcView file, ArchiveFormat format, ICollection <Entry> dir, IMalieDecryptor decr)
     : base(file, format, dir)
 {
     Decryptor = decr;
 }
Beispiel #48
0
        public override ArcFile TryOpen(ArcView file)
        {
            int format_count = file.View.ReadUInt16(4);
            int count        = file.View.ReadUInt16(6);

            if (0 == format_count || 0 == count)
            {
                return(null);
            }
            uint index_offset = 8;
            long base_offset  = index_offset + format_count * 0x14 + count * 0x18;

            if (base_offset >= file.MaxOffset)
            {
                return(null);
            }
            var formats = new List <WaveFormat> (format_count);

            for (int i = 0; i < format_count; ++i)
            {
                var format = new WaveFormat
                {
                    FormatTag             = file.View.ReadUInt16(index_offset),
                    Channels              = file.View.ReadUInt16(index_offset + 2),
                    SamplesPerSecond      = file.View.ReadUInt32(index_offset + 4),
                    AverageBytesPerSecond = file.View.ReadUInt32(index_offset + 8),
                    BitsPerSample         = file.View.ReadUInt16(index_offset + 12),
                    BlockAlign            = file.View.ReadUInt16(index_offset + 14),
                };
                index_offset += 0x14;
                formats.Add(format);
            }
            var dir = new List <Entry> (count);

            for (int i = 0; i < count; ++i)
            {
                int fmt_index = file.View.ReadUInt16(index_offset);
                if (fmt_index > formats.Count)
                {
                    return(null);
                }
                string name  = file.View.ReadString(index_offset + 2, 0x0A);
                var    entry = new PkwEntry
                {
                    Name     = name + ".wav",
                    Type     = "audio",
                    Offset   = base_offset + file.View.ReadInt64(index_offset + 0x10),
                    Size     = file.View.ReadUInt32(index_offset + 0x0C),
                    IsPacked = true,
                    Format   = formats[fmt_index],
                };
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                entry.UnpackedSize = entry.Size + WaveHeaderSize;
                dir.Add(entry);
                index_offset += 0x18;
            }
            return(new ArcFile(file, this, dir));
        }
Beispiel #49
0
 public BellArchive(ArcView arc, ArchiveFormat impl, ICollection <Entry> dir, AImageScheme scheme)
     : base(arc, impl, dir)
 {
     Scheme = scheme;
 }
Beispiel #50
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.Name.HasExtension(".dat"))
            {
                return(null);
            }
            var arc_name = Path.GetFileName(file.Name);
            var match    = IndexNameRe.Match(arc_name);

            if (!match.Success)
            {
                return(null);
            }
            var base_name = match.Groups[2].Value;

            base_name = VFS.ChangeFileName(file.Name, base_name);
            var index_name = base_name + ".pcg";

            if (!VFS.FileExists(index_name))
            {
                index_name = base_name + ".spf";
                if (!VFS.FileExists(index_name))
                {
                    return(null);
                }
            }
            arc_name = match.Groups[1].Value;
            using (var index = VFS.OpenView(index_name))
            {
                int parts_count = index.View.ReadInt32(0);
                int count       = index.View.ReadInt32(4);
                if (parts_count > 10 || !IsSaneCount(count))
                {
                    return(null);
                }
                int entry_size = (int)(index.MaxOffset - 0x198) / count;
                if (entry_size < 0x30)
                {
                    return(null);
                }
                int first_index = -1, last_index = -1;
                for (int i = 0; i < parts_count; ++i)
                {
                    int name_pos = 8 + i * 0x20;
                    var name     = index.View.ReadString(name_pos, 0x20);
                    if (name == arc_name)
                    {
                        int first_index_pos = 0x148 + i * 4;
                        int last_index_pos  = 0x170 + i * 4;
                        first_index = index.View.ReadInt32(first_index_pos);
                        last_index  = index.View.ReadInt32(last_index_pos);
                        break;
                    }
                }
                if (first_index < 0 || first_index >= last_index || last_index > count)
                {
                    return(null);
                }

                uint name_size    = entry_size >= 0x48 ? 0x40u : 0x20u;
                int  index_offset = 0x198 + entry_size * first_index;
                var  dir          = new List <Entry> (last_index - first_index);
                for (int i = first_index; i < last_index; ++i)
                {
                    var name  = index.View.ReadString(index_offset, name_size);
                    var entry = FormatCatalog.Instance.Create <Entry> (name);
                    entry.Size   = index.View.ReadUInt32(index_offset + name_size);
                    entry.Offset = index.View.ReadUInt32(index_offset + name_size + 4);
                    if (!entry.CheckPlacement(file.MaxOffset))
                    {
                        return(null);
                    }
                    dir.Add(entry);
                    index_offset += entry_size;
                }
                return(new ArcFile(file, this, dir));
            }
        }
Beispiel #51
0
        public override ArcFile TryOpen(ArcView file)
        {
            long base_offset = 0;

            if (0x5a4d == file.View.ReadUInt16(0))  // 'MZ'
            {
                base_offset = SkipExeHeader(file);
            }
            if (!file.View.AsciiEqual(base_offset, SignatureBytes))
            {
                return(null);
            }
            long dir_offset = base_offset + file.View.ReadInt64(base_offset + 0x0b);

            if (dir_offset < 0x13 || dir_offset >= file.MaxOffset)
            {
                return(null);
            }
            if (0x80 == file.View.ReadUInt32(dir_offset))
            {
                dir_offset = base_offset + file.View.ReadInt64(dir_offset + 9);
                if (dir_offset < 0x13 || dir_offset >= file.MaxOffset)
                {
                    return(null);
                }
            }
            int header_type = file.View.ReadByte(dir_offset);

            if (0 != header_type && 1 != header_type)
            {
                return(null);
            }

            Stream header_stream;

            if (0 == header_type) // read unpacked header
            {
                long header_size = file.View.ReadInt64(dir_offset + 1);
                if (header_size > uint.MaxValue)
                {
                    return(null);
                }
                header_stream = file.CreateStream(dir_offset + 9, (uint)header_size);
            }
            else // read packed header
            {
                long packed_size = file.View.ReadInt64(dir_offset + 1);
                if (packed_size > uint.MaxValue)
                {
                    return(null);
                }
                long header_size = file.View.ReadInt64(dir_offset + 9);
                using (var input = file.CreateStream(dir_offset + 17, (uint)packed_size))
                    header_stream = ZLibCompressor.DeCompress(input);
            }

            var crypt_algorithm = new Lazy <ICrypt> (() => QueryCryptAlgorithm(file), false);

            var dir = new List <Entry>();

            dir_offset = 0;
            using (var header = new BinaryReader(header_stream, Encoding.Unicode))
                using (var filename_map = new FilenameMap())
                {
                    while (-1 != header.PeekChar())
                    {
                        uint entry_signature = header.ReadUInt32();
                        long entry_size      = header.ReadInt64();
                        if (entry_size < 0)
                        {
                            return(null);
                        }
                        dir_offset += 12 + entry_size;
                        if (0x656C6946 == entry_signature) // "File"
                        {
                            var entry = new Xp3Entry();
                            while (entry_size > 0)
                            {
                                uint section      = header.ReadUInt32();
                                long section_size = header.ReadInt64();
                                entry_size -= 12;
                                if (section_size > entry_size)
                                {
                                    break;
                                }
                                entry_size -= section_size;
                                long next_section_pos = header.BaseStream.Position + section_size;
                                switch (section)
                                {
                                case 0x6f666e69: // "info"
                                    if (entry.Size != 0 || !string.IsNullOrEmpty(entry.Name))
                                    {
                                        goto NextEntry; // ambiguous entry, ignore
                                    }
                                    entry.IsEncrypted = 0 != header.ReadUInt32();
                                    long file_size   = header.ReadInt64();
                                    long packed_size = header.ReadInt64();
                                    if (file_size >= uint.MaxValue || packed_size > uint.MaxValue || packed_size > file.MaxOffset)
                                    {
                                        goto NextEntry;
                                    }
                                    entry.IsPacked     = file_size != packed_size;
                                    entry.Size         = (uint)packed_size;
                                    entry.UnpackedSize = (uint)file_size;

                                    int name_size = header.ReadInt16();
                                    if (name_size > 0x100 || name_size <= 0)
                                    {
                                        goto NextEntry;
                                    }
                                    if (entry.IsEncrypted || ForceEncryptionQuery)
                                    {
                                        entry.Cipher = crypt_algorithm.Value;
                                    }
                                    else
                                    {
                                        entry.Cipher = NoCryptAlgorithm;
                                    }

                                    var name = new string (header.ReadChars(name_size));
                                    if (entry.Cipher.ObfuscatedIndex && ObfuscatedPathRe.IsMatch(name))
                                    {
                                        goto NextEntry;
                                    }
                                    if (filename_map.Count > 0)
                                    {
                                        name = filename_map.Get(entry.Hash, name);
                                    }
                                    if (name.Length > 0x100)
                                    {
                                        goto NextEntry;
                                    }
                                    entry.Name        = name;
                                    entry.Type        = FormatCatalog.Instance.GetTypeFromName(name);
                                    entry.IsEncrypted = !(entry.Cipher is NoCrypt) &&
                                                        !(entry.Cipher.StartupTjsNotEncrypted && "startup.tjs" == name);
                                    break;

                                case 0x6d676573: // "segm"
                                    int segment_count = (int)(section_size / 0x1c);
                                    if (segment_count > 0)
                                    {
                                        for (int i = 0; i < segment_count; ++i)
                                        {
                                            bool compressed          = 0 != header.ReadInt32();
                                            long segment_offset      = base_offset + header.ReadInt64();
                                            long segment_size        = header.ReadInt64();
                                            long segment_packed_size = header.ReadInt64();
                                            if (segment_offset > file.MaxOffset || segment_packed_size > file.MaxOffset)
                                            {
                                                goto NextEntry;
                                            }
                                            var segment = new Xp3Segment {
                                                IsCompressed = compressed,
                                                Offset       = segment_offset,
                                                Size         = (uint)segment_size,
                                                PackedSize   = (uint)segment_packed_size
                                            };
                                            entry.Segments.Add(segment);
                                        }
                                        entry.Offset = entry.Segments.First().Offset;
                                    }
                                    break;

                                case 0x726c6461: // "adlr"
                                    if (4 == section_size)
                                    {
                                        entry.Hash = header.ReadUInt32();
                                    }
                                    break;

                                default: // unknown section
                                    break;
                                }
                                header.BaseStream.Position = next_section_pos;
                            }
                            if (!string.IsNullOrEmpty(entry.Name) && entry.Segments.Any())
                            {
                                if (entry.Cipher.ObfuscatedIndex)
                                {
                                    DeobfuscateEntry(entry);
                                }
                                dir.Add(entry);
                            }
                        }
                        else if (entry_size > 7)
                        {
                            // 0x6E666E68 == entry_signature    // "hnfn"
                            // 0x6C696D73 == entry_signature    // "smil"
                            // 0x46696C65 == entry_signature    // "eliF"
                            // 0x757A7559 == entry_signature    // "Yuzu"
                            uint hash      = header.ReadUInt32();
                            int  name_size = header.ReadInt16();
                            if (name_size > 0)
                            {
                                entry_size -= 6;
                                if (name_size * 2 <= entry_size)
                                {
                                    var filename = new string (header.ReadChars(name_size));
                                    filename_map.Add(hash, filename);
                                }
                            }
                        }
NextEntry:
                        header.BaseStream.Position = dir_offset;
                    }
                }
            if (0 == dir.Count)
            {
                return(null);
            }
            var arc = new ArcFile(file, this, dir);

            try
            {
                if (crypt_algorithm.IsValueCreated)
                {
                    crypt_algorithm.Value.Init(arc);
                }
                return(arc);
            }
            catch
            {
                arc.Dispose();
                throw;
            }
        }
Beispiel #52
0
 public ArcIndexReader(byte[] toc, ArcView file, int arc_number, string game_name = null) : base(toc, file)
 {
     m_arc_number     = arc_number;
     m_game_name      = game_name;
     m_ignore_b_files = m_game_name == "ドキドキ母娘レッスン ~教えて♪Hなお勉強~";
 }
Beispiel #53
0
 public NpkArchive(ArcView arc, ArchiveFormat impl, ICollection <Entry> dir, Aes enc)
     : base(arc, impl, dir)
 {
     Encryption = enc;
 }
Beispiel #54
0
        private List <Entry> OpenPakV3(ArcView file)
        {
            if (0x110 > file.View.Reserve(4, 0x110))
            {
                return(null);
            }

            uint size_xor = file.View.ReadUInt32(0x104);

            if (0x64 != size_xor)
            {
                return(null);
            }
            byte[] name_buf = file.View.ReadBytes(4, 0x100);
            int    name_len = 0;

            for (int i = 0; i < name_buf.Length; ++i)
            {
                if (0 == name_buf[i])
                {
                    break;
                }
                if (name_buf[i] >= 0x80 || name_buf[i] < 0x20)
                {
                    return(null);
                }
                ++name_len;
            }
            if (0 == name_len || name_len > 0x10)
            {
                return(null);
            }

            uint header_key = GetKey(name_buf, name_len);
            uint unpacked   = file.View.ReadUInt32(0x108) ^ header_key;
            int  count      = (int)(file.View.ReadUInt32(0x10c) ^ header_key);

            if (!IsSaneCount(count))
            {
                return(null);
            }

            var  dir         = new List <Entry> (count);
            uint header_size = file.View.ReadUInt32(0x110) ^ size_xor;
            long base_offset = 0x114 + header_size;

            using (var input = file.CreateStream(0x114, header_size))
                using (var header_stream = new ZLibStream(input, CompressionMode.Decompress))
                    using (var header = new BinaryReader(header_stream, Encoding.ASCII, true))
                    {
                        for (int i = 0; i < count; ++i)
                        {
                            name_len = header.ReadInt32();
                            if (name_len <= 0 || name_len > name_buf.Length)
                            {
                                return(null);
                            }
                            if (name_len != header.Read(name_buf, 0, name_len))
                            {
                                return(null);
                            }
                            uint key   = GetKey(name_buf, name_len);
                            var  name  = Encodings.cp932.GetString(name_buf, 0, name_len);
                            var  entry = FormatCatalog.Instance.Create <PakEntry> (name);
                            entry.Offset       = (header.ReadUInt32() ^ key) + base_offset;
                            entry.UnpackedSize = (header.ReadUInt32() ^ key);
                            uint ignored = (header.ReadUInt32() ^ key);
                            entry.IsPacked = (header.ReadUInt32() ^ key) != 0;
                            uint packed_size = (header.ReadUInt32() ^ key);
                            entry.Key  = key;
                            entry.Size = entry.IsPacked ? packed_size : entry.UnpackedSize;
                            if (!entry.CheckPlacement(file.MaxOffset))
                            {
                                return(null);
                            }
                            dir.Add(entry);
                        }
                        return(dir);
                    }
        }
Beispiel #55
0
 public ArchiveFile(ArcView arc, ArchiveFormat impl, ICollection <Entry> dir, int offset, byte[] key)
     : base(arc, impl, dir)
 {
     HeaderOffset = offset;
     Key          = key;
 }
Beispiel #56
0
        protected List <Entry> ReadIndex(ArcView index, int index_offset, int count, long base_offset, ArcView file)
        {
            uint index_size = (uint)count * 0x18u;

            if (index_size > index.View.Reserve(index_offset, index_size))
            {
                return(null);
            }
            string arc_name = Path.GetFileNameWithoutExtension(file.Name);
            bool   is_grp   = arc_name.EndsWith("GRP", StringComparison.InvariantCultureIgnoreCase);
            var    dir      = new List <Entry> (count);

            for (int i = 0; i < count; ++i)
            {
                string name = index.View.ReadString(index_offset, 0x10);
                if (0 == name.Length)
                {
                    return(null);
                }
                var   offset = base_offset + index.View.ReadUInt32(index_offset + 0x10);
                Entry entry;
                if (is_grp)
                {
                    entry = new Entry {
                        Name   = Path.ChangeExtension(name, "grp"),
                        Type   = "image",
                        Offset = offset
                    };
                }
                else
                {
                    entry = AutoEntry.Create(file, offset, name);
                }
                entry.Size = index.View.ReadUInt32(index_offset + 0x14);
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                dir.Add(entry);
                index_offset += 0x18;
            }
            return(dir);
        }
Beispiel #57
0
 public NoaArchive(ArcView arc, ArchiveFormat impl, ICollection <Entry> dir, string password = null)
     : base(arc, impl, dir)
 {
     Password = password;
 }
Beispiel #58
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.View.AsciiEqual(8, "AlicArch"))
            {
                return(null);
            }
            if (!file.View.AsciiEqual(0x1C, "INFO"))
            {
                return(null);
            }
            int  version       = file.View.ReadInt32(0x10);
            long base_offset   = file.View.ReadUInt32(0x18);
            uint packed_size   = file.View.ReadUInt32(0x20);
            int  unpacked_size = file.View.ReadInt32(0x24);
            int  count         = file.View.ReadInt32(0x28);

            if (!IsSaneCount(count))
            {
                return(null);
            }

            var dir      = new List <Entry> (count);
            var name_buf = new byte[0x40];

            using (var input = file.CreateStream(0x2C, packed_size))
                using (var zstream = new ZLibStream(input, CompressionMode.Decompress))
                    using (var index = new BinaryReader(zstream))
                    {
                        for (int i = 0; i < count; ++i)
                        {
                            int name_length = index.ReadInt32();
                            int index_step  = index.ReadInt32();
                            if (name_length <= 0 || name_length > index_step || index_step > unpacked_size)
                            {
                                return(null);
                            }
                            if (index_step > name_buf.Length)
                            {
                                name_buf = new byte[index_step];
                            }
                            if (index_step != index.Read(name_buf, 0, index_step))
                            {
                                return(null);
                            }
                            var name  = Encodings.cp932.GetString(name_buf, 0, name_length);
                            var entry = FormatCatalog.Instance.Create <Entry> (name);
                            index.ReadInt32();
                            index.ReadInt32();
                            if (version < 2)
                            {
                                index.ReadInt32();
                            }
                            entry.Offset = index.ReadUInt32() + base_offset;
                            entry.Size   = index.ReadUInt32();
                            if (!entry.CheckPlacement(file.MaxOffset))
                            {
                                return(null);
                            }
                            dir.Add(entry);
                        }
                        return(new ArcFile(file, this, dir));
                    }
        }
Beispiel #59
0
 public override ArcFile TryOpen(ArcView file)
 {
     var header = file.View.ReadBytes (0, 0x5C);
     if (header.Length != 0x5C)
         return null;
     header = HeaderEncryption.Decrypt (header);
     if (!Binary.AsciiEqual (header, "GLibArchiveData2.") || header[0x12] != 0)
         return null;
     int version = header[0x11] - '0';
     if (version != 0 && version != 1)
         return null;
     uint index_offset = LittleEndian.ToUInt32 (header, 0x54);
     uint index_size   = LittleEndian.ToUInt32 (header, 0x58);
     byte[][] encrypted_index = new byte[2][];
     encrypted_index[0] = file.View.ReadBytes (index_offset, index_size);
     if (encrypted_index[0].Length != index_size)
         return null;
     encrypted_index[1] = new byte[index_size];
     uint[] keys = {
         LittleEndian.ToUInt32 (header, 0x44),
         LittleEndian.ToUInt32 (header, 0x34),
         LittleEndian.ToUInt32 (header, 0x24),
         LittleEndian.ToUInt32 (header, 0x14),
     };
     int i = 0;
     foreach (var key in keys)
     {
         var decoder = G2MetaScheme.CreateInstance (key);
         decoder.Decrypt (encrypted_index[i], encrypted_index[i^1]);
         i ^= 1;
     }
     byte[] index = encrypted_index[i];
     if (!Binary.AsciiEqual (index, "CDBD"))
         return null;
     int count = LittleEndian.ToInt32 (index, 4);
     int current_offset = 0x10;
     int info_base = current_offset + LittleEndian.ToInt32 (index, 8);
     int names_base = current_offset + count * 0x18;
     var dir = new List<Entry> (count);
     for (i = 0; i < count; ++i)
     {
         int name_offset = names_base + LittleEndian.ToInt32 (index, current_offset);
         int parent_dir = LittleEndian.ToInt32 (index, current_offset+8);
         int attr = LittleEndian.ToInt32 (index, current_offset+0xC);
         var name = Binary.GetCString (index, name_offset, info_base-name_offset);
         if (parent_dir != -1)
             name = Path.Combine (dir[parent_dir].Name, name);
         var entry = new G2Entry { Name = name };
         if (0x100 == attr)
         {
             int info_offset = info_base + LittleEndian.ToInt32 (index, current_offset+0x10);
             entry.Size   = LittleEndian.ToUInt32 (index, info_offset+8);
             entry.Offset = LittleEndian.ToUInt32 (index, info_offset+0xC);
             entry.Type   = FormatCatalog.Instance.GetTypeFromName (name);
             for (int j = 0; j < 4; ++j)
             {
                 info_offset += 0x10;
                 entry.Keys[j] = LittleEndian.ToUInt32 (index, info_offset);
             }
         }
         dir.Add (entry);
         current_offset += 0x18;
     }
     return new ArcFile (file, this, dir.Where (e => e.Offset != -1).ToList());
 }
Beispiel #60
0
 public AdvReader(ArcView file)
 {
     m_file = file;
 }