internal static HspCryptoTransform CrackEncryption(byte[] plain, byte[] encrypted, Hsp3Dictionary dictionary) { int count = Math.Min(plain.Length, encrypted.Length); if (count < 2) { throw new Exception("情報サイズが不足"); } byte[] difBuffer = new byte[count]; //byte baseXor = plain[0]; byte prevByte = 0; byte andByte = 0xFF; byte orByte = 0x00; for (int i = 0; i < count; i++) { difBuffer[i] = XorAddTransform.Dif(plain[i], prevByte); prevByte = plain[i]; //difBuffer[i] ^= baseXor; andByte &= difBuffer[i]; orByte |= difBuffer[i]; } if ((andByte != 0x00) || (orByte != 0xFF)) { throw new Exception("平文の情報が足りません"); } List <XorAddTransform> transformList = new List <XorAddTransform>(); //deHSP100 総当りテスト。 for (int i = 0; i < 0x100; i++) { XorAddTransform xoradd; bool ok = true; byte add = (byte)(i & 0x7F); xoradd.XorSum = (i >= 0x80); xoradd.AddByte = add; xoradd.XorByte = XorAddTransform.GetXorByte(add, difBuffer[0], encrypted[0], xoradd.XorSum); //チェック for (int index = 1; index < count; index++) { if (encrypted[index] != xoradd.Encode(difBuffer[index])) { ok = false; break; } } if (ok) { AbstractAxDecoder decoder = null; if (plain[3] == 0x32) { decoder = new Ax2Decoder(); } else { Ax3Decoder decoder3 = new Ax3Decoder(); decoder3.Dictionary = dictionary; decoder = decoder3; } HspCryptoTransform decryptor = new HspCryptoTransform(); decryptor.xorAdd = xoradd; byte[] buffer = (byte[])encrypted.Clone(); buffer = decryptor.Decryption(buffer); MemoryStream stream = new MemoryStream(buffer); BinaryReader reader = new BinaryReader(stream, Encoding.GetEncoding("SHIFT-JIS")); try { decoder.Decode(reader); transformList.Add(xoradd); } catch (Exception e) { Console.WriteLine(e); } } } //候補が2つ以上ならアルゴリズムに問題アリ。 if (transformList.Count > 1) { throw new Exception("復号器の異常"); } if (transformList.Count == 1) { HspCryptoTransform ret = new HspCryptoTransform(); ret.xorAdd = transformList[0]; return(ret); } return(null); }
internal static HspCryptoTransform CrackEncryption(byte[] plain, byte[] encrypted, Hsp3Dictionary dictionary, string filePath) { int count = Math.Min(plain.Length, encrypted.Length); if (count < 2) { throw new Exception("情報サイズが不足"); } byte[] difBuffer = new byte[count]; //byte baseXor = plain[0]; byte prevByte = 0; byte andByte = 0xFF; byte orByte = 0x00; for (int i = 0; i < count; i++) { difBuffer[i] = XorAddTransform.Dif(plain[i], prevByte); prevByte = plain[i]; //difBuffer[i] ^= baseXor; andByte &= difBuffer[i]; orByte |= difBuffer[i]; } if ((andByte != 0x00) || (orByte != 0xFF)) { throw new Exception("平文の情報が足りません"); } List <XorAddTransform> transformList = new List <XorAddTransform>(); //deHSP100 総当りテスト。 for (int i = 0; i < 0x100; i++) { XorAddTransform xoradd; bool ok = true; byte add = (byte)(i & 0x7F); xoradd.XorSum = (i >= 0x80); xoradd.AddByte = add; xoradd.XorByte = XorAddTransform.GetXorByte(add, difBuffer[0], encrypted[0], xoradd.XorSum); //チェック for (int index = 1; index < count; index++) { if (encrypted[index] != xoradd.Encode(difBuffer[index])) { ok = false; break; } } if (ok) { global::KttK.HspDecompiler.HspConsole.Write(xoradd.ToString()); HspCryptoTransform decryptor = new HspCryptoTransform(); decryptor.xorAdd = xoradd; byte[] buffer = (byte[])encrypted.Clone(); buffer = decryptor.Decryption(buffer); MemoryStream stream = new MemoryStream(buffer); BinaryReader reader = new BinaryReader(stream, Encoding.GetEncoding("SHIFT-JIS")); HspDecoder decoder = new HspDecoder(); /* ファイル名の決定 */ string outputFileExtention = null; if (plain[3] == 0x32) { outputFileExtention = ".as"; } else { outputFileExtention = ".hsp"; } string dirName = Path.GetDirectoryName(filePath) + @"\"; string outputFileName = Path.GetFileNameWithoutExtension(filePath); string outputPath = dirName + outputFileName + outputFileExtention; int suffix = 1; while (File.Exists(outputPath)) { outputFileName = string.Format("{0} ({1})", outputFileName, suffix); outputPath = dirName + outputFileName + outputFileExtention; suffix++; } try { decoder.Decode(reader, outputPath); transformList.Add(xoradd); break; } catch (Exception e) { Console.WriteLine(e); } } } if (transformList.Count == 1) { HspCryptoTransform ret = new HspCryptoTransform(); ret.xorAdd = transformList[0]; return(ret); } return(null); }