Пример #1
0
        void ImportKeys(string source_name)
        {
            var script_lpk = VFS.CombinePath(Path.GetDirectoryName(source_name), "SCRIPT.LPK");

            using (var script_file = VFS.OpenView(script_lpk))
                using (var script_arc = Open(ScriptName, script_file, CurrentScheme, null))
                {
                    if (null == script_arc)
                    {
                        throw new UnknownEncryptionScheme();
                    }
                    var entry = script_arc.Dir.FirstOrDefault(e => e.Name.Equals("gameinit.sob", StringComparison.InvariantCultureIgnoreCase));
                    if (null == entry)
                    {
                        throw new FileNotFoundException("Missing 'gameinit.sob' entry in SCRIPT.LPK");
                    }
                    using (var gameinit = script_arc.OpenEntry(entry))
                    {
                        var init_data = new byte[gameinit.Length];
                        gameinit.Read(init_data, 0, init_data.Length);
                        if (!ParseGameInit(init_data))
                        {
                            throw new UnknownEncryptionScheme();
                        }
                    }
                }
        }
Пример #2
0
        public override ArcFile TryOpen(ArcView file)
        {
            string lst_name = Path.ChangeExtension(file.Name, ".lst");

            if (lst_name == file.Name || !VFS.FileExists(lst_name))
            {
                return(null);
            }
            var lst_entry = VFS.FindFile(lst_name);
            int count     = (int)(lst_entry.Size / 0x16);

            if (count > 0xffff || count * 0x16 != lst_entry.Size)
            {
                return(null);
            }
            using (var lst = VFS.OpenView(lst_entry))
            {
                var  dir          = new List <Entry> (count);
                uint index_offset = 0;
                for (int i = 0; i < count; ++i)
                {
                    string name  = lst.View.ReadString(index_offset, 14);
                    var    entry = FormatCatalog.Instance.Create <Entry> (name);
                    entry.Offset = lst.View.ReadUInt32(index_offset + 14);
                    entry.Size   = lst.View.ReadUInt32(index_offset + 18);
                    if (!entry.CheckPlacement(file.MaxOffset))
                    {
                        return(null);
                    }
                    dir.Add(entry);
                    index_offset += 0x16;
                }
                return(new ArcFile(file, this, dir));
            }
        }
Пример #3
0
        IList <string> GetFileNames(string arc_name)
        {
            var dir_name = VFS.GetDirectoryName(arc_name);
            var lst_name = Path.ChangeExtension(arc_name, ".lst");

            if (VFS.FileExists(lst_name))
            {
                return(ReadListFile(lst_name));
            }

            var lists_lst_name = VFS.CombinePath(dir_name, "lists.lst");

            if (!VFS.FileExists(lists_lst_name))
            {
                return(null);
            }
            var base_name = Path.GetFileNameWithoutExtension(arc_name);
            var arcs      = ReadListFile(lists_lst_name);
            var arc_no    = arcs.IndexOf(base_name);

            if (-1 == arc_no)
            {
                return(null);
            }
            var lists_bin_name = VFS.CombinePath(dir_name, "lists.bin");

            using (var lists_bin = VFS.OpenView(lists_bin_name))
                return(ReadFileNames(lists_bin, arc_no));
        }
Пример #4
0
        public override ArcFile TryOpen(ArcView file)
        {
            string lstname = file.Name + ".lst";

            if (!VFS.FileExists(lstname))
            {
                return(null);
            }
            using (var lst = VFS.OpenView(lstname))
            {
                List <Entry> dir = null;
                try
                {
                    dir = OpenMoon(lst, file.MaxOffset);
                }
                catch { /* ignore parse errors */ }
                if (null == dir)
                {
                    dir = OpenNexton(lst, file.MaxOffset);
                }
                if (null == dir)
                {
                    return(null);
                }
                return(new ArcFile(file, this, dir));
            }
        }
