public override ImageMetaData ReadMetaData(IBinaryStream stream) { var key = new byte[0x10]; stream.Position = 4; if (key.Length != stream.Read(key, 0, key.Length)) { return(null); } using (var enc = new InputProxyStream(stream.AsStream, true)) using (var crypto = new InputCryptoStream(enc, new GaxTransform(key))) using (var input = new BinaryStream(crypto, stream.Name)) { var info = Png.ReadMetaData(input); if (null == info) { return(null); } return(new GaxMetaData { OffsetX = info.OffsetX, OffsetY = info.OffsetY, Width = info.Width, Height = info.Height, BPP = info.BPP, Key = key, }); } }
public override Stream OpenEntry(ArcFile arc, Entry entry) { var larc = arc as LunaArchive; if (null == arc || !arc.File.View.AsciiEqual(entry.Offset, "LZSS")) { return(base.OpenEntry(arc, entry)); } uint unpacked_size = arc.File.View.ReadUInt32(entry.Offset + 4); Stream input = arc.File.CreateStream(entry.Offset + 8, entry.Size - 8); if (larc.Key != null) { var bf = new Blowfish(larc.Key); input = new InputCryptoStream(input, bf.CreateDecryptor()); return(new LimitStream(input, unpacked_size)); } else { var lz = new LzssStream(input); lz.Config.FrameInitPos = 0xFF0; return(lz); } }
public override ImageData Read(IBinaryStream stream, ImageMetaData info) { using (var proxy = new ProxyStream(stream.AsStream, true)) using (var crypt = new InputCryptoStream(proxy, new TigTransform())) using (var input = new BinaryStream(crypt, stream.Name)) return(base.Read(input, info)); }
void UnpackStream(byte[] output, int packed_size) { if (0 == packed_size) { m_input.Read(output, 0, output.Length); return; } var input = m_input.AsStream; var input_pos = m_input.Position; if (m_info.IsEncrypted) { input = new StreamRegion(input, input_pos, packed_size, true); input = new InputCryptoStream(input, new SjTransform(m_info.Key)); } try { UnpackRle(input, output); } finally { if (input != m_input.AsStream) { input.Dispose(); } m_input.Position = input_pos + packed_size; } }
public override ImageMetaData ReadMetaData(IBinaryStream stream) { using (var sha = SHA1.Create()) { var key = sha.ComputeHash(KnownKey).Take(16).ToArray(); using (var proxy = new InputProxyStream(stream.AsStream, true)) using (var crypto = new InputCryptoStream(proxy, new Rc4Transform(key))) using (var input = new BinaryStream(crypto, stream.Name)) { var info = base.ReadMetaData(input); if (null == info) { return(null); } return(new Rc4PngMetaData { Width = info.Width, Height = info.Height, OffsetX = info.OffsetX, OffsetY = info.OffsetY, BPP = info.BPP, Key = key, }); } } }
public ImageData Unpack() { Stream input = new StreamRegion(m_input.AsStream, 0x18, m_info.PackedLength, true); if (m_info.IsEncrypted) { input = new InputCryptoStream(input, new SjTransform(m_info.Key)); } using (input = new LzssStream(input)) { var header = new byte[0x28]; input.Read(header, 0, header.Length); if (8 == m_info.BPP) { Palette = ImageFormat.ReadPalette(input); } input.Read(m_output, 0, m_output.Length); } if (m_info.AlphaLength > 0 && m_info.BPP == 8) { m_input.Position = 0x18 + m_info.PackedLength; var alpha = new byte[m_info.AlphaLength]; using (var lzss = new LzssStream(m_input.AsStream, LzssMode.Decompress, true)) lzss.Read(alpha, 0, alpha.Length); return(ApplyAlpha(alpha)); } return(ImageData.CreateFlipped(m_info, Format, Palette, m_output, Stride)); }
public override ImageData Read(IBinaryStream stream, ImageMetaData info) { var meta = (GaxMetaData)info; using (var enc = new StreamRegion(stream.AsStream, 0x14, true)) using (var crypto = new InputCryptoStream(enc, new GaxTransform(meta.Key))) using (var input = new BinaryStream(crypto, stream.Name)) return(Png.Read(input, info)); }
public override ImageData Read(IBinaryStream stream, ImageMetaData info) { var rc4 = (Rc4PngMetaData)info; using (var sha = SHA1.Create()) using (var proxy = new InputProxyStream(stream.AsStream, true)) using (var crypto = new InputCryptoStream(proxy, new Rc4Transform(rc4.Key))) using (var input = new BinaryStream(crypto, stream.Name)) return(base.Read(input, info)); }
internal IBinaryStream OpenEncrypted(IBinaryStream stream, bool seekable = false) { Stream input = new ProxyStream(stream.AsStream, true); input = new InputCryptoStream(input, new TigTransform()); if (seekable) { input = new SeekableStream(input); } return(new BinaryStream(input, stream.Name)); }
public override SoundInput TryOpen(IBinaryStream file) { uint key = file.Signature ^ 0x46464952u; Stream input = new InputCryptoStream(file.AsStream, new Ags32Transform(key)); input = new SeekableStream(input); var header = new byte[12]; input.Read(header, 0, 12); if (!header.AsciiEqual(8, "WAVE")) { return(null); } input.Position = 0; return(new WaveInput(input)); }
bool ReadV1(Stream input, int entry_size) { // NOTE CryptoStream will close an input stream using (var proxy = new InputProxyStream(input, true)) using (var xored = new InputCryptoStream(proxy, new NotTransform())) using (var lzss = new LzssStream(xored)) if (m_index.Length != lzss.Read(m_index, 0, m_index.Length)) { return(false); } int index_offset = Array.IndexOf <byte> (m_index, 0); if (-1 == index_offset || 0 == index_offset) { return(false); } Password = m_index.Take(index_offset++).ToArray(); long base_offset = 0x20 + m_packed_size; for (int i = 0; i < m_count; ++i) { var entry = new PackedEntry(); entry.Offset = LittleEndian.ToUInt32(m_index, index_offset) + base_offset; entry.Size = LittleEndian.ToUInt32(m_index, index_offset + 4); if (!entry.CheckPlacement(m_file.MaxOffset)) { return(false); } entry.UnpackedSize = LittleEndian.ToUInt32(m_index, index_offset + 8); entry.IsPacked = entry.UnpackedSize != 0; if (!entry.IsPacked) { entry.UnpackedSize = entry.Size; } int name_len = LittleEndian.ToInt32(m_index, index_offset + 0xC); if (name_len <= 0 || name_len > 0x100) { return(false); } entry.Name = Encodings.cp932.GetString(m_index, index_offset + entry_size, name_len); entry.Type = FormatCatalog.Instance.GetTypeFromName(entry.Name); m_dir.Value.Add(entry); index_offset += entry_size + name_len; } return(true); }
internal Stream OpenEncryptedEntry(AgsiArchive arc, AgsiEntry entry) { uint enc_size = entry.Size; if (enc_size > 1024) { enc_size = 1032; } using (var des = DES.Create()) { des.Key = arc.Key; des.Mode = CipherMode.ECB; des.Padding = PaddingMode.Zeros; using (var enc = arc.File.CreateStream(entry.Offset, enc_size)) using (var dec = new InputCryptoStream(enc, des.CreateDecryptor())) { var output = new byte[enc_size]; dec.Read(output, 0, output.Length); int header_size; if (!entry.IsSpecial) { header_size = output.ToInt32(output.Length - 4); if (header_size > entry.UnpackedSize) { throw new InvalidEncryptionScheme(); } } else { header_size = (int)entry.UnpackedSize; } if (!entry.IsSpecial && entry.Size > enc_size) { var header = new byte[header_size]; Buffer.BlockCopy(output, 0, header, 0, header_size); var input = arc.File.CreateStream(entry.Offset + enc_size, entry.Size - enc_size); return(new PrefixStream(header, input)); } else { return(new BinMemoryStream(output, 0, header_size, entry.Name)); } } } }
bool ReadBlock() { if (m_position >= m_length) { return(false); } m_block_start = m_position & ~0xFFFL; m_block_length = m_view.Read(m_block_start, m_block, 0, 0x1000); if (m_block_length != 0x1000) { return(false); } using (var decryptor = m_encryption.CreateDecryptor((int)(m_block_start >> 12))) using (var enc = new BinMemoryStream(m_block)) using (var dec = new InputCryptoStream(enc, decryptor)) dec.Read(m_block, 0, m_block_length); return(true); }
static byte[] CzDecryptData(byte[] data) { int padded_size = data.Length - 5; int original_size = padded_size - (data[padded_size+1] ^ data[padded_size]); uint iv_seed = data.ToUInt32 (padded_size+1) ^ CzIvSeed; using (var aes = Aes.Create()) { aes.Mode = CipherMode.CBC; aes.Padding = PaddingMode.Zeros; aes.Key = CzDefaultKey; aes.IV = CzCreateIV (iv_seed); using (var enc = new MemoryStream (data, 0, padded_size)) using (var dec = new InputCryptoStream (enc, aes.CreateDecryptor())) { var original = new byte[original_size]; dec.Read (original, 0, original_size); return original; } } }
public override Stream OpenEntry(ArcFile arc, Entry entry) { var parc = (PckArchive)arc; var pent = (PackedEntry)entry; byte data_type = arc.File.View.ReadByte(pent.Offset); Stream input = arc.File.CreateStream(pent.Offset + 1, pent.Size); if (data_type != 0) { input = new InputCryptoStream(input, parc.Encryption.CreateDecryptor()); if (data_type != 3) { input = new LimitStream(input, pent.UnpackedSize); } else { input = new BZip2InputStream(input); } } return(input); }
internal override Stream DecryptEntry(Stream input, PazEntry entry) { input = new InputCryptoStream(input, Encryption.CreateDecryptor()); var key = entry.Key; if (null == key) { return(input); } var rc4 = new Rc4Transform(key); if (Version >= 2) { uint crc = Crc32.Compute(key, 0, key.Length); int skip_rounds = (int)(crc >> 12) & 0xFF; for (int i = 0; i < skip_rounds; ++i) { rc4.NextByte(); } } return(new InputCryptoStream(input, rc4)); }
public override Stream OpenEntry(ArcFile arc, Entry entry) { var a3ent = entry as Arc3Entry; Stream input = arc.File.CreateStream(entry.Offset, entry.Size); if (null == entry) { return(input); } if (a3ent.IsEncrypted) { input = new InputCryptoStream(input, new NotTransform()); } if (!a3ent.IsPacked) { return(input); } using (input) { var data = UnpackLze(input, a3ent.UnpackedSize); return(new BinMemoryStream(data, entry.Name)); } }
Stream UnpackCps(IBinaryStream input) { input.Seek(-4, SeekOrigin.End); uint key_offset = input.ReadUInt32() - 0x7534682; input.Position = key_offset; uint key = input.ReadUInt32() + key_offset + 0x3786425; var header = input.ReadHeader(0x10); int packed_size = header.ToInt32(4); int compression = header.ToUInt16(0xA); int unpacked_size = header.ToInt32(0xC); var decryptor = new CpsTransform(packed_size, (int)key_offset, key); using (var decoded = new InputCryptoStream(input.AsStream, decryptor)) using (var cps = new BinaryStream(decoded, input.Name)) { var output = new byte[unpacked_size]; if ((compression & 1) != 0) { cps.ReadInt32(); UnpackLnd(cps, output); } else if ((compression & 2) != 0) { UnpackLnd16(cps, output); } else { cps.ReadInt32(); cps.Read(output, 0, unpacked_size); } return(new BinMemoryStream(output)); } }
public override ArcFile TryOpen(ArcView file) { if (!file.Name.HasExtension(".bin")) { return(null); } var idx_name = Path.ChangeExtension(file.Name, "idx"); if (!VFS.FileExists(idx_name)) { return(null); } var scheme = QueryScheme(file.Name); if (null == scheme) { return(null); } var dir = new List <Entry>(); using (var idx = VFS.OpenBinaryStream(idx_name)) using (var aes = Aes.Create()) { aes.Padding = PaddingMode.PKCS7; aes.Mode = CipherMode.CBC; aes.KeySize = 128; aes.Key = scheme.Key; aes.IV = scheme.IV; var input_buffer = new byte[0x100]; var unpacker = new BinDeserializer(); while (idx.PeekByte() != -1) { int length = idx.ReadInt32(); if (length <= 0) { return(null); } if (length > input_buffer.Length) { input_buffer = new byte[length]; } if (idx.Read(input_buffer, 0, length) < length) { return(null); } using (var decryptor = aes.CreateDecryptor()) using (var encrypted = new MemoryStream(input_buffer, 0, length)) using (var input = new InputCryptoStream(encrypted, decryptor)) { var info = unpacker.DeserializeEntry(input); var filename = info["fileName"] as string; if (string.IsNullOrEmpty(filename)) { return(null); } filename = filename.TrimStart('/', '\\'); var entry = Create <Entry> (filename); entry.Offset = Convert.ToInt64(info["index"]); entry.Size = Convert.ToUInt32(info["size"]); if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); } } } if (0 == dir.Count) { return(null); } var arc_aes = Aes.Create(); arc_aes.Padding = PaddingMode.PKCS7; arc_aes.Mode = CipherMode.CBC; arc_aes.KeySize = 256; arc_aes.Key = scheme.Key; arc_aes.IV = scheme.IV; return(new BinArchive(file, this, dir, arc_aes)); }
public override ArcFile TryOpen(ArcView file) { uint flags = file.View.ReadUInt32(4); if ((flags & 0x7FFFFFFF) != 0x10000) { return(null); } int count = file.View.ReadInt32(8); if (!IsSaneCount(count)) { return(null); } bool is_encrypted = (flags >> 31) != 0; uint index_size = (uint)((count * 24 + 31) & -4096) + 0xFE0u; uint names_size = file.View.ReadUInt32(12); var arc_md5 = file.View.ReadBytes(0x10, 0x10); var index = new byte[index_size + names_size]; CsafEncryption enc = null; try { if (is_encrypted) { file.View.Read(0x20, index, 0, index_size); enc = new CsafEncryption(DefaultKey, DefaultIV); using (var decryptor = enc.CreateDecryptor(0)) using (var enc_names = file.CreateStream(0x20 + index_size, names_size)) using (var dec_names = new InputCryptoStream(enc_names, decryptor)) { dec_names.Read(index, (int)index_size, (int)names_size); } } else { file.View.Read(0x20, index, 0, index_size + names_size); } using (var md5 = MD5.Create()) { var hash = md5.ComputeHash(index); if (!hash.SequenceEqual(arc_md5)) { return(null); } int index_pos = 0x10; int name_pos = (int)index_size; var dir = new List <Entry> (count); for (int i = 0; i < count; ++i) { int j; for (j = name_pos; j + 1 < index.Length; j += 2) { if (index[j] == 0 && index[j + 1] == 0) { break; } } int name_length = j - name_pos; var name = Encoding.Unicode.GetString(index, name_pos, name_length); // hash = md5.ComputeHash (index, name_pos, name_length); // == [index_pos-0x10] name_pos += name_length + 10; var entry = Create <Entry> (name); entry.Offset = (long)index.ToUInt32(index_pos) << 12; entry.Size = index.ToUInt32(index_pos + 4); index_pos += 0x18; if (!entry.CheckPlacement(file.MaxOffset)) { return(null); } dir.Add(entry); } if (!is_encrypted) { return(new ArcFile(file, this, dir)); } var arc = new CsafArchive(file, this, dir, enc); enc = null; return(arc); } } finally { if (enc != null) { enc.Dispose(); } } }
public Stream TransformStream(Stream input, byte[] key, uint flags) { var key1 = GenerateKey(key); var iv = GenerateKey(key1); ICryptoTransform decryptor; switch (flags & 0xF0000) { case 0x10000: decryptor = new Primel1Encyption(key1, iv); break; case 0x20000: decryptor = new Primel2Encyption(key1, iv); break; case 0x30000: decryptor = new Primel3Encyption(key1, iv); break; case 0x80000: // RC6 decryptor = new GameRes.Cryptography.RC6(key1, iv); break; case 0xA0000: // AES using (var aes = Rijndael.Create()) { aes.Mode = CipherMode.CFB; aes.Padding = PaddingMode.Zeros; decryptor = aes.CreateDecryptor(key1, iv); } break; default: // not encrypted return(input); } input = new InputCryptoStream(input, decryptor); try { if (0 != (flags & 0xFF)) { input = new RangePackedStream(input); } switch (flags & 0xF00) { case 0x400: input = new RlePackedStream(input); input = new MtfPackedStream(input); break; case 0x700: input = new LzssPackedStream(input); break; } return(input); } catch { 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)); }