public override ArcFile TryOpen(ArcView file) { int count = file.View.ReadInt32(4); if (!IsSaneCount(count)) { return(null); } byte key = file.View.ReadByte(0x87); using (var input = file.CreateStream(8, 0x88 * (uint)count)) using (var dec = new XoredStream(input, key)) using (var index = new BinaryStream(dec, file.Name)) { var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { var name = index.ReadCString(0x80); if (string.IsNullOrWhiteSpace(name)) { return(null); } var entry = FormatCatalog.Instance.Create <Entry> (name); entry.Size = index.ReadUInt32(); entry.Offset = index.ReadUInt32(); if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); } return(new PkdArchive(file, this, dir, key)); } }
} // 'GRPH' public override ImageMetaData ReadMetaData(IBinaryStream stream) { var header = stream.ReadHeader(0x1C); byte key = (byte)(header[4] ^ header[5]); int data_offset = 0x14; int x = 0, y = 0; if (0 != header[0xC]) { data_offset += header.ToInt32(0x10) / 0x10 * 0x18; x = header.ToInt32(0x14); y = header.ToInt32(0x18); } using (var input = new StreamRegion(stream.AsStream, data_offset, true)) using (var crypto = new XoredStream(input, key)) using (var png = new BinaryStream(crypto, stream.Name)) { var info = Png.ReadMetaData(png); if (null == info) { return(null); } return(new KgpMetaData { Width = info.Width, Height = info.Height, OffsetX = x, OffsetY = y, BPP = info.BPP, Key = key, DataOffset = data_offset, DataLength = header.ToInt32(8), }); } }
public override ImageData Read(IBinaryStream stream, ImageMetaData info) { var meta = (KgpMetaData)info; using (var input = new StreamRegion(stream.AsStream, meta.DataOffset, true)) using (var crypto = new XoredStream(input, meta.Key)) using (var png = new BinaryStream(crypto, stream.Name)) return(Png.Read(png, info)); }
public override Stream OpenEntry(ArcFile arc, Entry entry) { Stream input = arc.File.CreateStream(entry.Offset, entry.Size); if (arc is PackPlusArchive) { input = new XoredStream(input, 0xFF); } return(input); }
public override Stream OpenEntry(ArcFile arc, Entry entry) { Stream input = arc.File.CreateStream(entry.Offset, entry.Size); if (entry.Name.HasExtension(".res")) { input = new XoredStream(input, 0x80); } return(input); }
public override SoundInput TryOpen(IBinaryStream file) { var header = file.ReadHeader(2); if (header[0] != 0) { return(null); } file.Position = 0; var input = new XoredStream(file.AsStream, 0xFF); return(Mp3Format.Value.TryOpen(new BinaryStream(input, file.Name))); }
public override SoundInput TryOpen(IBinaryStream file) { var header = file.ReadHeader(3); if (0xFF != (header[0] ^ Key) || 0xE2 != ((header[1] ^ Key) & 0xE6) || 0xF0 == ((header[2] ^ Key) & 0xF0)) { return(null); } file.Position = 0; var input = new XoredStream(file.AsStream, Key); return(new Mp3Input(input)); }
public override Stream OpenEntry(ArcFile arc, Entry entry) { var fent = (FltEntry)entry; Stream input = arc.File.CreateStream(fent.Offset, fent.Size); if (fent.IsEncrypted) { input = new XoredStream(input, fent.Key); } if (fent.IsPacked) { input = new ZLibStream(input, CompressionMode.Decompress); } return(input); }
internal Stream OpenDataStream(ArcView file, long offset) { uint packed_size = file.View.ReadUInt32(offset); int flags = file.View.ReadInt32(offset + 4); int unpacked_size = file.View.ReadInt32(offset + 8); Stream input = file.CreateStream(offset + 12, packed_size - 12); if ((flags & 1) != 0) { input = new XoredStream(input, 0xFF); } if ((flags & 2) != 0) { input = new LzssStream(input); } return(input); }
public override Stream OpenEntry(ArcFile arc, Entry entry) { Stream input = arc.File.CreateStream(entry.Offset, entry.Size); var pent = entry as PackedEntry; if (null == pent || !pent.IsPacked) { return(input); } input = new PackedStream <LzBitsDecompressor> (input); input = new LimitStream(input, pent.UnpackedSize); if (entry.Name.HasExtension(".gpa")) { input = new XoredStream(input, 0xFF); } return(input); }
public override Stream OpenEntry(ArcFile arc, Entry entry) { var mdarc = arc as MdArchive; Stream input = arc.File.CreateStream(entry.Offset, entry.Size); if (mdarc != null && (mdarc.Version >= 5 && mdarc.Version <= 8)) { input = new XoredStream(input, 0xFF); } var pent = entry as PackedEntry; if (pent != null && pent.IsPacked) { input = new LzssStream(input); } return(input); }
public override ArcFile TryOpen(ArcView file) { if (!file.View.AsciiEqual(4, "ARC\0")) { return(null); } uint data_offset = file.View.ReadUInt32(8); uint unpacked_size = file.View.ReadUInt32(0xC); uint packed_size = file.View.ReadUInt32(0x10); byte[] unpacked = new byte[unpacked_size]; using (var packed = file.CreateStream(0x14, packed_size)) using (var input = new XoredStream(packed, 0xFF)) { LzssUnpack(input, unpacked); } using (var index = new BinMemoryStream(unpacked)) { var key = index.ReadBytes(256); int count = index.ReadInt32(); if (!IsSaneCount(count)) { return(null); } var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { int name_length = index.ReadInt32(); var name = index.ReadCString(name_length); var entry = FormatCatalog.Instance.Create <GmlEntry> (name); entry.Offset = index.ReadUInt32() + data_offset; entry.Size = index.ReadUInt32(); if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); entry.Header = index.ReadBytes(4); } return(new GmlArchive(file, this, dir, key)); } }
public override ArcFile TryOpen(ArcView file) { int count = (short)(file.View.ReadUInt16(0) ^ 0x8080); if (!IsSaneCount(count)) { return(null); } using (var input = file.CreateStream()) using (var dec = new XoredStream(input, 0x80)) using (var index = new BinaryReader(dec)) { index.BaseStream.Position = 2; int data_offset = 2 + 0x2C * count; var name_buf = new byte[0x22]; var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { if (0x22 != index.Read(name_buf, 0, 0x22)) { return(null); } var name = Binary.GetCString(name_buf, 0); if (string.IsNullOrWhiteSpace(name)) { return(null); } var entry = FormatCatalog.Instance.Create <YaneEntry> (name); entry.EncryptedSize = index.ReadUInt16(); entry.Size = index.ReadUInt32(); entry.Offset = index.ReadUInt32(); if (!entry.CheckPlacement(file.MaxOffset) || entry.Offset <= data_offset) { return(null); } dir.Add(entry); } return(new ArcFile(file, this, dir)); } }
public override Stream OpenEntry(ArcFile arc, Entry entry) { var parc = arc as PazArchiveBase; var pent = entry as PazEntry; if (null == parc || null == pent) { return(base.OpenEntry(arc, entry)); } Stream input = parc.OpenStream(entry); try { if (parc.XorKey != 0) { input = new XoredStream(input, parc.XorKey); } input = parc.DecryptEntry(input, pent); if (pent.Size < pent.AlignedSize) { input = new LimitStream(input, pent.Size); } if (pent.IsPacked) { input = new ZLibStream(input, CompressionMode.Decompress); } return(input); } catch { if (input != null) { input.Dispose(); } throw; } }
IEnumerable <string> ReadNames(string res_name, string num) { if (!VFS.FileExists(res_name)) { yield break; } using (var pack = VFS.OpenView(res_name)) { uint offset = 4 + pack.View.ReadUInt32(0); offset += 4 + pack.View.ReadUInt32(offset); uint size = pack.View.ReadUInt32(offset); offset += 4; if (offset >= pack.MaxOffset) { yield break; } using (var res = pack.CreateStream(offset, size)) using (var decrypted = new XoredStream(res, 0x80)) using (var input = new StreamReader(decrypted, Encodings.cp932)) { var line = input.ReadLine(); if (string.IsNullOrEmpty(line)) { yield break; } var match = FirstLineRe.Match(line); if (!match.Success || match.Groups[1].Value != num) { yield break; } while ((line = input.ReadLine()) != null) { yield return(line); } } } }
public override Stream OpenEntry(ArcFile arc, Entry entry) { var parc = arc as PazArchiveBase; var pent = entry as PazEntry; if (null == parc || null == pent) { return(base.OpenEntry(arc, entry)); } Stream input = null; try { long part_offset = 0; long entry_start = pent.Offset; long entry_end = pent.Offset + pent.AlignedSize; foreach (var part in parc.Parts) { long part_end_offset = part_offset + part.MaxOffset; if (entry_start < part_end_offset) { uint part_size = (uint)Math.Min(entry_end - entry_start, part_end_offset - entry_start); var entry_part = part.CreateStream(entry_start - part_offset, part_size); if (input != null) { input = new ConcatStream(input, entry_part); } else { input = entry_part; } entry_start += part_size; if (entry_start >= entry_end) { break; } } part_offset = part_end_offset; } if (null == input) { return(Stream.Null); } if (parc.XorKey != 0) { input = new XoredStream(input, parc.XorKey); } input = parc.DecryptEntry(input, pent); if (pent.Size < pent.AlignedSize) { input = new LimitStream(input, pent.Size); } if (pent.IsPacked) { input = new ZLibStream(input, CompressionMode.Decompress); } return(input); } catch { if (input != null) { input.Dispose(); } throw; } }
public override ArcFile TryOpen(ArcView file) { if (!file.Name.HasExtension(".paz")) { return(null); } uint signature = file.View.ReadUInt32(0); // XXX encryption is queried for every .paz file var scheme = QueryEncryption(file.Name, signature); uint start_offset = scheme.Version > 0 ? 0x20u : 0u; uint index_size = file.View.ReadUInt32(start_offset); start_offset += 4; byte xor_key = (byte)(index_size >> 24); if (xor_key != 0) { index_size ^= (uint)(xor_key << 24 | xor_key << 16 | xor_key << 8 | xor_key); } if (0 != (index_size & 7) || index_size + start_offset >= file.MaxOffset) { return(null); } var arc_list = new List <Entry>(); var arc_dir = VFS.GetDirectoryName(file.Name); long max_offset = file.MaxOffset; for (char suffix = 'A'; suffix <= 'Z'; ++suffix) { var part_name = VFS.CombinePath(arc_dir, file.Name + suffix); if (!VFS.FileExists(part_name)) { break; } var part = VFS.FindFile(part_name); arc_list.Add(part); max_offset += part.Size; } var arc_name = Path.GetFileNameWithoutExtension(file.Name).ToLowerInvariant(); bool is_audio = AudioPazNames.Contains(arc_name); bool is_video = VideoPazNames.Contains(arc_name); Stream input = file.CreateStream(start_offset, index_size); byte[] video_key = null; List <Entry> dir; try { if (xor_key != 0) { input = new XoredStream(input, xor_key); } var enc = new Blowfish(scheme.ArcKeys[arc_name].IndexKey); input = new InputCryptoStream(input, enc.CreateDecryptor()); using (var index = new ArcView.Reader(input)) { int count = index.ReadInt32(); if (!IsSaneCount(count)) { return(null); } if (is_video) { video_key = index.ReadBytes(0x100); } dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { var name = index.BaseStream.ReadCString(); var entry = FormatCatalog.Instance.Create <PazEntry> (name); entry.Offset = index.ReadInt64(); entry.UnpackedSize = index.ReadUInt32(); entry.Size = index.ReadUInt32(); entry.AlignedSize = index.ReadUInt32(); if (!entry.CheckPlacement(max_offset)) { return(null); } entry.IsPacked = index.ReadInt32() != 0; if (string.IsNullOrEmpty(entry.Type) && is_audio) { entry.Type = "audio"; } if (scheme.Version > 0) { string password = ""; if (!entry.IsPacked && scheme.TypeKeys != null) { password = scheme.GetTypePassword(name, is_audio); } if (!string.IsNullOrEmpty(password) || is_video) { password = string.Format("{0} {1:X08} {2}", name.ToLowerInvariant(), entry.UnpackedSize, password); entry.Key = Encodings.cp932.GetBytes(password); } } dir.Add(entry); } } } finally { input.Dispose(); } List <ArcView> parts = null; if (arc_list.Count > 0) { parts = new List <ArcView> (arc_list.Count); try { foreach (var arc_entry in arc_list) { var arc_file = VFS.OpenView(arc_entry); parts.Add(arc_file); } } catch { foreach (var part in parts) { part.Dispose(); } throw; } } if (is_video) { if (scheme.Version < 1) { var table = new byte[0x100]; for (int i = 0; i < 0x100; ++i) { table[video_key[i]] = (byte)i; } video_key = table; } return(new MovPazArchive(file, this, dir, scheme.Version, xor_key, video_key, parts)); } return(new PazArchive(file, this, dir, scheme.Version, xor_key, scheme.ArcKeys[arc_name].DataKey, parts)); }
internal IBinaryStream DecryptStream(IBinaryStream input) { var stream = new XoredStream(input.AsStream, 0xFF, true); return(new BinaryStream(stream, input.Name)); }
public override ArcFile TryOpen(ArcView file) { int count = file.View.ReadInt32(4); if (!IsSaneCount(count) || VFS.IsPathEqualsToFileName(file.Name, "00.mpk")) { return(null); } var list_name = VFS.ChangeFileName(file.Name, "00.mpk"); List <string> filelist; if (VFS.FileExists(list_name)) { using (var s = VFS.OpenStream(list_name)) using (var xs = new XoredStream(s, 0xA)) using (var reader = new StreamReader(xs, Encodings.cp932)) { filelist = new List <string> (count); string filename; while ((filename = reader.ReadLine()) != null) { filelist.Add(filename); } } } else { var base_name = Path.GetFileNameWithoutExtension(file.Name); filelist = Enumerable.Range(0, count).Select(x => string.Format("{0}#{1:D4}", base_name, x)).ToList(); } bool has_sizes = file.View.ReadByte(3) != 'P'; uint index_offset = 8; uint record_size = has_sizes ? 8u : 4u; var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { var entry = FormatCatalog.Instance.Create <Entry> (filelist[i]); entry.Offset = file.View.ReadUInt32(index_offset); if (has_sizes) { entry.Size = file.View.ReadUInt32(index_offset + 4); if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } } else if (entry.Offset > file.MaxOffset) { return(null); } dir.Add(entry); index_offset += record_size; } if (!has_sizes) { for (int i = 1; i < count; ++i) { dir[i - 1].Size = (uint)(dir[i].Offset - dir[i - 1].Offset); } dir[dir.Count - 1].Size = (uint)(file.MaxOffset - dir[dir.Count - 1].Offset); } return(new ArcFile(file, this, dir)); }
public override ArcFile TryOpen(ArcView file) { if (!file.Name.HasExtension(".dat")) { return(null); } int count = (short)(file.View.ReadUInt16(0) ^ 0x8080); if (!IsSaneCount(count)) { return(null); } var scheme = QueryScheme(file.Name); if (null == scheme) { return(null); } var dat_name = Path.GetFileName(file.Name).ToLowerInvariant(); IList <HibikiTocRecord> toc_table = null; if (scheme.ArcMap != null && scheme.ArcMap.TryGetValue(dat_name, out toc_table)) { if (toc_table.Count != count) { toc_table = null; } } var lst_name = Path.ChangeExtension(file.Name, ".lst"); Stream input; if (VFS.FileExists(lst_name)) { input = VFS.OpenStream(lst_name); } else { input = file.CreateStream(); } using (var dec = new XoredStream(input, 0x80)) using (var index = new BinaryReader(dec)) { const int name_length = 0x100; index.BaseStream.Position = 2; Func <int, Entry> read_entry; if (null == toc_table) { var name_buf = new byte[name_length]; read_entry = i => { if (name_length != index.Read(name_buf, 0, name_length)) { return(null); } var name = Binary.GetCString(name_buf, 0); var entry = FormatCatalog.Instance.Create <Entry> (name); index.ReadUInt16(); entry.Size = index.ReadUInt32(); entry.Offset = index.ReadUInt32(); return(entry); }; } else { read_entry = i => { index.BaseStream.Seek(name_length + 6, SeekOrigin.Current); index.ReadUInt32(); // throws in case of EOF var toc_entry = toc_table[i]; var entry = FormatCatalog.Instance.Create <Entry> (toc_entry.Name); entry.Offset = toc_entry.Offset; entry.Size = toc_entry.Size; return(entry); }; } var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { var entry = read_entry(i); if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); } return(new HibikiArchive(file, this, dir, scheme.ContentKey)); } }
ArcFile TryOpenWithScheme(ArcView file, int count, HibikiDatScheme scheme) { var dat_name = Path.GetFileName(file.Name).ToLowerInvariant(); IList <HibikiTocRecord> toc_table = null; if (scheme.ArcMap != null && scheme.ArcMap.TryGetValue(dat_name, out toc_table)) { if (toc_table.Count != count) { toc_table = null; } } using (var input = OpenLstIndex(file, dat_name, scheme)) using (var dec = new XoredStream(input, 0x80)) using (var index = new BinaryReader(dec)) { const int name_length = 0x100; int data_offset = 2 + (name_length + 10) * count; index.BaseStream.Position = 2; Func <int, Entry> read_entry; if (null == toc_table) { var name_buf = new byte[name_length]; read_entry = i => { if (name_length != index.Read(name_buf, 0, name_length)) { return(null); } var name = Binary.GetCString(name_buf, 0); var entry = FormatCatalog.Instance.Create <Entry> (name); index.ReadUInt16(); entry.Size = index.ReadUInt32(); entry.Offset = index.ReadUInt32(); return(entry); }; } else { read_entry = i => { index.BaseStream.Seek(name_length + 6, SeekOrigin.Current); index.ReadUInt32(); // throws in case of EOF var toc_entry = toc_table[i]; var entry = FormatCatalog.Instance.Create <Entry> (toc_entry.Name); entry.Offset = toc_entry.Offset; entry.Size = toc_entry.Size; return(entry); }; } var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { var entry = read_entry(i); if (null == entry || string.IsNullOrWhiteSpace(entry.Name) || entry.Offset < data_offset || entry.Size > file.MaxOffset) { return(null); } dir.Add(entry); } return(new HibikiArchive(file, this, dir, scheme.ContentKey)); } }
public override SoundInput TryOpen(IBinaryStream file) { var input = new XoredStream(file.AsStream, 0xFF); return(Wav.TryOpen(new BinaryStream(input, file.Name))); }
} // 'OggS' ^ 0x39 public override SoundInput TryOpen(IBinaryStream file) { var input = new XoredStream(file.AsStream, 0x39); return(new OggInput(input)); }
IBinaryStream DeobfuscateStream(IBinaryStream file, byte key) { var png = new XoredStream(file.AsStream, key, true); return(new BinaryStream(png, file.Name)); }