Пример #5
0
        uint GetContentKey(ArcView file, List <Entry> dir, EncryptionScheme scheme)
        {
            if (null != scheme.ContentKey)
            {
                return(scheme.ContentKey.Value);
            }

            if (VFS.IsPathEqualsToFileName(file.Name, "system.arc"))
            {
                return(ReadSysenvSeed(file, dir, scheme.IndexKey));
            }
            else
            {
                var system_arc = VFS.CombinePath(VFS.GetDirectoryName(file.Name), "system.arc");
                using (var arc = VFS.OpenView(system_arc))
                {
                    var header = arc.View.ReadBytes(0, 0x30);
                    Decrypt(header, 0, scheme.IndexKey);
                    using (var arc_file = ReadIndex(arc, header, scheme))
                    {
                        return(ReadSysenvSeed(arc, arc_file.Dir, scheme.IndexKey));
                    }
                }
            }
        }
        public override ArcFile TryOpen(ArcView file)
        {
            string lstname = file.Name + ".lst"; //we find the name of the file with the name of the original file

            if (!VFS.FileExists(lstname))
            {
                return(null);
            }
            using (var lst = VFS.OpenView(lstname)) //lst is a view on the file lst that is created with the name of the file of the view
            {
                List <Entry> dir = null;
                try
                {
                    dir = OpenMoon(lst, file.MaxOffset);
                }
                catch { /* ignore parse errors */ }
                if (null == dir)
                {
                    dir = OpenNexton(lst, file.MaxOffset);
                }
                if (null == dir)
                {
                    return(null);
                }
                return(new ArcFile(file, this, dir));
            }
        }
Пример #7
0
        public Dictionary <string, ArcView> GenerateResourceMap(List <Entry> dir)
        {
            var res_map   = new Dictionary <string, ArcView>();
            var asset_dir = VFS.GetDirectoryName(m_res_name);

            foreach (AssetEntry entry in dir)
            {
                if (null == entry.Bundle)
                {
                    continue;
                }
                if (res_map.ContainsKey(entry.Bundle.Name))
                {
                    continue;
                }
                var bundle_name = VFS.CombinePath(asset_dir, entry.Bundle.Name);
                if (!VFS.FileExists(bundle_name))
                {
                    entry.Bundle = null;
                    entry.Offset = entry.AssetObject.Offset;
                    entry.Size   = entry.AssetObject.Size;
                    continue;
                }
                res_map[entry.Bundle.Name] = VFS.OpenView(bundle_name);
            }
            return(res_map);
        }
Пример #8
0
        Stream OpenLstIndex(ArcView file, string dat_name, HibikiDatScheme scheme)
        {
            var lst_name = Path.ChangeExtension(file.Name, ".lst");

            if (VFS.FileExists(lst_name))
            {
                return(VFS.OpenStream(lst_name));
            }
            else if ("init.dat" == dat_name)
            {
                return(file.CreateStream());
            }
            // try to open 'init.dat' archive in the same directory
            var init_dat = VFS.CombinePath(VFS.GetDirectoryName(file.Name), "init.dat");

            if (!VFS.FileExists(init_dat))
            {
                return(file.CreateStream());
            }
            try
            {
                using (var init = VFS.OpenView(init_dat))
                    using (var init_arc = TryOpenWithScheme(init, ReadCount(init), scheme))
                    {
                        lst_name = Path.GetFileName(lst_name);
                        var lst_entry = init_arc.Dir.First(e => e.Name == lst_name);
                        return(init_arc.OpenEntry(lst_entry));
                    }
            }
            catch
            {
                return(file.CreateStream());
            }
        }
Пример #9
0
        internal IBinaryStream OpenFg(IBinaryStream fg)
        {
            var fge_name = Path.ChangeExtension(fg.Name, ".fge");

            using (var fge = VFS.OpenView(fge_name))
            {
                if (fge.MaxOffset != 0x818)
                {
                    throw new InvalidFormatException();
                }
                int  chunk1_size   = fge.View.ReadInt32(0);
                int  chunk2_offset = fge.View.ReadInt32(0x404);
                int  chunk2_size   = fge.View.ReadInt32(0x408);
                bool is_compressed = fge.View.ReadInt32(0x810) != 0;
                int  part1_size    = chunk2_offset + chunk2_size;
                var  part1         = new byte[part1_size];
                fge.View.Read(4, part1, 0, (uint)chunk1_size);
                fg.Position = 5;
                fg.Read(part1, chunk1_size, chunk2_offset - chunk1_size);
                fge.View.Read(0x40C, part1, chunk2_offset, (uint)chunk2_size);
                var    part2     = new StreamRegion(fg.AsStream, fg.Position, true);
                Stream fg_stream = new PrefixStream(part1, part2);
                if (is_compressed)
                {
                    fg_stream = new ZLibStream(fg_stream, CompressionMode.Decompress);
                    fg_stream = new SeekableStream(fg_stream);
                }
                return(new BinaryStream(fg_stream, fg.Name));
            }
        }
