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);
        }
Example #2
0
        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);
        }