/// <summary> /// Encode the struct of Trans2Parameters into the byte array in SmbData.Trans2_Parameters /// </summary> protected override void EncodeTrans2Parameters() { int trans2ParametersSize = trans2ParametersLength; if (this.trans2Parameters.FileName != null) { trans2ParametersSize += this.trans2Parameters.FileName.Length; } this.smbData.Trans2_Parameters = new byte[trans2ParametersSize]; using (MemoryStream memoryStream = new MemoryStream(this.smbData.Trans2_Parameters)) { using (Channel channel = new Channel(null, memoryStream)) { channel.BeginWriteGroup(); channel.Write <ushort>(this.trans2Parameters.Flags); channel.Write <ushort>(this.trans2Parameters.AccessMode); channel.Write <ushort>(this.trans2Parameters.Reserved1); channel.Write <SmbFileAttributes>(this.trans2Parameters.FileAttributes); channel.Write <uint>(this.trans2Parameters.CreationTime); channel.Write <ushort>(this.trans2Parameters.OpenMode); channel.Write <uint>(this.trans2Parameters.AllocationSize); byte[] reserved = CifsMessageUtils.ToBytesArray(this.trans2Parameters.Reserved); channel.WriteBytes(reserved); if (this.trans2Parameters.FileName != null) { channel.WriteBytes(this.trans2Parameters.FileName); } channel.EndWriteGroup(); } } }
/// <summary> /// to decode the smb parameters: from the general SmbParameters to the concrete Smb Parameters. /// </summary> protected override void DecodeParameters() { if (this.smbParametersBlock.WordCount == WordCountOfCoreProtocol) { this.smbParameters.WordCount = this.smbParametersBlock.WordCount; using (MemoryStream memoryStream = new MemoryStream(CifsMessageUtils.ToBytesArray(this.SmbParametersBlock.Words))) { using (Channel channel = new Channel(null, memoryStream)) { this.smbParameters.DialectIndex = channel.Read <ushort>(); } } } else if (this.smbParametersBlock.WordCount == WordCountOfNtLanManager) { this.smbParameters = TypeMarshal.ToStruct <SMB_COM_NEGOTIATE_NtLanManagerResponse_SMB_Parameters>( CifsMessageUtils.ToBytes <SmbParameters>(this.smbParametersBlock)); } else if (this.smbParametersBlock.WordCount == WordCountOfLanManager) { throw new NotImplementedException("TD did not define the SmbParameters for Lan Manager Dialect."); } else { throw new NotSupportedException("Unknow SmbParameters structure."); } }
/// <summary> /// to decode the smb data: from the general SmbDada to the concrete Smb Data. /// </summary> protected override void DecodeData() { this.smbData = new SMB_COM_TRANSACTION2_Request_SMB_Data(); using (MemoryStream memoryStream = new MemoryStream(CifsMessageUtils.ToBytes <SmbData>(this.smbDataBlock))) { using (Channel channel = new Channel(null, memoryStream)) { this.smbData.ByteCount = channel.Read <ushort>(); if ((this.smbHeader.Flags2 & SmbFlags2.SMB_FLAGS2_UNICODE) == SmbFlags2.SMB_FLAGS2_UNICODE) { List <ushort> array = new List <ushort>(); ushort letter; do { letter = channel.Read <ushort>(); array.Add(letter); }while (letter != new ushort()); this.smbData.Name = CifsMessageUtils.ToBytesArray(array.ToArray()); } else { List <byte> array = new List <byte>(); byte letter; do { letter = channel.Read <byte>(); array.Add(letter); }while (letter != new byte()); this.smbData.Name = array.ToArray(); } this.smbData.Pad1 = channel.ReadBytes(this.smbParameters.ParameterOffset - this.HeaderSize - this.smbParameters.WordCount * 2 - SmbComTransactionPacket.SmbParametersWordCountLength - SmbComTransactionPacket.SmbDataByteCountLength - this.smbData.Name.Length); this.smbData.Trans2_Parameters = channel.ReadBytes(this.smbParameters.ParameterCount); if (this.smbParameters.DataOffset > 0) { this.smbData.Pad2 = channel.ReadBytes(this.smbParameters.DataOffset - this.smbParameters.ParameterOffset - this.smbParameters.ParameterCount); this.smbData.Trans2_Data = channel.ReadBytes(this.smbParameters.DataCount); } else { this.smbData.Pad2 = new byte[0]; this.smbData.Trans2_Data = new byte[0]; } } this.DecodeTrans2Parameters(); this.DecodeTrans2Data(); } }
/// <summary> /// to decode the smb parameters: from the general SmbParameters to the concrete Smb Parameters. /// </summary> protected override void DecodeParameters() { // When a client requests extended information, the word count must be 42 if (this.smbParametersBlock.WordCount == CREATE_EXTENDED_INFORMATION_RESPONSE_LENGTH) { SMB_COM_NT_CREATE_ANDX_Response_SMB_Parameters param = new SMB_COM_NT_CREATE_ANDX_Response_SMB_Parameters(); using (MemoryStream stream = new MemoryStream( CifsMessageUtils.ToBytesArray <ushort>(this.smbParametersBlock.Words))) { using (Channel channel = new Channel(null, stream)) { param.WordCount = this.smbParametersBlock.WordCount; param.AndXCommand = channel.Read <SmbCommand>(); param.AndXReserved = channel.Read <byte>(); param.AndXOffset = channel.Read <ushort>(); param.OplockLevel = channel.Read <OplockLevelValue>(); param.FID = channel.Read <ushort>(); param.CreationAction = channel.Read <uint>(); param.CreateTime = channel.Read <Cifs.FileTime>(); param.LastAccessTime = channel.Read <Cifs.FileTime>(); param.LastWriteTime = channel.Read <Cifs.FileTime>(); param.LastChangeTime = channel.Read <Cifs.FileTime>(); param.ExtFileAttributes = channel.Read <uint>(); param.AllocationSize = channel.Read <ulong>(); param.EndOfFile = channel.Read <ulong>(); param.ResourceType = channel.Read <FileTypeValue>(); param.NMPipeStatus_or_FileStatusFlags = channel.Read <SMB_NMPIPE_STATUS>(); param.Directory = channel.Read <byte>(); // VolumeGUID (16 bytes), td defines this length param.VolumeGUID = channel.ReadBytes(CifsMessageUtils.GetSize <Guid>(new Guid())); // if there is more 16 bytes in the channel. if (channel.Stream.Position <= channel.Stream.Length - WINDOWS_BEHAVIOR_ADDITIONAL_DATA_LENGTH) { // FileId (8 bytes), td defines this length param.FileId = channel.ReadBytes(sizeof(ulong)); // MaximalAccessRights (4 bytes), td defines this length param.MaximalAccessRights = channel.ReadBytes(sizeof(uint)); // GuestMaximalAccessRights (4 bytes), td defines this length param.GuestMaximalAccessRights = channel.ReadBytes(sizeof(uint)); } } } this.SmbParameters = param; } else { base.DecodeParameters(); this.smbParameters = SmbMessageUtils.ConvertSmbComCreatePacketPayload(base.SmbParameters); } }
/// <summary> /// to unmarshal the SmbParameters struct from a channel. /// </summary> /// <param name="channel">the channel started with SmbParameters.</param> /// <returns>the size in bytes of the SmbParameters.</returns> protected override int ReadParametersFromChannel(Channel channel) { this.smbParametersBlock = channel.Read <SmbParameters>(); if (channel.Stream.Position <= channel.Stream.Length - WINDOWS_BEHAVIOR_ADDITIONAL_DATA_LENGTH) { byte[] data = CifsMessageUtils.ToBytesArray <ushort>(this.smbParametersBlock.Words); this.smbParametersBlock.Words = CifsMessageUtils.ToTypeArray <ushort>( ArrayUtility.ConcatenateArrays <byte>( data, channel.ReadBytes(WINDOWS_BEHAVIOR_ADDITIONAL_DATA_LENGTH))); } this.DecodeParameters(); int sizeOfWordCount = sizeof(byte); int sizeOfWords = this.smbParametersBlock.WordCount * sizeof(ushort); return(sizeOfWordCount + sizeOfWords); }
/// <summary> /// to decode the smb data: from the general SmbDada to the concrete Smb Data. /// </summary> protected override void DecodeData() { this.smbData = new SMB_COM_TRANSACTION_Request_SMB_Data(); using (MemoryStream memoryStream = new MemoryStream(CifsMessageUtils.ToBytes <SmbData>(this.smbDataBlock))) { using (Channel channel = new Channel(null, memoryStream)) { this.smbData.ByteCount = channel.Read <ushort>(); bool isUnicode = (this.smbHeader.Flags2 & SmbFlags2.SMB_FLAGS2_UNICODE) == SmbFlags2.SMB_FLAGS2_UNICODE; if (isUnicode) { byte padLength = 1; channel.ReadBytes(padLength); List <ushort> array = new List <ushort>(); ushort letter; do { letter = channel.Read <ushort>(); array.Add(letter); }while (letter != new ushort()); this.smbData.Name = CifsMessageUtils.ToBytesArray(array.ToArray()); } else { List <byte> array = new List <byte>(); byte letter; do { letter = channel.Read <byte>(); array.Add(letter); }while (letter != new byte()); this.smbData.Name = array.ToArray(); } // the padding length of Pad1. int pad1Length = this.smbParameters.ParameterOffset - this.HeaderSize - this.smbParameters.WordCount * 2 - SmbComTransactionPacket.SmbParametersWordCountLength - SmbComTransactionPacket.SmbDataByteCountLength - this.smbData.Name.Length; // sub the padding bytes for Name. if (isUnicode) { pad1Length -= 1; } // read Pad1 from channel. if (pad1Length > 0) { this.smbData.Pad1 = channel.ReadBytes(pad1Length); } this.smbData.Trans_Parameters = channel.ReadBytes(this.smbParameters.ParameterCount); if (this.smbParameters.DataOffset > 0) { this.smbData.Pad2 = channel.ReadBytes(this.smbParameters.DataOffset - this.smbParameters.ParameterOffset - this.smbParameters.ParameterCount); this.smbData.Trans_Data = channel.ReadBytes(this.smbParameters.DataCount); } else { this.smbData.Pad2 = new byte[0]; this.smbData.Trans_Data = new byte[0]; } } } this.DecodeTransParameters(); this.DecodeTransData(); }
/// <summary> /// create the nt transaction packet /// </summary> /// <param name="request">the request packet</param> /// <param name="smbHeader">the smb header of response packet</param> /// <param name="channel">the channel contains the packet bytes</param> /// <returns>the response packet</returns> private SmbPacket CreateNtTransactionResponsePacket(SmbPacket request, SmbHeader smbHeader, Channel channel) { SmbPacket smbPacket = null; if (smbHeader.Status == 0 && channel.Peek <byte>(0) == 0 && channel.Peek <ushort>(1) == 0) { return(smbPacket); } SmbNtTransactRequestPacket ntTransactRequest = request as SmbNtTransactRequestPacket; if (ntTransactRequest == null) { return(smbPacket); } // find regular packet switch ((uint)ntTransactRequest.SmbParameters.Function) { case (uint)NtTransSubCommand.NT_TRANSACT_RENAME: smbPacket = new SmbNtTransRenameResponsePacket(); break; case (uint)NtTransSubCommand.NT_TRANSACT_CREATE: smbPacket = new SmbNtTransactCreateResponsePacket(); break; case (uint)NtTransSubCommand.NT_TRANSACT_IOCTL: NT_TRANSACT_IOCTL_SETUP setup = CifsMessageUtils.ToStuct <NT_TRANSACT_IOCTL_SETUP>( CifsMessageUtils.ToBytesArray <ushort>(ntTransactRequest.SmbParameters.Setup)); switch ((NtTransFunctionCode)setup.FunctionCode) { case NtTransFunctionCode.FSCTL_SRV_ENUMERATE_SNAPSHOTS: smbPacket = new SmbNtTransFsctlSrvEnumerateSnapshotsResponsePacket(); break; case NtTransFunctionCode.FSCTL_SRV_REQUEST_RESUME_KEY: smbPacket = new SmbNtTransFsctlSrvRequestResumeKeyResponsePacket(); break; case NtTransFunctionCode.FSCTL_SRV_COPYCHUNK: smbPacket = new SmbNtTransFsctlSrvCopyChunkResponsePacket(); break; default: smbPacket = new SmbNtTransactIoctlResponsePacket(); break; } break; case (uint)SmbNtTransSubCommand.NT_TRANSACT_QUERY_QUOTA: smbPacket = new SmbNtTransQueryQuotaResponsePacket(); break; case (uint)SmbNtTransSubCommand.NT_TRANSACT_SET_QUOTA: smbPacket = new SmbNtTransSetQuotaResponsePacket(); break; default: break; } return(smbPacket); }
/// <summary> /// find the target packet. /// </summary> /// <param name="smbHeader">the header of smb packet</param> /// <param name="channel">the channel to access bytes</param> /// <returns>the target packet</returns> private static SmbPacket FindTheTargetPacket(SmbHeader smbHeader, Channel channel) { SmbPacket smbPacket = null; switch (smbHeader.Command) { case SmbCommand.SMB_COM_NEGOTIATE: smbPacket = new SmbNegotiateRequestPacket(); break; case SmbCommand.SMB_COM_SESSION_SETUP_ANDX: SmbHeader_Flags2_Values flags2 = (SmbHeader_Flags2_Values)smbHeader.Flags2; if ((flags2 & SmbHeader_Flags2_Values.SMB_FLAGS2_EXTENDED_SECURITY) == SmbHeader_Flags2_Values.SMB_FLAGS2_EXTENDED_SECURITY) { smbPacket = new Smb.SmbSessionSetupAndxRequestPacket(); } else { smbPacket = new Cifs.SmbSessionSetupAndxRequestPacket(); } break; case SmbCommand.SMB_COM_TREE_CONNECT_ANDX: smbPacket = new SmbTreeConnectAndxRequestPacket(); break; case SmbCommand.SMB_COM_NT_CREATE_ANDX: smbPacket = new SmbNtCreateAndxRequestPacket(); break; case SmbCommand.SMB_COM_OPEN_ANDX: smbPacket = new SmbOpenAndxRequestPacket(); break; case SmbCommand.SMB_COM_WRITE_ANDX: smbPacket = new SmbWriteAndxRequestPacket(); break; case SmbCommand.SMB_COM_READ_ANDX: smbPacket = new SmbReadAndxRequestPacket(); break; case SmbCommand.SMB_COM_CLOSE: smbPacket = new SmbCloseRequestPacket(); break; case SmbCommand.SMB_COM_TREE_DISCONNECT: smbPacket = new SmbTreeDisconnectRequestPacket(); break; case SmbCommand.SMB_COM_LOGOFF_ANDX: smbPacket = new SmbLogoffAndxRequestPacket(); break; case SmbCommand.SMB_COM_TRANSACTION: SMB_COM_TRANSACTION_Request_SMB_Parameters transaction = channel.Read <SMB_COM_TRANSACTION_Request_SMB_Parameters>(); if (transaction.SetupCount == 0) { smbPacket = new SmbTransRapRequestPacket(); } else { smbPacket = FindTheTransactionPacket( transaction.SetupCount, (TransSubCommand)transaction.Setup[0]); } break; case SmbCommand.SMB_COM_TRANSACTION2: SMB_COM_TRANSACTION2_Request_SMB_Parameters transaction2 = channel.Read <SMB_COM_TRANSACTION2_Request_SMB_Parameters>(); smbPacket = FindTheTrans2Packet((Trans2SubCommand)transaction2.Subcommand); break; case SmbCommand.SMB_COM_NT_TRANSACT: SMB_COM_NT_TRANSACT_Request_SMB_Parameters ntTransactoin = channel.Read <SMB_COM_NT_TRANSACT_Request_SMB_Parameters>(); smbPacket = FindTheNtTransPacket(ntTransactoin.Function, CifsMessageUtils.ToBytesArray <ushort>(ntTransactoin.Setup)); break; default: break; } return(smbPacket); }