/// <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);
        }
예제 #6
0
        /// <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);
        }
예제 #8
0
        /// <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);
        }