diff --git a/ArcFormats/ShiinaRio/WarcEncryption.cs b/ArcFormats/ShiinaRio/WarcEncryption.cs index 111b5d0b..97acb5f5 100644 --- a/ArcFormats/ShiinaRio/WarcEncryption.cs +++ b/ArcFormats/ShiinaRio/WarcEncryption.cs @@ -582,41 +582,58 @@ namespace GameRes.Formats.ShiinaRio } [Serializable] - public abstract class KeyDecryptExtra : IDecryptExtra + public abstract class KeyDecryptBase : IDecryptExtra { - readonly uint Key; - readonly byte[] DecodeTable; + protected readonly uint Seed; + protected readonly byte[] DecodeTable; + protected uint MinLength = 0x400; - public KeyDecryptExtra (uint key, byte[] decode_bin) + public KeyDecryptBase (uint seed, byte[] decode_bin) { - Key = key; + Seed = seed; DecodeTable = decode_bin; } public void Decrypt (byte[] data, int index, uint length, uint flags) { - if (length < 0x400) + if (length < MinLength) return; if ((flags & 0x202) == 0x202) - { - var k = new uint[4]; - InitKey (Key, k); - for (int i = 0; i < 0xFF; ++i) - { - uint j = k[3] ^ (k[3] << 11) ^ k[0] ^ ((k[3] ^ (k[3] << 11) ^ (k[0] >> 11)) >> 8); - k[3] = k[2]; - k[2] = k[1]; - k[1] = k[0]; - k[0] = j; - data[index + i] ^= DecodeTable[j % DecodeTable.Length]; - } - } + DecryptPre (data, index, length); if ((flags & 0x204) == 0x204) + DecryptPost (data, index, length); + } + + protected abstract void DecryptPre (byte[] data, int index, uint length); + + protected virtual void DecryptPost (byte[] data, int index, uint length) + { + data[index + 0x200] ^= (byte)Seed; + data[index + 0x201] ^= (byte)(Seed >> 8); + data[index + 0x202] ^= (byte)(Seed >> 16); + data[index + 0x203] ^= (byte)(Seed >> 24); + } + } + + [Serializable] + public abstract class KeyDecryptExtra : KeyDecryptBase + { + public KeyDecryptExtra (uint seed, byte[] decode_bin) : base (seed, decode_bin) + { + } + + protected override void DecryptPre (byte[] data, int index, uint length) + { + var k = new uint[4]; + InitKey (Seed, k); + for (int i = 0; i < 0xFF; ++i) { - data[index + 0x200] ^= (byte)Key; - data[index + 0x201] ^= (byte)(Key >> 8); - data[index + 0x202] ^= (byte)(Key >> 16); - data[index + 0x203] ^= (byte)(Key >> 24); + uint j = k[3] ^ (k[3] << 11) ^ k[0] ^ ((k[3] ^ (k[3] << 11) ^ (k[0] >> 11)) >> 8); + k[3] = k[2]; + k[2] = k[1]; + k[1] = k[0]; + k[0] = j; + data[index + i] ^= DecodeTable[j % DecodeTable.Length]; } } @@ -656,27 +673,64 @@ namespace GameRes.Formats.ShiinaRio } [Serializable] - public class UnknownCrypt : IDecryptExtra + public class MakiFesCrypt : KeyDecryptBase + { + public MakiFesCrypt (uint seed, byte[] key) : base (seed, key) + { + } + + protected override void DecryptPre (byte[] data, int index, uint length) + { + uint k = Seed; + for (int i = 0; i < 0x100; ++i) + { + k = 0x343FD * k + 0x269EC3; + data[index+i] ^= DecodeTable[((int)(k >> 16) & 0x7FFF) % DecodeTable.Length]; + } + } + } + + [Serializable] + public class MajimeCrypt : IDecryptExtra + { + public void Decrypt (byte[] data, int index, uint length, uint flags) + { + if (length < 0x200) + return; + if ((flags & 0x202) == 0x202) + { + int sum = 0; + int bit = 0; + byte v; + for (int i = 0; i < 0x100; ++i) + { + v = data[index+i]; + sum += v >> 1; + data[index+i] = (byte)(v >> 1 | bit); + bit = v << 7; + } + data[index] |= (byte)bit; + data[index + 0x104] ^= (byte)sum; + data[index + 0x105] ^= (byte)(sum >> 8); + } + } + } + + [Serializable] + public class AlcotCrypt : IDecryptExtra { public void Decrypt (byte[] data, int index, uint length, uint flags) { if (length < 0x400) return; - int src = index; - uint key = 0; - for (uint i = (length & 0x7eu) + 1; i != 0; --i) + if ((flags & 0x204) == 0x204) { - key ^= data[src++]; - for (int j = 0; j < 8; ++j) - { - uint bit = key & 1; - key = bit << 15 | key >> 1; - if (0 == bit) - key ^= 0x408; - } + var crc16 = new Kogado.Crc16(); + crc16.Update (data, index, (int)length & 0x7E | 1); + var sum = crc16.Value ^ 0xFFFF; + data[index + 0x104] ^= (byte)sum; + data[index + 0x105] ^= (byte)(sum >> 8); } - data[index+0x104] ^= (byte)key; - data[index+0x105] ^= (byte)(key >> 8); } } } diff --git a/GUI/Resources/Formats.dat b/GUI/Resources/Formats.dat index 91b6fd5a..882a3429 100644 Binary files a/GUI/Resources/Formats.dat and b/GUI/Resources/Formats.dat differ diff --git a/supported.html b/supported.html index 78fce72b..cefb2ee1 100644 --- a/supported.html +++ b/supported.html @@ -102,6 +102,7 @@ Okaa-san ga Ippai!
Chikan Ou ~Inkoku no Souzousha~
Daisaimin Rankou Gakuen
Haitoku no Gakuen ~Yami ni Sasagerareta Otome-tachi~
+Haitoku no Gakuen 2 ~Yami o Tsugu Mono~
Injoku Shinryuu Club
Moon.
Ryoujoku Famiresu Choukyou Menu
@@ -367,6 +368,7 @@ Touka Gettan
*\x00\x00\x04\x00No *.warWARC 1.7
WARC 1.5
WARC 1.3NoShiina Rio +Aneiro ShiinaRio v2.49
Can Fes! ~Itazura Majo to Naisho no Gakuensai~ ShiinaRio v2.47
Chikan Circle ShiinaRio v2.46
Chikan Circle 2 ShiinaRio v2.47
@@ -374,11 +376,13 @@ Chuuchuu Nurse ShiinaRio v2.45
Classmate no Okaa-san ShiinaRio v2.37
Draculius ShiinaRio v2.38
Enkaku Sousa 2.36 or 2.37
+Gohoushi Nurse ~Mayonaka no Kyousei Call~ ShiinaRio v2.50
Helter Skelter ShiinaRio v2.40
Hitozuma Onna Kyoushi Reika ShiinaRio v2.39
Itsuka, Dokoka de ~Ano Ameoto no Kioku~2.36 or 2.37
Kichiku Nakadashi SuieibuShiinaRio v2.41
Mahou Shoujo no Taisetsu na Koto ShiinaRio v2.47
+Maki Fes! ShiinaRio v2.50
Nagagutsu wo Haita Deco ShiinaRio v2.39
Najimi no Oba-chan ShiinaRio v2.47
Niizuma to Yuukaihan ShiinaRio v2.45
@@ -386,9 +390,12 @@ Otome Chibaku Yuugi ShiinaRio v2.40
Otome Juurin Yuugi ShiinaRio v2.37
Ran→Sem ShiinaRio v2.47
Rin×Sen ShiinaRio v2.47
+Shinigami no Testament ShiinaRio v2.49
Shojo MamaShiinaRio v2.49
Tantei Shounen Asome old version, like 2.twenty-something
Tekoire Princess!ShiinaRio v2.37
+Wana ~Hakudaku Mamire no Houkago~ShiinaRio v2.36
+Wana II ~Gang Rape~ShiinaRio v2.44
Yoyogi Hitozuma Senmon GakuinShiinaRio v2.37
Zansho Omimai MoushiagemasuShiinaRio v2.41
@@ -431,6 +438,7 @@ Shuffle! Essence+
Clover Heart's
Geki Tama! ~Seiryou Gakuen Engeki Bu~
Maria ~Tenshi no Kiss to Akuma no Hanayome~
+Marionette Zero
Triptych
Tsurugi Otome Noah