Пример #10
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.Name.HasExtension(".dat"))
            {
                return(null);
            }
            var cpn_name = Path.ChangeExtension(file.Name, ".cpn");

            if (!VFS.FileExists(cpn_name))
            {
                return(null);
            }
            byte   key;
            string cpn_index;

            using (var cpn = VFS.OpenView(cpn_name))
            {
                key = cpn.View.ReadByte(0);
                var cpn_data = cpn.View.ReadBytes(1, (uint)(cpn.MaxOffset - 1));
                for (int i = 0; i < cpn_data.Length; ++i)
                {
                    cpn_data[i] ^= key;
                }
                cpn_index = Encodings.cp932.GetString(cpn_data);
            }
            int idx = cpn_index.IndexOf('#', 1);

            if (idx <= 1)
            {
                return(null);
            }
            var data_name = cpn_index.Substring(1, idx - 1);

            if (!VFS.IsPathEqualsToFileName(file.Name, data_name))
            {
                return(null);
            }
            var dir   = new List <Entry>();
            var match = CpnEntryRe.Match(cpn_index, idx);

            while (match.Success)
            {
                var name  = match.Groups["name"].Value;
                var entry = FormatCatalog.Instance.Create <Entry> (name);
                entry.Offset = UInt32.Parse(match.Groups["offset"].Value);
                entry.Size   = UInt32.Parse(match.Groups["size"].Value);
                if (!entry.CheckPlacement(file.MaxOffset))
                {
                    return(null);
                }
                dir.Add(entry);
                match = match.NextMatch();
            }
            if (0 == dir.Count)
            {
                return(null);
            }
            return(new CpnArchive(file, this, dir, key));
        }
Пример #11
0
        List <Entry> ReadIndex(string ini_file, string arc_name)
        {
            if (null == LastAccessedIndex ||
                !LastAccessedIndex.Item1.Equals(ini_file, StringComparison.InvariantCultureIgnoreCase))
            {
                LastAccessedIndex = null;
                using (var ini = VFS.OpenView(ini_file))
                {
                    if (!ini.View.AsciiEqual(0, "S4IC") && !ini.View.AsciiEqual(0, "S3IC"))
                    {
                        return(null);
                    }
                    uint packed_size = ini.View.ReadUInt32(0x134);
                    using (var packed = ini.CreateStream(0x138, packed_size))
                        using (var unpacked = new LzssStream(packed))
                            using (var index = new BinaryReader(unpacked))
                            {
                                int arc_count  = index.ReadInt32();
                                var name_buf   = new byte[0x100];
                                var file_table = new Dictionary <string, List <Entry> > (arc_count, StringComparer.InvariantCultureIgnoreCase);
                                var arc_list   = new List <List <Entry> > (arc_count);
                                for (int i = 0; i < arc_count; ++i)
                                {
                                    index.Read(name_buf, 0, name_buf.Length);
                                    var file_list = new List <Entry>();
                                    file_table.Add(Binary.GetCString(name_buf, 0, name_buf.Length), file_list);
                                    arc_list.Add(file_list);
                                }
                                int file_count = index.ReadInt32();
                                for (int i = 0; i < file_count; ++i)
                                {
                                    index.Read(name_buf, 0, 0x40);
                                    int arc_id = index.ReadInt32();
                                    if (arc_id < 0 || arc_id >= arc_list.Count)
                                    {
                                        return(null);
                                    }
                                    index.ReadInt32(); // file number
                                    uint offset = index.ReadUInt32();
                                    uint size   = index.ReadUInt32();
                                    var  name   = Binary.GetCString(name_buf, 0, 0x40);
                                    if ("@" == name)
                                    {
                                        continue;
                                    }
                                    var entry = FormatCatalog.Instance.Create <Entry> (name);
                                    entry.Offset = offset;
                                    entry.Size   = size;
                                    arc_list[arc_id].Add(entry);
                                }
                                LastAccessedIndex = Tuple.Create(ini_file, file_table);
                            }
                }
            }
            List <Entry> dir = null;

            LastAccessedIndex.Item2.TryGetValue(arc_name, out dir);
            return(dir);
        }
