コード例 #1
0
ファイル: LZNT1.cs プロジェクト: pirenga/CVE-2020-1206-POC
        public static List <LZNT1_Data> GenerateFromLZ77Match(byte[] arg, LZ77Match match, ref int processedBytes)
        {
            var result = new List <LZNT1_Data>();

            int remainingLength = match.Length;

            while (remainingLength >= 3)
            {
                var compressedWord   = new LZNT1_CompressedWord();
                int displacementBits = GetDisplcaementBits(processedBytes);
                int maximumLength    = GetMaximumLength(processedBytes);
                int length           = Math.Min(remainingLength, maximumLength);
                compressedWord.Value  = 0;
                compressedWord.Value |= (length - 3) & ((1 << (16 - displacementBits)) - 1);
                compressedWord.Value |= ((match.Distance - 1) & ((1 << displacementBits) - 1)) << (16 - displacementBits);
                result.Add(compressedWord);
                processedBytes  += length;
                remainingLength -= length;
            }
            for (int i = 0; i < remainingLength; i++)
            {
                var literal = new LZNT1_Literal();
                literal.Literal = arg[processedBytes - match.Distance];
                result.Add(literal);
                processedBytes++;
            }
            return(result);
        }
コード例 #2
0
        /// <summary>
        /// Encode data into LZ77 symbols.
        /// </summary>
        /// <param name="data">Byte array containing data to be encoded.</param>
        /// <returns>Array containing LZ77 symbols.</returns>
        public List <LZ77Symbol> Encode(byte[] data)
        {
            var hash = new LZ77HashTable();

            int i = 0;

            var result = new List <LZ77Symbol>();

            while (i < data.Length)
            {
                LZ77Symbol symbol;
                int        location = hash.Match(data, i);
                var        distance = i - location;
                if (distance > 0 && distance <= MaximumMatchDistance)
                {
                    int len = 0;
                    int k   = location;
                    for (int j = i; j < data.Length; j++)
                    {
                        if (len > MaximumMatchLength)
                        {
                            break;
                        }
                        if (data[k] == data[j])
                        {
                            hash.Match(data, j);
                            k++;
                            len++;
                        }
                        else
                        {
                            break;
                        }
                    }
                    symbol = new LZ77Match()
                    {
                        Length = len, Distance = distance
                    };
                    i += len;
                }
                else
                {
                    symbol = new LZ77Literal()
                    {
                        Literal = data[i]
                    };
                    i++;
                }
                result.Add(symbol);
            }

            var eof = new LZ77EOF();

            result.Add(eof);

            return(result);
        }
コード例 #3
0
        private byte[] EncodeSymbols(List <LZ77Symbol> input)
        {
            var header = getHeader();

            /*
             *  Write the 256-byte table of symbol bit lengths
             *  While there are more literals or matches to encode
             *        If the next thing is a literal
             *          WriteBits(SymbolLength[LiteralValue], SymbolCode[LiteralValue])
             *      Else      // the next thing is a match
             *          Extract the length and distance of the match
             *          MatchSymbolValue = 256 + min(Length - 3, 15) + (16 * GetHighBit(Distance))
             *          WriteBits(SymbolLength[MatchSymbolValue], SymbolCode[MatchSymbolValue])
             *          If (Length – 3) >= 15
             *              WriteByte(min(Length – 3 – 15, 255))
             *              If (Length – 3 – 15) >= 255
             *                  WriteTwoBytes(Length – 3)
             *          WriteBits(GetHighBit(Distance), Distance – (1 << GetHighBit(Distance)))
             *  WriteBits(SymbolLength[256], SymbolCode[256])
             *  FlushBits()
             */

            var stream = new HuffmanBitStreamWriter(header);

            foreach (var symbol in input)
            {
                if (symbol is LZ77Literal)
                {
                    stream.WriteBits(code[symbol.Encode()].Length, code[symbol.Encode()].Code);
                }
                else if (symbol is LZ77Match)
                {
                    stream.WriteBits(code[symbol.Encode()].Length, code[symbol.Encode()].Code);
                    var match       = symbol as LZ77Match;
                    int matchLength = match.Length;
                    if (matchLength - 3 >= 15)
                    {
                        stream.WriteByte((byte)Math.Min(matchLength - 3 - 15, 255));
                        if (matchLength - 3 - 15 >= 255)
                        {
                            stream.WriteTwoBytes((ushort)(matchLength - 3));
                        }
                    }
                    int distance = match.Distance;
                    stream.WriteBits(LZ77Match.GetHighBit(distance), distance - (1 << LZ77Match.GetHighBit(distance)));
                }
                else if (symbol is LZ77EOF)
                {
                    stream.WriteBits(code[symbol.Encode()].Length, code[symbol.Encode()].Code);
                }
            }

            stream.FlushBits();

            return(stream.GetBytes());
        }
コード例 #4
0
ファイル: LZNT1.cs プロジェクト: pirenga/CVE-2020-1206-POC
        public override LZ77Symbol ParseToLZ77Symbol(ref int processedBytes)
        {
            var displacementBits = GetDisplcaementBits(processedBytes);
            int diplacement      = (Value >> (16 - displacementBits)) + 1;
            int length           = (Value & ((1 << (16 - displacementBits)) - 1)) + 3;
            var result           = new LZ77Match()
            {
                Distance = diplacement, Length = length
            };

            processedBytes += length;
            return(result);
        }