mirror of
https://github.com/crskycode/GARbro.git
synced 2025-01-11 20:39:29 +08:00
(YpfOpener): support YSTB scripts decryption.
This commit is contained in:
parent
382b01cc9a
commit
d2e7882e6d
@ -57,6 +57,7 @@ namespace GameRes.Formats.YuRis
|
|||||||
public byte Key;
|
public byte Key;
|
||||||
public bool GuessKey;
|
public bool GuessKey;
|
||||||
public uint ExtraHeaderSize;
|
public uint ExtraHeaderSize;
|
||||||
|
public uint ScriptKey;
|
||||||
|
|
||||||
public YpfScheme () { }
|
public YpfScheme () { }
|
||||||
|
|
||||||
@ -76,6 +77,17 @@ namespace GameRes.Formats.YuRis
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class YpfArchive : ArcFile
|
||||||
|
{
|
||||||
|
public uint ScriptKey;
|
||||||
|
|
||||||
|
public YpfArchive (ArcView arc, ArchiveFormat impl, ICollection<Entry> dir, uint script_key)
|
||||||
|
: base (arc, impl, dir)
|
||||||
|
{
|
||||||
|
ScriptKey = script_key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class YuRisScheme : ResourceScheme
|
public class YuRisScheme : ResourceScheme
|
||||||
{
|
{
|
||||||
@ -115,17 +127,31 @@ namespace GameRes.Formats.YuRis
|
|||||||
if (null == dir || 0 == dir.Count)
|
if (null == dir || 0 == dir.Count)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
return new ArcFile (file, this, dir);
|
if (scheme.ScriptKey != 0)
|
||||||
|
return new YpfArchive (file, this, dir, scheme.ScriptKey);
|
||||||
|
else
|
||||||
|
return new ArcFile (file, this, dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Stream OpenEntry (ArcFile arc, Entry entry)
|
public override Stream OpenEntry (ArcFile arc, Entry entry)
|
||||||
{
|
{
|
||||||
var input = arc.File.CreateStream (entry.Offset, entry.Size);
|
|
||||||
var packed_entry = entry as PackedEntry;
|
var packed_entry = entry as PackedEntry;
|
||||||
if (null == packed_entry || !packed_entry.IsPacked)
|
var ypf = arc as YpfArchive;
|
||||||
|
Stream input = arc.File.CreateStream (entry.Offset, entry.Size);
|
||||||
|
if (null != packed_entry && packed_entry.IsPacked)
|
||||||
|
input = new ZLibStream (input, CompressionMode.Decompress);
|
||||||
|
uint unpacked_size = null == packed_entry ? entry.Size : packed_entry.UnpackedSize;
|
||||||
|
if (null == ypf || 0 == ypf.ScriptKey || unpacked_size <= 0x20
|
||||||
|
|| !entry.Name.EndsWith (".ybn", StringComparison.InvariantCultureIgnoreCase))
|
||||||
return input;
|
return input;
|
||||||
else
|
using (input)
|
||||||
return new ZLibStream (input, CompressionMode.Decompress);
|
{
|
||||||
|
var data = new byte[unpacked_size];
|
||||||
|
input.Read (data, 0, data.Length);
|
||||||
|
if (Binary.AsciiEqual (data, 0, "YSTB"))
|
||||||
|
DecryptYstb (data, ypf.ScriptKey);
|
||||||
|
return new MemoryStream (data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override ResourceOptions GetDefaultOptions ()
|
public override ResourceOptions GetDefaultOptions ()
|
||||||
@ -318,6 +344,57 @@ namespace GameRes.Formats.YuRis
|
|||||||
return SwapTable00;
|
return SwapTable00;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe void DecryptYstb (byte[] data, uint key)
|
||||||
|
{
|
||||||
|
if (data.Length <= 0x20)
|
||||||
|
return;
|
||||||
|
fixed (byte* raw = data)
|
||||||
|
{
|
||||||
|
uint* header = (uint*)raw;
|
||||||
|
uint version = header[1];
|
||||||
|
int first_item, last_item;
|
||||||
|
if (version >= 0x22A)
|
||||||
|
{
|
||||||
|
first_item = 3;
|
||||||
|
last_item = 7;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
first_item = 2;
|
||||||
|
last_item = 4;
|
||||||
|
}
|
||||||
|
uint total = 0x20;
|
||||||
|
// check sizes
|
||||||
|
for (int i = first_item; i < last_item; ++i)
|
||||||
|
{
|
||||||
|
if (header[i] >= data.Length)
|
||||||
|
return;
|
||||||
|
total += header[i];
|
||||||
|
if (total > data.Length)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (total != data.Length)
|
||||||
|
return;
|
||||||
|
byte* data8 = raw+0x20;
|
||||||
|
for (int i = first_item; i < last_item; ++i)
|
||||||
|
{
|
||||||
|
uint size = header[i];
|
||||||
|
if (0 == size)
|
||||||
|
continue;
|
||||||
|
uint* data32 = (uint*)data8;
|
||||||
|
for (uint j = size / 4; j != 0; --j)
|
||||||
|
*data32++ ^= key;
|
||||||
|
data8 = (byte*)data32;
|
||||||
|
uint k = key;
|
||||||
|
for (uint j = size & 3; j != 0; --j)
|
||||||
|
{
|
||||||
|
*data8++ ^= (byte)k;
|
||||||
|
k >>= 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class Parser
|
private class Parser
|
||||||
{
|
{
|
||||||
ArcView m_file;
|
ArcView m_file;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user