Пример #12
0
        /// <summary>
        /// Look for control block within specified TPM plugin file.
        /// </summary>

        public override void Init(ArcFile arc)
        {
            if (ControlBlock != null)
            {
                return;
            }
            if (string.IsNullOrEmpty(TpmFileName))
            {
                throw new InvalidEncryptionScheme();
            }

            var dir_name = VFS.GetDirectoryName(arc.File.Name);
            var tpm_name = VFS.CombinePath(dir_name, TpmFileName);

            using (var tpm = VFS.OpenView(tpm_name))
            {
                if (tpm.MaxOffset < 0x1000 || tpm.MaxOffset > uint.MaxValue)
                {
                    throw new InvalidEncryptionScheme("Invalid KiriKiri TPM plugin");
                }
                using (var view = tpm.CreateViewAccessor(0, (uint)tpm.MaxOffset))
                    unsafe
                    {
                        byte *begin = view.GetPointer(0);
                        byte *end   = begin + (((uint)tpm.MaxOffset - 0x1000u) & ~0x3u);
                        try {
                            while (begin < end)
                            {
                                int i;
                                for (i = 0; i < s_ctl_block_signature.Length; ++i)
                                {
                                    if (begin[i] != s_ctl_block_signature[i])
                                    {
                                        break;
                                    }
                                }
                                if (s_ctl_block_signature.Length == i)
                                {
                                    ControlBlock = new uint[0x400];
                                    uint *src = (uint *)begin;
                                    for (i = 0; i < ControlBlock.Length; ++i)
                                    {
                                        ControlBlock[i] = ~src[i];
                                    }
                                    return;
                                }
                                begin += 4; // control block expected to be on a dword boundary
                            }
                            throw new InvalidEncryptionScheme("No control block found inside TPM plugin");
                        }
                        finally {
                            view.SafeMemoryMappedViewHandle.ReleasePointer();
                        }
                    }
            }
        }
Пример #13
0
        public override ArcFile TryOpen(ArcView file)
        {
            var name = Path.GetFileName(file.Name);

            if (!NamePattern.IsMatch(name))
            {
                return(null);
            }
            var match   = NamePattern.Match(name);
            int name_id = 1;
            var num_str = match.Groups["num"].Value;

            if (!string.IsNullOrEmpty(num_str))
            {
                name_id = Int32.Parse(num_str);
            }
            if (name_id < 1)
            {
                return(null);
            }
            ArcView index = file;

            try
            {
                if (name_id != 1)
                {
                    string index_name;
                    if (file.Name.HasExtension(".dat"))
                    {
                        index_name = VFS.ChangeFileName(file.Name, "0001.dat");
                    }
                    else
                    {
                        index_name = VFS.ChangeFileName(file.Name, "data");
                    }
                    if (!VFS.FileExists(index_name))
                    {
                        return(null);
                    }
                    index = VFS.OpenView(index_name);
                }
                var dir = ReadIndex(index, name_id, file.MaxOffset);
                if (null == dir || 0 == dir.Count)
                {
                    return(null);
                }
                return(new ArcFile(file, this, dir));
            }
            finally
            {
                if (index != file)
                {
                    index.Dispose();
                }
            }
        }
Пример #14
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (file.Name.HasExtension(".SPL"))
            {
                return(null);
            }
            var index_name = Path.ChangeExtension(file.Name, ".SPL");

            if (!VFS.FileExists(index_name))
            {
                return(null);
            }
            using (var idx = VFS.OpenView(index_name))
            {
                if (!idx.View.AsciiEqual(0, "SFP\0"))
                {
                    return(null);
                }
                uint align        = idx.View.ReadUInt32(0xC);
                uint index_offset = 0x20;
                uint names_offset = idx.View.ReadUInt32(index_offset);
                if (names_offset > idx.MaxOffset || names_offset <= index_offset)
                {
                    return(null);
                }
                int count = (int)(names_offset - index_offset) / 0x10;
                if (!IsSaneCount(count))
                {
                    return(null);
                }
                var dir = new List <Entry> (count);
                for (int i = 0; i < count; ++i)
                {
                    uint name_offset = idx.View.ReadUInt32(index_offset);
                    var  name        = idx.View.ReadString(name_offset, (uint)(idx.MaxOffset - name_offset));
                    if (string.IsNullOrWhiteSpace(name))
                    {
                        return(null);
                    }
                    var entry = FormatCatalog.Instance.Create <Entry> (name);
                    entry.Size   = idx.View.ReadUInt32(index_offset + 4);
                    entry.Offset = (long)idx.View.ReadUInt32(index_offset + 8) * align;
                    if (!entry.CheckPlacement(file.MaxOffset))
                    {
                        return(null);
                    }
                    dir.Add(entry);
                    index_offset += 0x10;
                }
                return(new ArcFile(file, this, dir));
            }
        }
Пример #15
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));
            }
        }
