Example #1
0
        AbstractAxDecoder getDecoder(BinaryReader reader)
        {
            long startPosition = reader.BaseStream.Position;

            char[] buffer = reader.ReadChars(4);
            string bufStr = new string(buffer);

            reader.BaseStream.Seek(startPosition, SeekOrigin.Begin);
            if (bufStr.Equals("HSP2", StringComparison.Ordinal))
            {
                return(new Ax2Decoder());
            }
            else if (bufStr.Equals("HSP3", StringComparison.Ordinal))
            {
                Ax3Decoder decoder = new Ax3Decoder();
                decoder.Dictionary = dictionary;
                return(decoder);
            }
            throw new HspDecoderException("HSP2でもHSP3でもない形式");
        }
        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);
        }