static Smb2ChainedCompressedPacket() { var header = new Compression_Transform_Header(); FirstPayloadHeaderOffset = TypeMarshal.GetBlockMemorySize(header.ProtocolId) + TypeMarshal.GetBlockMemorySize(header.OriginalCompressedSegmentSize); var payloadHeader = new SMB2_COMPRESSION_PAYLOAD_HEADER(); FieldSizeOriginalPayloadSize = TypeMarshal.GetBlockMemorySize(payloadHeader.OriginalPayloadSize); }
private static Tuple <SMB2_COMPRESSION_PAYLOAD_HEADER, object> ChainedCompressWithCompressionAlgorithm(byte[] data, Smb2CompressionInfo compressionInfo, ref bool isFirst) { var compressionAlgorithm = GetPreferredCompressionAlgorithm(compressionInfo); SMB2_COMPRESSION_PAYLOAD_HEADER payloadHeader; bool isFirstCopy; isFirstCopy = isFirst; var compressedPayloadHeader = SMB2_COMPRESSION_PAYLOAD_HEADER.Create(compressionAlgorithm, 0, (UInt32)data.Length, ref isFirstCopy); isFirstCopy = isFirst; var uncompressedPayloadHeader = SMB2_COMPRESSION_PAYLOAD_HEADER.Create(CompressionAlgorithm.NONE, (UInt32)data.Length, 0, ref isFirstCopy); isFirst = isFirstCopy; byte[] payloadData; if (compressionAlgorithm != CompressionAlgorithm.NONE) { var compressor = GetCompressor(compressionAlgorithm); var compressedData = compressor.Compress(data); int compressedDataLength = TypeMarshal.ToBytes(compressedPayloadHeader).Length + compressedData.Length; int uncompressedDataLength = TypeMarshal.ToBytes(uncompressedPayloadHeader).Length + data.Length; if (compressedDataLength < uncompressedDataLength) { compressedPayloadHeader.Length = (UInt32)(compressedData.Length + FieldSizeOriginalPayloadSize); payloadHeader = compressedPayloadHeader; payloadData = compressedData; } else { payloadHeader = uncompressedPayloadHeader; payloadData = data; } } else { payloadHeader = uncompressedPayloadHeader; payloadData = data; } return(new Tuple <SMB2_COMPRESSION_PAYLOAD_HEADER, object>(payloadHeader, payloadData)); }
static Smb2Compression() { compressorInstances = new Dictionary <CompressionAlgorithm, XcaCompressor> { [CompressionAlgorithm.LZNT1] = new LZNT1Compressor(), [CompressionAlgorithm.LZ77] = new PlainLZ77Compressor(), [CompressionAlgorithm.LZ77Huffman] = new LZ77HuffmanCompressor() }; decompressorInstances = new Dictionary <CompressionAlgorithm, XcaDecompressor> { [CompressionAlgorithm.LZNT1] = new LZNT1Decompressor(), [CompressionAlgorithm.LZ77] = new PlainLZ77Decompressor(), [CompressionAlgorithm.LZ77Huffman] = new LZ77HuffmanDecompressor() }; var pattern = new SMB2_COMPRESSION_PATTERN_PAYLOAD_V1(); PatternPayloadLength = TypeMarshal.GetBlockMemorySize(pattern); var payloadHeader = new SMB2_COMPRESSION_PAYLOAD_HEADER(); FieldSizeOriginalPayloadSize = TypeMarshal.GetBlockMemorySize(payloadHeader.OriginalPayloadSize); }
private static Smb2Packet CompressWithPatternV1(Smb2CompressiblePacket packet, Smb2CompressionInfo compressionInfo, Smb2Role role) { var data = packet.ToBytes(); var dataToCompress = data; if (compressionInfo.CompressBufferOnly) { dataToCompress = data.Skip((packet as IPacketBuffer).BufferOffset).ToArray(); } SMB2_COMPRESSION_PATTERN_PAYLOAD_V1?forwardDataPattern; SMB2_COMPRESSION_PATTERN_PAYLOAD_V1?backwardDataPattern; ScanForPatternV1(dataToCompress, out forwardDataPattern, out backwardDataPattern); if (forwardDataPattern == null && backwardDataPattern == null) { // Regress to non-chained since no pattern is found at front or end. return(CompressForNonChained(packet, compressionInfo, role)); } var result = new Smb2ChainedCompressedPacket(); result.OriginalPacket = packet; result.Header = new Compression_Transform_Header(); result.Header.ProtocolId = Smb2Consts.ProtocolIdInCompressionTransformHeader; result.Header.OriginalCompressedSegmentSize = (UInt32)data.Length; result.Header.Flags = Compression_Transform_Header_Flags.SMB2_COMPRESSION_FLAG_CHAINED; var payloads = new List <Tuple <SMB2_COMPRESSION_PAYLOAD_HEADER, object> >(); bool isFirst = true; if (compressionInfo.CompressBufferOnly) { var header = data.Take((packet as IPacketBuffer).BufferOffset).ToArray(); var payloadHeader = SMB2_COMPRESSION_PAYLOAD_HEADER.Create(CompressionAlgorithm.NONE, (UInt32)header.Length, 0, ref isFirst); payloads.Add(new Tuple <SMB2_COMPRESSION_PAYLOAD_HEADER, object>(payloadHeader, header)); } if (forwardDataPattern != null) { var payloadHeader = SMB2_COMPRESSION_PAYLOAD_HEADER.Create(CompressionAlgorithm.Pattern_V1, (UInt32)PatternPayloadLength, 0, ref isFirst); payloads.Add(new Tuple <SMB2_COMPRESSION_PAYLOAD_HEADER, object>(payloadHeader, forwardDataPattern)); } int forwardDataPatternLength = (int)(forwardDataPattern?.Repetitions ?? 0); int backwardDataPatternLength = (int)(backwardDataPattern?.Repetitions ?? 0); var innerData = dataToCompress.Skip(forwardDataPatternLength).Take(dataToCompress.Length - forwardDataPatternLength - backwardDataPatternLength).ToArray(); if (innerData.Length > 0) { var innerPayload = ChainedCompressWithCompressionAlgorithm(innerData, compressionInfo, ref isFirst); payloads.Add(innerPayload); } if (backwardDataPattern != null) { var payloadHeader = SMB2_COMPRESSION_PAYLOAD_HEADER.Create(CompressionAlgorithm.Pattern_V1, (UInt32)PatternPayloadLength, 0, ref isFirst); payloads.Add(new Tuple <SMB2_COMPRESSION_PAYLOAD_HEADER, object>(payloadHeader, backwardDataPattern)); } result.Payloads = payloads.ToArray(); return(result); }