Пример #16
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (file.Name.HasExtension(".lst"))
            {
                return(null);
            }
            var lst_name = Path.ChangeExtension(file.Name, ".lst");

            if (!VFS.FileExists(lst_name))
            {
                return(null);
            }
            using (var lst = VFS.OpenView(lst_name))
            {
                if (!lst.View.AsciiEqual(0, "ARC1.00"))
                {
                    return(null);
                }
                int count = lst.View.ReadInt32(8);
                if (!IsSaneCount(count))
                {
                    return(null);
                }
                uint lst_pos     = 0x10;
                var  name_buffer = new byte[0x20];
                var  dir         = new List <Entry> (count);
                for (int i = 0; i < count; ++i)
                {
                    lst.View.Read(lst_pos + 0x10, name_buffer, 0, 0x20);
                    for (int j = 0; j < 0x20 && name_buffer[j] != 0; ++j)
                    {
                        name_buffer[j] ^= 0x80;
                    }
                    var name  = Binary.GetCString(name_buffer, 0);
                    var entry = Create <PackedEntry> (name);
                    entry.Size   = lst.View.ReadUInt32(lst_pos + 8);
                    entry.Offset = lst.View.ReadUInt32(lst_pos + 0xC);
                    if (!entry.CheckPlacement(file.MaxOffset))
                    {
                        return(null);
                    }
                    entry.UnpackedSize = lst.View.ReadUInt32(lst_pos + 4);
                    entry.IsPacked     = lst.View.ReadInt32(lst_pos) != 0;
                    dir.Add(entry);
                    lst_pos += 0x30;
                }
                return(new ArcFile(file, this, dir));
            }
        }
Пример #17
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.View.AsciiEqual(0, "PF"))
            {
                return(null);
            }
            var base_name = Path.GetFileName(file.Name);

            if (!base_name.Equals("data02", StringComparison.InvariantCultureIgnoreCase))
            {
                return(null);
            }
            var index_name = VFS.CombinePath(VFS.GetDirectoryName(file.Name), "data01");

            if (!VFS.FileExists(index_name))
            {
                return(null);
            }
            using (var index = VFS.OpenView(index_name))
            {
                if (!index.View.AsciiEqual(0, "IF"))
                {
                    return(null);
                }
                int count = index.View.ReadInt16(2);
                if (!IsSaneCount(count) || 4 + 0x18 * count > index.MaxOffset)
                {
                    return(null);
                }

                uint index_offset = 4;
                var  dir          = new List <Entry> (count);
                for (int i = 0; i < count; ++i)
                {
                    var name  = index.View.ReadString(index_offset, 0x10);
                    var entry = FormatCatalog.Instance.Create <Entry> (name);
                    entry.Offset = index.View.ReadUInt32(index_offset + 0x10);
                    entry.Size   = index.View.ReadUInt32(index_offset + 0x14);
                    if (!entry.CheckPlacement(file.MaxOffset))
                    {
                        return(null);
                    }
                    dir.Add(entry);
                    index_offset += 0x18;
                }
                return(new ArcFile(file, this, dir));
            }
        }
Пример #18
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.Name.EndsWith(".det", StringComparison.InvariantCultureIgnoreCase))
            {
                return(null);
            }
            var name_file  = Path.ChangeExtension(file.Name, "nme");
            var index_file = Path.ChangeExtension(file.Name, "atm");

            if (!VFS.FileExists(name_file) || !VFS.FileExists(index_file))
            {
                return(null);
            }
            using (var nme = VFS.OpenView(name_file))
                using (var idx = VFS.OpenView(index_file))
                {
                    int count = (int)(idx.MaxOffset / 0x14);
                    if (!IsSaneCount(count))
                    {
                        return(null);
                    }
                    uint idx_offset = 0;
                    var  name_table = nme.View.ReadBytes(0, (uint)nme.MaxOffset);
                    var  dir        = new List <Entry> (count);
                    for (int i = 0; i < count; ++i)
                    {
                        int name_offset = idx.View.ReadInt32(idx_offset);
                        if (name_offset < 0 || name_offset >= name_table.Length)
                        {
                            return(null);
                        }
                        var name  = Binary.GetCString(name_table, name_offset, name_table.Length - name_offset);
                        var entry = FormatCatalog.Instance.Create <PackedEntry> (name);
                        entry.Offset = idx.View.ReadUInt32(idx_offset + 4);
                        entry.Size   = idx.View.ReadUInt32(idx_offset + 8);
                        if (!entry.CheckPlacement(file.MaxOffset))
                        {
                            return(null);
                        }
                        entry.UnpackedSize = idx.View.ReadUInt32(idx_offset + 0x10);
                        entry.IsPacked     = true;
                        dir.Add(entry);
                        idx_offset += 0x14;
                    }
                    return(new ArcFile(file, this, dir));
                }
        }
