mirror of
https://github.com/crskycode/GARbro.git
synced 2024-12-25 12:24:12 +08:00
(QLIE): better handling of version 1 archives.
This commit is contained in:
parent
48451ea482
commit
28aed8df37
@ -91,12 +91,14 @@ namespace GameRes.Formats.Qlie
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
static readonly string[] KeyLocations = { ".", "..", @"..\DLL", "DLL" };
|
static readonly string[] KeyLocations = { ".", "..", @"..\DLL", "DLL" };
|
||||||
|
|
||||||
public static Dictionary<string, byte[]> KnownKeys = new Dictionary<string, byte[]>();
|
static QlieScheme DefaultScheme = new QlieScheme { KnownKeys = new Dictionary<string, byte[]>() };
|
||||||
|
|
||||||
|
public static Dictionary<string, byte[]> KnownKeys { get { return DefaultScheme.KnownKeys; } }
|
||||||
|
|
||||||
public override ResourceScheme Scheme
|
public override ResourceScheme Scheme
|
||||||
{
|
{
|
||||||
get { return new QlieScheme { KnownKeys = KnownKeys }; }
|
get { return DefaultScheme; }
|
||||||
set { KnownKeys = ((QlieScheme)value).KnownKeys; }
|
set { DefaultScheme = (QlieScheme)value; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public override ArcFile TryOpen (ArcView file)
|
public override ArcFile TryOpen (ArcView file)
|
||||||
@ -156,7 +158,8 @@ namespace GameRes.Formats.Qlie
|
|||||||
entry.UnpackedSize = index.ReadUInt32(); // [+0C]
|
entry.UnpackedSize = index.ReadUInt32(); // [+0C]
|
||||||
entry.IsPacked = 0 != index.ReadInt32(); // [+10]
|
entry.IsPacked = 0 != index.ReadInt32(); // [+10]
|
||||||
entry.EncryptionMethod = index.ReadInt32(); // [+14]
|
entry.EncryptionMethod = index.ReadInt32(); // [+14]
|
||||||
entry.Hash = index.ReadUInt32(); // [+18]
|
if (pack_version.Major > 1)
|
||||||
|
entry.Hash = index.ReadUInt32(); // [+18]
|
||||||
entry.KeyFile = key_file;
|
entry.KeyFile = key_file;
|
||||||
if (read_pack_keyfile && entry.Name.Contains ("pack_keyfile"))
|
if (read_pack_keyfile && entry.Name.Contains ("pack_keyfile"))
|
||||||
{
|
{
|
||||||
|
@ -56,7 +56,9 @@ namespace GameRes.Formats.Qlie
|
|||||||
|
|
||||||
public static IEncryption Create (ArcView file, Version version, byte[] arc_key)
|
public static IEncryption Create (ArcView file, Version version, byte[] arc_key)
|
||||||
{
|
{
|
||||||
if (2 == version.Major || 1 == version.Major)
|
if (1 == version.Major)
|
||||||
|
return new EncryptionV1();
|
||||||
|
else if (2 == version.Major)
|
||||||
return new EncryptionV2();
|
return new EncryptionV2();
|
||||||
else if (3 == version.Major && 1 == version.Minor)
|
else if (3 == version.Major && 1 == version.Minor)
|
||||||
return new EncryptionV3_1 (file);
|
return new EncryptionV3_1 (file);
|
||||||
@ -73,6 +75,55 @@ namespace GameRes.Formats.Qlie
|
|||||||
public abstract void DecryptEntry (byte[] data, int offset, int length, QlieEntry entry);
|
public abstract void DecryptEntry (byte[] data, int offset, int length, QlieEntry entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal class EncryptionV1 : QlieEncryption
|
||||||
|
{
|
||||||
|
public EncryptionV1 ()
|
||||||
|
{
|
||||||
|
NameKey = 0xC4;
|
||||||
|
ArcKey = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override uint CalculateHash (byte[] data, int length)
|
||||||
|
{
|
||||||
|
return 0; // not implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string DecryptName (byte[] name, int name_length)
|
||||||
|
{
|
||||||
|
int key = NameKey ^ 0x3E;
|
||||||
|
for (int k = 0; k < name_length; ++k)
|
||||||
|
name[k] ^= (byte)(((k + 1) ^ key) + k + 1);
|
||||||
|
|
||||||
|
return Encodings.cp932.GetString (name, 0, name_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void DecryptEntry (byte[] data, int offset, int length, QlieEntry entry)
|
||||||
|
{
|
||||||
|
if (offset < 0)
|
||||||
|
throw new ArgumentOutOfRangeException ("offset");
|
||||||
|
if (length > data.Length || offset > data.Length - length)
|
||||||
|
throw new ArgumentOutOfRangeException ("length");
|
||||||
|
uint arc_key = ArcKey;
|
||||||
|
|
||||||
|
ulong hash = 0xA73C5F9DA73C5F9Dul;
|
||||||
|
ulong xor = arc_key ^ 0xFEC9753Eu;
|
||||||
|
xor |= xor << 32;
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
fixed (byte* raw = data)
|
||||||
|
{
|
||||||
|
ulong* encoded = (ulong*)(raw + offset);
|
||||||
|
for (int i = 0; i < length / 8; ++i)
|
||||||
|
{
|
||||||
|
hash = MMX.PAddD (hash, 0xCE24F523CE24F523ul) ^ xor;
|
||||||
|
xor = *encoded ^ hash;
|
||||||
|
*encoded++ = xor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
internal class EncryptionV2 : QlieEncryption
|
internal class EncryptionV2 : QlieEncryption
|
||||||
{
|
{
|
||||||
public EncryptionV2 ()
|
public EncryptionV2 ()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user