예제 #1
0
파일: ArcIFX.cs 프로젝트: uboaa/GARbro
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.Name.HasExtension(".ifx") || file.MaxOffset <= 0x10000)
            {
                return(null);
            }
            var base_name = Path.GetFileNameWithoutExtension(file.Name);
            var dir       = new List <Entry>();

            for (uint index_offset = 0x20; index_offset < 0x10000; index_offset += 0x10)
            {
                if (file.View.ReadUInt16(index_offset) == 0)
                {
                    continue;
                }
                var  name   = string.Format("{0}#{1:D5}", base_name, dir.Count);
                uint offset = file.View.ReadUInt32(index_offset + 4);
                var  entry  = AutoEntry.Create(file, offset, name);
                entry.Size = file.View.ReadUInt32(index_offset + 8);
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                dir.Add(entry);
                index_offset += 0x10;
            }
            if (0 == dir.Count)
            {
                return(null);
            }
            return(new ArcFile(file, this, dir));
        }
예제 #2
0
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32(4);

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

            var  base_name    = Path.GetFileNameWithoutExtension(file.Name);
            uint index_offset = 8;
            long base_offset  = index_offset + count * 4;
            var  dir          = new List <Entry> (count);

            for (int i = 0; i < count; ++i)
            {
                uint offset = file.View.ReadUInt32(index_offset);
                index_offset += 4;
                var name  = string.Format("{0}#{1:D4}", base_name, i);
                var entry = AutoEntry.Create(file, base_offset + offset, name);
                if (entry.Offset >= file.MaxOffset)
                {
                    return(null);
                }
                dir.Add(entry);
            }
            for (int i = 1; i < dir.Count; ++i)
            {
                dir[i - 1].Size = (uint)(dir[i].Offset - dir[i - 1].Offset);
            }
            var last_entry = dir[dir.Count - 1];

            last_entry.Size = (uint)(file.MaxOffset - last_entry.Offset);
            return(new ArcFile(file, this, dir));
        }
예제 #3
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.Name.HasExtension(".paq"))
            {
                return(null);
            }
            int count = file.View.ReadInt32(0);

            if (!IsSaneCount(count))
            {
                return(null);
            }
            var  base_name    = Path.GetFileNameWithoutExtension(file.Name);
            uint index_offset = 8;
            uint data_offset  = 4 + (uint)count * 8;
            var  dir          = new List <Entry> (count);

            for (int i = 0; i < count; ++i)
            {
                var name  = string.Format("{0}#{1:D4}", base_name, i);
                var entry = AutoEntry.Create(file, data_offset, name);
                entry.Size = file.View.ReadUInt32(index_offset);
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                dir.Add(entry);
                index_offset += 8;
                data_offset  += entry.Size;
            }
            return(new ArcFile(file, this, dir));
        }
예제 #4
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.View.AsciiEqual(4, "FILELINK"))
            {
                return(null);
            }
            int count = file.View.ReadInt32(0x10);

            if (!IsSaneCount(count))
            {
                return(null);
            }
            uint index_offset = file.View.ReadUInt32(0x18);
            var  dir          = new List <Entry> (count);

            for (int i = 0; i < count; ++i)
            {
                var  name   = file.View.ReadString(index_offset, 0x28);
                uint offset = file.View.ReadUInt32(index_offset + 0x2C);
                var  entry  = AutoEntry.Create(file, offset, name);
                entry.Size = file.View.ReadUInt32(index_offset + 0x30);
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                dir.Add(entry);
                index_offset += 0x40;
            }
            return(new ArcFile(file, this, dir));
        }