Пример #19
0
        BinScheme FindScheme(ArcView bin_file)
        {
            var bin_name = Path.GetFileName(bin_file.Name).ToUpperInvariant();

            foreach (var game in KnownSchemes.Values)
            {
                BinScheme scheme;
                if (game.TryGetValue(bin_name, out scheme) && bin_file.MaxOffset == scheme.Size)
                {
                    return(scheme);
                }
            }
            if (bin_file.MaxOffset >= uint.MaxValue)
            {
                return(null);
            }
            var bin_dir   = VFS.GetDirectoryName(bin_file.Name);
            var game_dir  = Directory.GetParent(bin_dir).FullName;
            var exe_files = VFS.GetFiles(VFS.CombinePath(game_dir, "*.exe"));

            if (!exe_files.Any())
            {
                return(null);
            }
            var last_idx = new byte[12];

            LittleEndian.Pack((uint)bin_file.MaxOffset, last_idx, 0);
            LittleEndian.Pack((uint)bin_file.MaxOffset, last_idx, 4);
            foreach (var exe_entry in exe_files)
            {
                using (var exe_file = VFS.OpenView(exe_entry))
                {
                    var exe = new ExeFile(exe_file);
                    if (!exe.ContainsSection(".data"))
                    {
                        continue;
                    }
                    var data_section = exe.Sections[".data"];
                    var idx_pos      = exe.FindString(data_section, last_idx, 4);
                    if (idx_pos > 0)
                    {
                        return(ParseIndexTable(exe_file, data_section, idx_pos, bin_name));
                    }
                }
            }
            return(null);
        }
Пример #20
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.Name.HasExtension(".ar2"))
            {
                return(null);
            }
            var idx_name = Path.ChangeExtension(file.Name, ".idx");

            using (var idx_view = VFS.OpenView(idx_name))
                using (var idx = idx_view.CreateStream())
                {
                    int count = idx.ReadInt32();
                    if (!IsSaneCount(count))
                    {
                        return(null);
                    }
                    var name_buffer = new byte[0x100];
                    var dir         = new List <Entry> (count);
                    for (int i = 0; i < count; ++i)
                    {
                        uint size          = idx.ReadUInt32();
                        uint unpacked_size = idx.ReadUInt32();
                        idx.ReadInt32();
                        int  name_length = idx.ReadInt32();
                        uint offset      = idx.ReadUInt32();
                        if (name_length > name_buffer.Length)
                        {
                            return(null);
                        }
                        idx.Read(name_buffer, 0, name_length);
                        for (int j = 0; j < name_length; ++j)
                        {
                            name_buffer[j] ^= 0x55;
                        }
                        var name  = Encodings.cp932.GetString(name_buffer, 0, name_length);
                        var entry = FormatCatalog.Instance.Create <Entry> (name);
                        entry.Offset = offset;
                        entry.Size   = size;
                        if (!entry.CheckPlacement(file.MaxOffset))
                        {
                            return(null);
                        }
                        dir.Add(entry);
                    }
                    return(new ArcFile(file, this, dir));
                }
        }
Пример #21
0
        public override ArcFile TryOpen(ArcView file)
        {
            var pft_name = Path.ChangeExtension(file.Name, "pft");

            if (file.Name.Equals(pft_name, StringComparison.InvariantCultureIgnoreCase) ||
                !VFS.FileExists(pft_name))
            {
                return(null);
            }
            using (var pft_view = VFS.OpenView(pft_name))
                using (var pft = pft_view.CreateStream())
                {
                    var    arc_name = Path.GetFileNameWithoutExtension(file.Name);
                    string ext      = "";
                    ExtensionMap.TryGetValue(arc_name, out ext);
                    uint header_size  = pft.ReadUInt16();
                    uint cluster_size = pft.ReadUInt16();
                    int  count        = pft.ReadInt32();
                    if (!IsSaneCount(count))
                    {
                        return(null);
                    }

                    pft.Position = header_size;
                    var dir = new List <Entry> (count);
                    for (int i = 0; i < count; ++i)
                    {
                        var name = pft.ReadCString(8);
                        if (name.Length > 0)
                        {
                            if (!string.IsNullOrEmpty(ext))
                            {
                                name = Path.ChangeExtension(name, ext);
                            }
                            var entry = FormatCatalog.Instance.Create <Entry> (name);
                            entry.Offset = cluster_size * (long)pft.ReadUInt32();
                            entry.Size   = pft.ReadUInt32();
                            if (!entry.CheckPlacement(file.MaxOffset))
                            {
                                return(null);
                            }
                            dir.Add(entry);
                        }
                    }
                    return(new ArcFile(file, this, dir));
                }
        }
