(LINK): another encryption variant.

This commit is contained in:
morkt 2016-10-25 18:29:07 +04:00
parent 27dbb52b89
commit 13bb077b46
2 changed files with 84 additions and 48 deletions

View File

@ -192,10 +192,7 @@ namespace GameRes.Formats.Kaguya
using (var input = VFS.OpenBinaryStream (params_dat)) using (var input = VFS.OpenBinaryStream (params_dat))
{ {
var param = ParamsDeserializer.Create (input); var param = ParamsDeserializer.Create (input);
var key = param.GetKey(); return param.GetEncryption();
if (null == key)
return null;
return new LinkEncryption (key);
} }
} }
@ -426,7 +423,7 @@ namespace GameRes.Formats.Kaguya
#endregion #endregion
} }
internal class ParamsDeserializer internal abstract class ParamsDeserializer
{ {
protected IBinaryStream m_input; protected IBinaryStream m_input;
protected string m_title; protected string m_title;
@ -442,54 +439,19 @@ namespace GameRes.Formats.Kaguya
if (!header.AsciiEqual ("[SCR-PARAMS]")) if (!header.AsciiEqual ("[SCR-PARAMS]"))
return null; return null;
if (header.AsciiEqual (12, "v02")) if (header.AsciiEqual (12, "v02"))
return new ParamsDeserializer (input); return new ParamsV2Deserializer (input);
else if (header.AsciiEqual (12, "v05.6")) else if (header.AsciiEqual (12, "v05.6"))
return new ParamsV5Deserializer (input); return new ParamsV5Deserializer (input);
return null; return null;
} }
public virtual byte[] GetKey () public virtual LinkEncryption GetEncryption ()
{ {
// 毎日がM! return new LinkEncryption (GetKey());
m_input.Position = 0x17;
SkipChunk();
m_title = ReadString();
m_input.ReadCString();
SkipString();
SkipString();
m_input.ReadByte();
SkipString();
SkipString();
SkipDict();
m_input.ReadByte();
int count = m_input.ReadUInt8();
for (int i = 0; i < count; ++i)
{
m_input.ReadByte();
SkipChunk();
for (int j = 0; j < 2; ++j)
{
int n = m_input.ReadUInt8();
for (int k = 0; k < n; ++k)
SkipChunk();
}
}
SkipDict();
count = m_input.ReadUInt8();
for (int i = 0; i < count; ++i)
{
SkipChunk();
for (int j = 0; j < 2; ++j)
{
int n = m_input.ReadUInt8();
for (int k = 0; k < n; ++k)
SkipChunk();
}
}
return ReadKey();
} }
public abstract byte[] GetKey ();
protected byte[] ReadKey () protected byte[] ReadKey ()
{ {
int key_length = m_input.ReadInt32(); int key_length = m_input.ReadInt32();
@ -517,6 +479,13 @@ namespace GameRes.Formats.Kaguya
Skip (m_input.ReadUInt8()); Skip (m_input.ReadUInt8());
} }
protected void SkipArray ()
{
int count = m_input.ReadUInt8();
for (int i = 0; i < count; ++i)
SkipChunk();
}
protected void SkipDict () protected void SkipDict ()
{ {
int count = m_input.ReadUInt8(); int count = m_input.ReadUInt8();
@ -528,6 +497,70 @@ namespace GameRes.Formats.Kaguya
} }
} }
internal class ParamsV2Deserializer : ParamsDeserializer
{
public ParamsV2Deserializer (IBinaryStream input) : base (input)
{
}
public override LinkEncryption GetEncryption ()
{
var key = GetKey();
return new LinkEncryption (key, m_title != "幼なじみと甘~くエッチに過ごす方法");
}
public override byte[] GetKey ()
{
m_input.Position = 0x17;
SkipChunk();
m_title = ReadString();
m_input.ReadCString();
SkipString();
SkipString();
m_input.ReadByte();
SkipString();
SkipString();
SkipDict();
m_input.ReadByte();
if ("幼なじみと甘~くエッチに過ごす方法" == m_title)
{
int count = m_input.ReadUInt8();
for (int i = 0; i < count; ++i)
{
m_input.ReadByte();
SkipChunk();
SkipArray();
SkipChunk();
}
SkipArray();
SkipArray();
m_input.ReadInt32();
return m_input.ReadBytes (240000);
}
else // 毎日がM!
{
int count = m_input.ReadUInt8();
for (int i = 0; i < count; ++i)
{
m_input.ReadByte();
SkipChunk();
SkipArray();
SkipArray();
}
SkipDict();
count = m_input.ReadUInt8();
for (int i = 0; i < count; ++i)
{
SkipChunk();
SkipArray();
SkipArray();
}
return ReadKey();
}
}
}
internal class ParamsV5Deserializer : ParamsDeserializer internal class ParamsV5Deserializer : ParamsDeserializer
{ {
public ParamsV5Deserializer (IBinaryStream input) : base (input) public ParamsV5Deserializer (IBinaryStream input) : base (input)
@ -596,19 +629,21 @@ namespace GameRes.Formats.Kaguya
delegate Stream Decryptor (LinkArchive arc, LinkEntry entry); delegate Stream Decryptor (LinkArchive arc, LinkEntry entry);
public LinkEncryption (byte[] key) public LinkEncryption (byte[] key, bool anm_encrypted = true)
{ {
if (null == key || 0 == key.Length) if (null == key || 0 == key.Length)
throw new ArgumentException ("Invalid encryption key"); throw new ArgumentException ("Invalid encryption key");
m_key = key; m_key = key;
m_type_table = new [] var table = new List<Tuple<string, Decryptor>>
{ {
new Tuple<string, Decryptor> ("BM", (a, e) => DecryptImage (a, e, 0x36)), new Tuple<string, Decryptor> ("BM", (a, e) => DecryptImage (a, e, 0x36)),
new Tuple<string, Decryptor> ("AP-2", (a, e) => DecryptImage (a, e, 0x18)), new Tuple<string, Decryptor> ("AP-2", (a, e) => DecryptImage (a, e, 0x18)),
new Tuple<string, Decryptor> ("AP-3", (a, e) => DecryptImage (a, e, 0x18)), new Tuple<string, Decryptor> ("AP-3", (a, e) => DecryptImage (a, e, 0x18)),
new Tuple<string, Decryptor> ("AP", (a, e) => DecryptImage (a, e, 0xC)), new Tuple<string, Decryptor> ("AP", (a, e) => DecryptImage (a, e, 0xC)),
new Tuple<string, Decryptor> ("AN00", (a, e) => DecryptAn00 (a, e)),
}; };
if (anm_encrypted)
table.Add (new Tuple<string, Decryptor> ("AN00", (a, e) => DecryptAn00 (a, e)));
m_type_table = table.ToArray();
} }
public Stream DecryptEntry (LinkArchive arc, LinkEntry entry) public Stream DecryptEntry (LinkArchive arc, LinkEntry entry)

View File

@ -961,6 +961,7 @@ Harami Tama<br/>
Mahokoi ~Ecchi na Mahou de Koi x Koi Shichau~<br/> Mahokoi ~Ecchi na Mahou de Koi x Koi Shichau~<br/>
Mainichi ga M!<br/> Mainichi ga M!<br/>
Ningyou no Yakata<br/> Ningyou no Yakata<br/>
Osananajimi to Ama~ku Ecchi ni Sugosu Houhou<br/>
</td></tr> </td></tr>
<tr class="odd"><td>*.alp</td><td><tt>AP-0</tt><br/><tt>AP-2</tt></td><td>No</td></tr> <tr class="odd"><td>*.alp</td><td><tt>AP-0</tt><br/><tt>AP-2</tt></td><td>No</td></tr>
<tr class="odd last"><td>*.anm</td><td><tt>AN00</tt></td><td>No</td></tr> <tr class="odd last"><td>*.anm</td><td><tt>AN00</tt></td><td>No</td></tr>