mirror of
https://github.com/crskycode/GARbro.git
synced 2024-11-23 21:55:34 +08:00
(KiriKiri.ChinReactionCrypt): modification.
This commit is contained in:
parent
bc82a2bdfb
commit
72f6d329f1
@ -46,6 +46,17 @@ namespace GameRes.Formats.KiriKiri
|
|||||||
[Serializable]
|
[Serializable]
|
||||||
public class ChainReactionCrypt : ICrypt
|
public class ChainReactionCrypt : ICrypt
|
||||||
{
|
{
|
||||||
|
readonly string m_list_bin;
|
||||||
|
|
||||||
|
public ChainReactionCrypt () : this ("plugin/list.bin")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChainReactionCrypt (string list_file)
|
||||||
|
{
|
||||||
|
m_list_bin = list_file;
|
||||||
|
}
|
||||||
|
|
||||||
public override void Decrypt (Xp3Entry entry, long offset, byte[] values, int pos, int count)
|
public override void Decrypt (Xp3Entry entry, long offset, byte[] values, int pos, int count)
|
||||||
{
|
{
|
||||||
uint limit = GetEncryptionLimit (entry);
|
uint limit = GetEncryptionLimit (entry);
|
||||||
@ -64,7 +75,7 @@ namespace GameRes.Formats.KiriKiri
|
|||||||
// Decrypt (entry, offset, values, pos, count);
|
// Decrypt (entry, offset, values, pos, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint GetEncryptionLimit (Xp3Entry entry)
|
internal uint GetEncryptionLimit (Xp3Entry entry)
|
||||||
{
|
{
|
||||||
uint limit;
|
uint limit;
|
||||||
if (EncryptionThresholdMap != null && EncryptionThresholdMap.TryGetValue (entry.Hash, out limit))
|
if (EncryptionThresholdMap != null && EncryptionThresholdMap.TryGetValue (entry.Hash, out limit))
|
||||||
@ -78,19 +89,19 @@ namespace GameRes.Formats.KiriKiri
|
|||||||
|
|
||||||
public override void Init (ArcFile arc)
|
public override void Init (ArcFile arc)
|
||||||
{
|
{
|
||||||
var list_bin = arc.Dir.FirstOrDefault (e => e.Name == "plugin/list.bin") as Xp3Entry;
|
var bin = ReadListBin (arc);
|
||||||
if (null == list_bin || list_bin.UnpackedSize <= 0x30)
|
if (null == bin || bin.Length <= 0x30)
|
||||||
return;
|
return;
|
||||||
var bin = new byte[list_bin.UnpackedSize];
|
|
||||||
using (var input = arc.OpenEntry (list_bin))
|
|
||||||
input.Read (bin, 0, bin.Length);
|
|
||||||
|
|
||||||
|
if (!Binary.AsciiEqual (bin, "\"\x0D\x0A"))
|
||||||
|
{
|
||||||
for (int i = 0; i < 3; ++i)
|
for (int i = 0; i < 3; ++i)
|
||||||
{
|
{
|
||||||
bin = DecodeListBin (bin);
|
bin = DecodeListBin (bin);
|
||||||
if (null == bin)
|
if (null == bin)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (null == EncryptionThresholdMap)
|
if (null == EncryptionThresholdMap)
|
||||||
EncryptionThresholdMap = new Dictionary<uint, uint>();
|
EncryptionThresholdMap = new Dictionary<uint, uint>();
|
||||||
else
|
else
|
||||||
@ -99,6 +110,17 @@ namespace GameRes.Formats.KiriKiri
|
|||||||
ParseListBin (bin);
|
ParseListBin (bin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal byte[] ReadListBin (ArcFile arc)
|
||||||
|
{
|
||||||
|
var list_bin = arc.Dir.FirstOrDefault (e => e.Name == m_list_bin) as Xp3Entry;
|
||||||
|
if (null == list_bin)
|
||||||
|
return null;
|
||||||
|
var bin = new byte[list_bin.UnpackedSize];
|
||||||
|
using (var input = arc.OpenEntry (list_bin))
|
||||||
|
input.Read (bin, 0, bin.Length);
|
||||||
|
return bin;
|
||||||
|
}
|
||||||
|
|
||||||
void ParseListBin (byte[] data)
|
void ParseListBin (byte[] data)
|
||||||
{
|
{
|
||||||
using (var mem = new MemoryStream (data))
|
using (var mem = new MemoryStream (data))
|
||||||
@ -203,4 +225,30 @@ namespace GameRes.Formats.KiriKiri
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class HachukanoCrypt : ChainReactionCrypt
|
||||||
|
{
|
||||||
|
public HachukanoCrypt () : base ("plugins/list.txt")
|
||||||
|
{
|
||||||
|
StartupTjsNotEncrypted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Decrypt (Xp3Entry entry, long offset, byte[] values, int pos, int count)
|
||||||
|
{
|
||||||
|
uint limit = GetEncryptionLimit (entry);
|
||||||
|
switch (limit)
|
||||||
|
{
|
||||||
|
case 0: return;
|
||||||
|
case 1: limit = 0x100; break;
|
||||||
|
case 2: limit = 0x200; break;
|
||||||
|
case 3: limit = entry.Size; break;
|
||||||
|
}
|
||||||
|
uint key = entry.Hash;
|
||||||
|
for (int i = 0; i < count && offset < limit; ++i, ++offset)
|
||||||
|
{
|
||||||
|
values[pos+i] ^= (byte)(offset ^ (key >> (((int)offset & 3) << 3)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user