Пример #22
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.Name.HasExtension(".arc"))
            {
                return(null);
            }
            var bin_name = Path.ChangeExtension(file.Name, "BIN");

            if (!VFS.FileExists(bin_name))
            {
                return(null);
            }
            using (var bin = VFS.OpenView(bin_name))
            {
                if (!bin.View.AsciiEqual(0, "LSDARC V.100"))
                {
                    return(null);
                }
                int count = bin.View.ReadInt32(0xC);
                if (!IsSaneCount(count))
                {
                    return(null);
                }
                using (var index = bin.CreateStream())
                {
                    index.Position = 0x10;
                    var dir = new List <Entry>(count);
                    for (int i = 0; i < count; ++i)
                    {
                        var entry = new PackedEntry();
                        entry.IsPacked     = index.ReadInt32() != 0;
                        entry.Offset       = index.ReadUInt32();
                        entry.UnpackedSize = index.ReadUInt32();
                        entry.Size         = index.ReadUInt32();
                        entry.Name         = index.ReadCString();
                        if (!entry.CheckPlacement(file.MaxOffset))
                        {
                            return(null);
                        }
                        dir.Add(entry);
                    }
                    return(new ArcFile(file, this, dir));
                }
            }
        }
Пример #23
0
        public override ArcFile TryOpen(ArcView file)
        {
            string pak_name = Path.ChangeExtension(file.Name, "pak");

            if (pak_name == file.Name || !VFS.FileExists(pak_name))
            {
                return(null);
            }
            var file_map = GetFileMap(pak_name);

            if (null == file_map)
            {
                return(null);
            }
            string base_name = Path.GetFileNameWithoutExtension(pak_name);

            using (var pak = VFS.OpenView(pak_name))
            {
                if (0x00646568 != pak.View.ReadUInt32(0))
                {
                    return(null);
                }
                int count = pak.View.ReadInt32(4);
                if (count != file_map.Count)
                {
                    return(null);
                }
                List <Entry> dir;
                if ("cg" == base_name)
                {
                    dir = ReadCgPak(pak, file, file_map);
                }
                else
                {
                    dir = ReadVoicePak(pak, file, file_map);
                }
                if (null == dir)
                {
                    return(null);
                }
                return(new ArcFile(file, this, dir));
            }
        }
Пример #24
0
        public override ArcFile TryOpen(ArcView file)
        {
            var name = Path.GetFileName(file.Name);

            if (!NamePattern.IsMatch(name))
            {
                return(null);
            }
            var match   = NamePattern.Match(name);
            int name_id = Int32.Parse(match.Groups[1].Value);

            if (name_id < 1)
            {
                return(null);
            }
            ArcView index = file;

            try
            {
                if (name_id != 1)
                {
                    var index_name = VFS.ChangeFileName(file.Name, "0001.dat");
                    if (!VFS.FileExists(index_name))
                    {
                        return(null);
                    }
                    index = VFS.OpenView(index_name);
                }
                var dir = ReadIndex(index, name_id, file.MaxOffset);
                if (null == dir || 0 == dir.Count)
                {
                    return(null);
                }
                return(new ArcFile(file, this, dir));
            }
            finally
            {
                if (index != file)
                {
                    index.Dispose();
                }
            }
        }
Пример #25
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.Name.HasExtension(".vpk"))
            {
                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));
            }
        }
Пример #26
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.View.AsciiEqual(4, "-PAC"))
            {
                return(null);
            }
            var hed_name = Path.ChangeExtension(file.Name, "hed");

            if (!VFS.FileExists(hed_name))
            {
                return(null);
            }
            using (var hed = VFS.OpenView(hed_name))
            {
                if (!hed.View.AsciiEqual(0, "PPAC-HED"))
                {
                    return(null);
                }
                uint       index_offset = 0x10;
                const uint data_offset  = 0x10;
                int        count        = (int)(hed.MaxOffset - index_offset) / 0x20;
                if (!IsSaneCount(count))
                {
                    return(null);
                }
                var dir = new List <Entry> (count);
                while (index_offset + 0x20 <= hed.MaxOffset)
                {
                    var name  = hed.View.ReadString(index_offset, 0x10);
                    var entry = FormatCatalog.Instance.Create <PackedEntry> (name);
                    entry.Offset = hed.View.ReadUInt32(index_offset + 0x10) + data_offset;
                    entry.Size   = hed.View.ReadUInt32(index_offset + 0x14);
                    if (!entry.CheckPlacement(file.MaxOffset))
                    {
                        return(null);
                    }
                    dir.Add(entry);
                    index_offset += 0x20;
                }
                return(new ArcFile(file, this, dir));
            }
        }
