(LPK): moved Decrypt methods to EncryptionScheme class.

This commit is contained in:
morkt 2017-01-08 06:17:36 +04:00
parent 9c27c8b4f8
commit 1b3b54f4f9

View File

@ -61,6 +61,47 @@ namespace GameRes.Formats.Lucifen
public byte ContentXor; public byte ContentXor;
public uint RotatePattern; public uint RotatePattern;
public bool ImportGameInit; public bool ImportGameInit;
internal void DecryptContent (byte[] data)
{
for (int i = 0; i < data.Length; ++i)
{
int v = data[i] ^ ContentXor;
data[i] = Binary.RotByteR ((byte)v, 4);
}
}
internal unsafe void DecryptEntry (byte[] data, int length, uint key)
{
uint pattern = RotatePattern;
fixed (byte* buf_raw = data)
{
uint* encoded = (uint*)buf_raw;
length /= 4;
for (int i = 0; i < length; ++i)
{
encoded[i] ^= key;
pattern = Binary.RotR (pattern, 4);
key = Binary.RotL (key, (int)pattern);
}
}
}
internal unsafe void DecryptIndex (byte[] data, int length, uint key)
{
uint pattern = RotatePattern;
fixed (byte* buf_raw = data)
{
uint* encoded = (uint*)buf_raw;
length /= 4;
for (int i = 0; i < length; ++i)
{
encoded[i] ^= key;
pattern = Binary.RotL (pattern, 4);
key = Binary.RotR (key, (int)pattern);
}
}
}
} }
[Serializable] [Serializable]
@ -150,37 +191,31 @@ namespace GameRes.Formats.Lucifen
{ {
if (0 == entry.Size) if (0 == entry.Size)
return Stream.Null; return Stream.Null;
var larc = arc as LuciArchive;
var lent = entry as LuciEntry; var lent = entry as LuciEntry;
Stream input = arc.File.CreateStream (entry.Offset, entry.Size); Stream input = arc.File.CreateStream (entry.Offset, entry.Size);
if (null == larc || null == lent) if (null == lent)
return input; return input;
byte[] data;
using (input)
{
if (lent.IsPacked) if (lent.IsPacked)
{ {
using (var reader = new LzssReader (input, (int)lent.Size, (int)lent.UnpackedSize)) input = new LzssStream (input);
{
reader.Unpack();
data = reader.Data;
} }
} var larc = arc as LuciArchive;
else if (null == larc)
return input;
var data = new byte[lent.UnpackedSize];
using (input)
{ {
data = new byte[lent.Size];
input.Read (data, 0, data.Length); input.Read (data, 0, data.Length);
} }
}
if (larc.Info.WholeCrypt) if (larc.Info.WholeCrypt)
{ {
DecryptContent (data, larc.Scheme.ContentXor); larc.Scheme.DecryptContent (data);
} }
if (larc.Info.IsEncrypted) if (larc.Info.IsEncrypted)
{ {
int count = Math.Min (data.Length, 0x100); int count = Math.Min (data.Length, 0x100);
if (count != 0) if (count != 0)
DecryptEntry (data, count, larc.Info.Key, larc.Scheme.RotatePattern); larc.Scheme.DecryptEntry (data, count, larc.Info.Key);
} }
input = new BinMemoryStream (data, entry.Name); input = new BinMemoryStream (data, entry.Name);
if (null != larc.Info.Prefix) if (null != larc.Info.Prefix)
@ -189,45 +224,6 @@ namespace GameRes.Formats.Lucifen
return input; return input;
} }
static void DecryptContent (byte[] data, byte key)
{
for (int i = 0; i < data.Length; ++i)
{
int v = data[i] ^ key;
data[i] = Binary.RotByteR ((byte)v, 4);
}
}
static unsafe void DecryptEntry (byte[] data, int length, uint key, uint pattern)
{
fixed (byte* buf_raw = data)
{
uint* encoded = (uint*)buf_raw;
length /= 4;
for (int i = 0; i < length; ++i)
{
encoded[i] ^= key;
pattern = Binary.RotR (pattern, 4);
key = Binary.RotL (key, (int)pattern);
}
}
}
static unsafe void DecryptIndex (byte[] data, int length, uint key, uint pattern)
{
fixed (byte* buf_raw = data)
{
uint* encoded = (uint*)buf_raw;
length /= 4;
for (int i = 0; i < length; ++i)
{
encoded[i] ^= key;
pattern = Binary.RotL (pattern, 4);
key = Binary.RotR (key, (int)pattern);
}
}
}
ArcFile Open (byte[] basename, ArcView file, EncryptionScheme scheme, Key key) ArcFile Open (byte[] basename, ArcView file, EncryptionScheme scheme, Key key)
{ {
uint key1 = scheme.BaseKey.Key1; uint key1 = scheme.BaseKey.Key1;
@ -254,7 +250,7 @@ namespace GameRes.Formats.Lucifen
var index = new byte[index_size]; var index = new byte[index_size];
if (index_size != file.View.Read (8, index, 0, (uint)index_size)) if (index_size != file.View.Read (8, index, 0, (uint)index_size))
return null; return null;
DecryptIndex (index, index_size, key2, scheme.RotatePattern); scheme.DecryptIndex (index, index_size, key2);
var lpk_info = new LpkInfo var lpk_info = new LpkInfo
{ {
AlignedOffset = 0 != (flags & 1), AlignedOffset = 0 != (flags & 1),
@ -414,7 +410,7 @@ namespace GameRes.Formats.Lucifen
{ {
m_index = index; m_index = index;
int count = LittleEndian.ToInt32 (m_index, 0); int count = LittleEndian.ToInt32 (m_index, 0);
if (count <= 0 || count > 0xfffff) if (!ArchiveFormat.IsSaneCount (count))
return null; return null;
int index_offset = 4; int index_offset = 4;
int prefix_length = m_index[index_offset++]; int prefix_length = m_index[index_offset++];