mirror of
https://github.com/crskycode/GARbro.git
synced 2025-01-12 04:49:32 +08:00
(ArcOpener.OpenEntry): decrypt ASB scripts (the only known key is hard-coded).
This commit is contained in:
parent
8ee82a8c31
commit
35ad091adf
@ -29,6 +29,7 @@ using System.ComponentModel.Composition;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using GameRes.Formats.Strings;
|
using GameRes.Formats.Strings;
|
||||||
using GameRes.Utility;
|
using GameRes.Utility;
|
||||||
|
using ZLibNet;
|
||||||
|
|
||||||
namespace GameRes.Formats.AZSys
|
namespace GameRes.Formats.AZSys
|
||||||
{
|
{
|
||||||
@ -83,6 +84,44 @@ namespace GameRes.Formats.AZSys
|
|||||||
return new ArcFile (file, this, dir);
|
return new ArcFile (file, this, dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static readonly uint[] KnownKeys = new uint[] { 0x1de71cb9 }; // Triptych
|
||||||
|
|
||||||
|
public override Stream OpenEntry (ArcFile arc, Entry entry)
|
||||||
|
{
|
||||||
|
if (entry.Size < 20
|
||||||
|
|| ".asb" != Path.GetExtension (entry.Name).ToLowerInvariant()
|
||||||
|
|| !arc.File.View.AsciiEqual (entry.Offset, "ASB\x1a"))
|
||||||
|
return arc.File.CreateStream (entry.Offset, entry.Size);
|
||||||
|
uint packed = arc.File.View.ReadUInt32 (entry.Offset+4);
|
||||||
|
uint unpacked = arc.File.View.ReadUInt32 (entry.Offset+8);
|
||||||
|
if (12 + packed != entry.Size)
|
||||||
|
return arc.File.CreateStream (entry.Offset, entry.Size);
|
||||||
|
|
||||||
|
uint key = KnownKeys[0] ^ unpacked;
|
||||||
|
key ^= ((key << 12) | key) << 11;
|
||||||
|
|
||||||
|
uint first = arc.File.View.ReadUInt16 (entry.Offset+16);
|
||||||
|
first = (first - key) & 0xffff;
|
||||||
|
if (first != 0xda78) // doesn't look like zlib stream
|
||||||
|
return arc.File.CreateStream (entry.Offset, entry.Size);
|
||||||
|
byte[] input = new byte[packed];
|
||||||
|
arc.File.View.Read (entry.Offset+12, input, 0, packed);
|
||||||
|
unsafe
|
||||||
|
{
|
||||||
|
fixed (byte* raw = input)
|
||||||
|
{
|
||||||
|
uint* encoded = (uint*)raw;
|
||||||
|
for (int i = 0; i < input.Length/4; ++i)
|
||||||
|
encoded[i] -= key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// first 4 bytes are CRC32 of the compressed stream
|
||||||
|
uint checksum = LittleEndian.ToUInt32 (input, 0);
|
||||||
|
if (checksum != Crc32.Compute (input, 4, input.Length-4))
|
||||||
|
return arc.File.CreateStream (entry.Offset, entry.Size);
|
||||||
|
return new ZLibStream (new MemoryStream (input, 4, input.Length-4), CompressionMode.Decompress);
|
||||||
|
}
|
||||||
|
|
||||||
internal class IndexReader
|
internal class IndexReader
|
||||||
{
|
{
|
||||||
byte[] m_input;
|
byte[] m_input;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user