Пример #27
0
        public override ArcFile TryOpen(ArcView file)
        {
            if (!file.Name.EndsWith(".snn", StringComparison.InvariantCultureIgnoreCase))
            {
                return(null);
            }
            var inx_name = Path.ChangeExtension(file.Name, "Inx");

            if (!VFS.FileExists(inx_name))
            {
                return(null);
            }
            using (var inx = VFS.OpenView(inx_name))
            {
                int count = inx.View.ReadInt32(0);
                if (!IsSaneCount(count))
                {
                    return(null);
                }

                int inx_offset = 4;
                if (inx_offset + count * 0x48 > inx.MaxOffset)
                {
                    return(null);
                }
                var dir = new List <Entry> (count);
                for (int i = 0; i < count; ++i)
                {
                    var name  = inx.View.ReadString(inx_offset, 0x40);
                    var entry = FormatCatalog.Instance.Create <Entry> (name);
                    entry.Offset = inx.View.ReadUInt32(inx_offset + 0x40);
                    entry.Size   = inx.View.ReadUInt32(inx_offset + 0x44);
                    if (!entry.CheckPlacement(file.MaxOffset))
                    {
                        return(null);
                    }
                    dir.Add(entry);
                    inx_offset += 0x48;
                }
                return(new ArcFile(file, this, dir));
            }
        }
Пример #28
0
        List <Entry> ReadIndex(string ini_file, string arc_name)
        {
            if (null == LastAccessedIndex ||
                !LastAccessedIndex.Item1.Equals(ini_file, StringComparison.OrdinalIgnoreCase))
            {
                LastAccessedIndex = null;
                using (var ini = VFS.OpenView(ini_file))
                {
                    IBinaryStream index;
                    bool          is_append = ini.View.AsciiEqual(0, "S4AC");
                    if (is_append || ini.View.AsciiEqual(0, "S4IC") || ini.View.AsciiEqual(0, "S3IC"))
                    {
                        uint offset      = is_append ? 0x114u : 0x134u;
                        uint packed_size = ini.View.ReadUInt32(offset);
                        var  packed      = ini.CreateStream(offset + 4, packed_size);
                        var  unpacked    = new LzssStream(packed);
                        index = new BinaryStream(unpacked, ini_file);
                    }
                    else if (ini.View.AsciiEqual(0, "S3IN"))
                    {
                        index = ini.CreateStream(0x12C);
                    }
                    else
                    {
                        return(null);
                    }
                    using (index)
                    {
                        var file_table = ReadSysIni(index);
                        if (null == file_table)
                        {
                            return(null);
                        }
                        LastAccessedIndex = Tuple.Create(ini_file, file_table);
                    }
                }
            }
            List <Entry> dir = null;

            LastAccessedIndex.Item2.TryGetValue(arc_name, out dir);
            return(dir);
        }
Пример #29
0
        IList <string> GetFileNames(string dir_name, string base_name)
        {
            var lists_lst_name = VFS.CombinePath(dir_name, "lists.lst");

            if (!VFS.FileExists(lists_lst_name))
            {
                return(null);
            }
            var arcs   = GetArcNames(lists_lst_name);
            var arc_no = arcs.IndexOf(base_name);

            if (-1 == arc_no)
            {
                return(null);
            }
            var lists_bin_name = VFS.CombinePath(dir_name, "lists.bin");

            using (var lists_bin = VFS.OpenView(lists_bin_name))
                return(ReadFileNames(lists_bin, arc_no));
        }
Пример #30
0
        List <Entry> ReadAriIndex(ArcView file, string ari_name)
        {
            long arc_offset = 4;

            using (var ari = VFS.OpenView(ari_name))
            {
                long index_offset = 0;
                while (index_offset + 4 < ari.MaxOffset)
                {
                    int name_len = ari.View.ReadInt32(index_offset);
                    var name     = ReadName(ari, index_offset + 4, name_len);
                    if (null == name)
                    {
                        return(null);
                    }
                    var entry = new AriEntry {
                        Name = name
                    };
                    index_offset      += name_len + 4;
                    entry.Mode         = ari.View.ReadUInt16(index_offset);
                    entry.Size         = ari.View.ReadUInt32(index_offset + 2);
                    entry.UnpackedSize = 0;
                    SetType(entry);
                    index_offset += 6;
                    arc_offset   += name_len + 10;
                    if (1 == entry.Mode)
                    {
                        entry.IsPacked = true;
                        arc_offset    += 4;
                    }
                    entry.Offset = arc_offset;
                    if (!entry.CheckPlacement(file.MaxOffset))
                    {
                        return(null);
                    }
                    arc_offset += entry.Size;
                    m_dir.Add(entry);
                }
            }
            return(m_dir);
        }