예제 #5
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (!(file.View.AsciiEqual(0, "DataPack5") ||
                  file.View.AsciiEqual(0, "GsPack5") ||
                  file.View.AsciiEqual(0, "GsPack4")))
            {
                return(null);
            }
            int  version_minor = file.View.ReadUInt16(0x30);
            int  version_major = file.View.ReadUInt16(0x32);
            uint index_size    = file.View.ReadUInt32(0x34);
            int  count         = file.View.ReadInt32(0x3c);

            if (!IsSaneCount(count) || index_size > 0xffffff)
            {
                return(null);
            }
            uint crypt_key     = file.View.ReadUInt32(0x38);
            long data_offset   = file.View.ReadUInt32(0x40);
            int  index_offset  = file.View.ReadInt32(0x44);
            int  entry_size    = version_major < 5 ? 0x48 : 0x68;
            int  unpacked_size = count * entry_size;

            byte[] packed_index = file.View.ReadBytes(index_offset, index_size);
            if (index_size != packed_index.Length)
            {
                return(null);
            }
            if (0 != crypt_key)
            {
                for (int i = 0; i != packed_index.Length; ++i)
                {
                    packed_index[i] ^= (byte)(i & crypt_key);
                }
            }
            using (var stream = new MemoryStream(packed_index))
                using (var reader = new LzssReader(stream, packed_index.Length, unpacked_size))
                {
                    reader.Unpack();
                    var index = reader.Data;
                    index_offset = 0;
                    var dir = new List <Entry> (count);
                    for (int i = 0; i < count; ++i)
                    {
                        string name = Binary.GetCString(index, index_offset, 0x40);
                        if (0 != name.Length)
                        {
                            long offset = data_offset + LittleEndian.ToUInt32(index, index_offset + 0x40);
                            var  entry  = AutoEntry.Create(file, offset, name);
                            entry.Size = LittleEndian.ToUInt32(index, index_offset + 0x44);
                            dir.Add(entry);
                        }
                        index_offset += entry_size;
                    }
                    return(new ArcFile(file, this, dir));
                }
        }
예제 #6
0
파일: ArcVOL.cs 프로젝트: zxc120/GARbro
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.Name.HasExtension(".vol"))
            {
                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));
        }
예제 #7
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));
        }
예제 #8
0
파일: ArcGD.cs 프로젝트: zxc120/GARbro
        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));
            }
        }
예제 #9
0
        public override ArcFile TryOpen(ArcView file)
        {
            var  base_name   = Path.GetFileNameWithoutExtension(file.Name);
            var  dir         = new List <Entry>();
            uint prev_offset = file.View.ReadUInt32(4);

            for (uint index_offset = 8; index_offset < file.MaxOffset; index_offset += 4)
            {
                uint offset = file.View.ReadUInt32(index_offset);
                if (offset <= prev_offset || offset > file.MaxOffset)
                {
                    return(null);
                }
                uint  size = offset - prev_offset;
                var   name = string.Format("{0}#{1:D4}", base_name, dir.Count);
                Entry entry;
                if (size > 4)
                {
                    entry = AutoEntry.Create(file, prev_offset, name);
                }
                else
                {
                    entry = new Entry {
                        Name = name, Offset = prev_offset
                    }
                };
                entry.Size = size;
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                dir.Add(entry);
                if (file.MaxOffset == offset)
                {
                    break;
                }
                prev_offset = offset;
            }
            if (0 == dir.Count)
            {
                return(null);
            }
            return(new ArcFile(file, this, dir));
        }
    }
예제 #10
0
파일: ArcPKG.cs 프로젝트: ziyuejun/GARbro
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32(4);

            if (!IsSaneCount(count))
            {
                return(null);
            }
            var    base_name    = Path.GetFileNameWithoutExtension(file.Name);
            uint   index_offset = 8;
            string default_type = null;

            if (base_name.Equals("cg", StringComparison.OrdinalIgnoreCase))
            {
                default_type = "image";
            }
            var dir = new List <Entry> (count);

            for (int i = 0; i < count; ++i)
            {
                var   name   = string.Format("{0}#{1:D4}", base_name, i);
                var   offset = file.View.ReadUInt32(index_offset);
                Entry entry;
                if (default_type != null)
                {
                    entry = new Entry {
                        Name = name, Type = default_type, Offset = offset
                    }
                }
                ;
                else
                {
                    entry = AutoEntry.Create(file, offset, name);
                }
                entry.Size = file.View.ReadUInt32(index_offset + 4);
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                dir.Add(entry);
                index_offset += 8;
            }
            return(new ArcFile(file, this, dir));
        }
예제 #11
0
파일: ArcBIN.cs 프로젝트: zxc120/GARbro
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32(0);

            if (!IsSaneCount(count - 1))
            {
                return(null);
            }
            uint base_offset = (uint)(4 + 4 * count);

            if (base_offset >= file.MaxOffset)
            {
                return(null);
            }

            uint index_offset = 4;
            uint next_offset  = file.View.ReadUInt32(index_offset);

            if (next_offset != 0)
            {
                return(null);
            }
            var base_name = Path.GetFileNameWithoutExtension(file.Name);

            next_offset = base_offset;
            --count;
            var dir = new List <Entry> (count);

            for (int i = 0; i < count; ++i)
            {
                index_offset += 4;
                var name  = string.Format("{0}#{1:D4}", base_name, i);
                var entry = AutoEntry.Create(file, next_offset, name);
                next_offset = base_offset + file.View.ReadUInt32(index_offset);
                entry.Size  = next_offset - (uint)entry.Offset;
                if (0 == entry.Size || !entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                dir.Add(entry);
            }
            return(new ArcFile(file, this, dir));
        }
예제 #12
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);
        }
예제 #13
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));
        }
    }
예제 #14
0
파일: ArcMFG.cs 프로젝트: zxc120/GARbro
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32(4);

            if (count <= 0 || count > 0xfffff)
            {
                return(null);
            }
            var  dir          = new List <Entry> (count);
            long index_offset = 8;
            uint next_offset  = file.View.ReadUInt32(index_offset + 0x10);

            for (int i = 0; i < count; ++i)
            {
                string name = file.View.ReadString(index_offset, 0x10);
                if (0 == name.Length)
                {
                    return(null);
                }
                uint offset = next_offset;
                index_offset += 0x14;
                if (i + 1 != count)
                {
                    next_offset = file.View.ReadUInt32(index_offset + 0x10);
                }
                else
                {
                    next_offset = (uint)file.MaxOffset;
                }
                var entry = AutoEntry.Create(file, offset, name);
                entry.Size = next_offset - offset;
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                dir.Add(entry);
            }
            return(new ArcFile(file, this, dir));
        }
예제 #15
0
        public override ArcFile TryOpen(ArcView file)
        {
            int count = file.View.ReadInt32(0);

            if (count <= 0 || count > 0xfffff)
            {
                return(null);
            }
            uint name_size    = 100;
            uint index_size   = (uint)((name_size + 8) * count);
            uint first_offset = file.View.ReadUInt32(4 + name_size + 4);

            if (first_offset != (4 + index_size) || index_size > file.View.Reserve(4, index_size))
            {
                return(null);
            }
            var  dir          = new List <Entry> (count);
            long index_offset = 4;

            for (int i = 0; i < count; ++i)
            {
                string name = file.View.ReadString(index_offset, name_size);
                if (0 == name.Length)
                {
                    return(null);
                }
                index_offset += 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 (offset <= index_size || !entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                dir.Add(entry);
                index_offset += 8;
            }
            return(new ArcFile(file, this, dir));
        }
예제 #16
0
파일: ArcBGI.cs 프로젝트: tenyuhuang/GARbro
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.View.AsciiEqual(4, "KO ARC20"))
            {
                return(null);
            }
            int count = file.View.ReadInt32(12);

            if (!IsSaneCount(count))
            {
                return(null);
            }
            uint index_size = 0x80 * (uint)count;

            if (index_size > file.View.Reserve(0x10, index_size))
            {
                return(null);
            }
            var  dir          = new List <Entry> (count);
            long index_offset = 0x10;
            long base_offset  = index_offset + index_size;

            for (uint i = 0; i < count; ++i)
            {
                string name   = file.View.ReadString(index_offset, 0x60);
                var    offset = base_offset + file.View.ReadUInt32(index_offset + 0x60);
                var    entry  = AutoEntry.Create(file, offset, name);
                entry.Size = file.View.ReadUInt32(index_offset + 0x64);
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                dir.Add(entry);
                index_offset += 0x80;
            }
            return(new ArcFile(file, this, dir));
        }