public NTStatus DeviceIOControl(object handle, uint ctlCode, byte[] input, out byte[] output, int maxOutputLength) { if ((IoControlCode)ctlCode == IoControlCode.FSCTL_PIPE_TRANSCEIVE) { return(FsCtlPipeTranscieve(handle, input, out output, maxOutputLength)); } output = null; NTTransactIOCTLRequest subcommand = new NTTransactIOCTLRequest(); subcommand.FID = (ushort)handle; subcommand.FunctionCode = ctlCode; subcommand.IsFsctl = true; subcommand.Data = input; NTTransactRequest request = new NTTransactRequest(); request.Function = subcommand.SubcommandName; request.Setup = subcommand.GetSetup(); request.TransParameters = subcommand.GetParameters(m_client.Unicode); request.TransData = subcommand.GetData(); request.TotalDataCount = (uint)request.TransData.Length; request.TotalParameterCount = (uint)request.TransParameters.Length; request.MaxParameterCount = NTTransactIOCTLResponse.ParametersLength; request.MaxDataCount = (uint)maxOutputLength; TrySendMessage(request); SMB1Message reply = m_client.WaitForMessage(CommandName.SMB_COM_NT_TRANSACT); if (reply != null) { if (reply.Header.Status == NTStatus.STATUS_SUCCESS && reply.Commands[0] is NTTransactResponse) { NTTransactResponse response = (NTTransactResponse)reply.Commands[0]; NTTransactIOCTLResponse subcommandResponse = new NTTransactIOCTLResponse(response.Setup, response.TransData); output = subcommandResponse.Data; } return(reply.Header.Status); } return(NTStatus.STATUS_INVALID_SMB); }
public void DeviceIOControl(NtHandle handle, uint ctlCode, byte[] input, out byte[]?output, int maxOutputLength) { if ((IoControlCode)ctlCode == IoControlCode.FSCTL_PIPE_TRANSCEIVE) { FsCtlPipeTranscieve(handle, input, out output, maxOutputLength); return; } NTTransactIOCTLRequest subcommand = new NTTransactIOCTLRequest { FID = ((Smb1Handle)handle).FID, FunctionCode = ctlCode, IsFsctl = true, Data = input }; NTTransactRequest request = new NTTransactRequest { Function = subcommand.SubcommandName, Setup = subcommand.GetSetup(), TransParameters = subcommand.GetParameters(m_client.Unicode), TransData = subcommand.GetData() }; request.TotalDataCount = (uint)request.TransData.Length; request.TotalParameterCount = (uint)request.TransParameters.Length; request.MaxParameterCount = NTTransactIOCTLResponse.ParametersLength; request.MaxDataCount = (uint)maxOutputLength; TrySendMessage(request); SMB1Message reply = m_client.WaitForMessage(CommandName.SMB_COM_NT_TRANSACT); if (reply.Header.Status != NTStatus.STATUS_SUCCESS || !(reply.Commands[0] is NTTransactResponse ntTransactResponse)) { throw new NtStatusException(reply.Header.Status); } NTTransactIOCTLResponse subcommandResponse = new NTTransactIOCTLResponse(ntTransactResponse.Setup, ntTransactResponse.TransData); output = subcommandResponse.Data; }
private static NTTransactIOCTLResponse GetSubcommandResponse(SMB1Header header, uint maxDataCount, NTTransactIOCTLRequest subcommand, ISMBShare share, SMB1ConnectionState state) { SMB1Session session = state.GetSession(header.UID); string ctlCode = Enum.IsDefined(typeof(IoControlCode), subcommand.FunctionCode) ? ((IoControlCode)subcommand.FunctionCode).ToString() : ("0x" + subcommand.FunctionCode.ToString("X8")); if (!subcommand.IsFsctl) { // [MS-SMB] If the IsFsctl field is set to zero, the server SHOULD fail the request with STATUS_NOT_SUPPORTED state.LogToServer(Severity.Verbose, "IOCTL: Non-FSCTL requests are not supported. CTL Code: {0}", ctlCode); header.Status = NTStatus.STATUS_NOT_SUPPORTED; return(null); } OpenFileObject openFile = session.GetOpenFileObject(subcommand.FID); if (openFile == null) { state.LogToServer(Severity.Verbose, "IOCTL failed. CTL Code: {0}. Invalid FID. (UID: {1}, TID: {2}, FID: {3})", ctlCode, header.UID, header.TID, subcommand.FID); header.Status = NTStatus.STATUS_INVALID_HANDLE; return(null); } int maxOutputLength = (int)maxDataCount; byte[] output; header.Status = share.FileStore.DeviceIOControl(openFile.Handle, subcommand.FunctionCode, subcommand.Data, out output, maxOutputLength); if (header.Status != NTStatus.STATUS_SUCCESS && header.Status != NTStatus.STATUS_BUFFER_OVERFLOW) { state.LogToServer(Severity.Verbose, "IOCTL failed. CTL Code: {0}. NTStatus: {1}. (FID: {2})", ctlCode, header.Status, subcommand.FID); return(null); } state.LogToServer(Severity.Verbose, "IOCTL succeeded. CTL Code: {0}. (FID: {1})", ctlCode, subcommand.FID); NTTransactIOCTLResponse response = new NTTransactIOCTLResponse(); response.Data = output; return(response); }
private static NTTransactIOCTLResponse GetSubcommandResponse(SMB1Header header, NTTransactIOCTLRequest subcommand, ISMBShare share, SMB1ConnectionState state) { SMB1Session session = state.GetSession(header.UID); NTTransactIOCTLResponse response = new NTTransactIOCTLResponse(); if (subcommand.IsFsctl) { OpenFileObject openFile = session.GetOpenFileObject(subcommand.FID); if (openFile == null) { header.Status = NTStatus.STATUS_INVALID_HANDLE; return(null); } int maxOutputLength = UInt16.MaxValue; byte[] output; header.Status = share.FileStore.DeviceIOControl(openFile.Handle, subcommand.FunctionCode, subcommand.Data, out output, maxOutputLength); if (header.Status != NTStatus.STATUS_SUCCESS) { return(null); } response.Data = output; return(response); } else { // [MS-SMB] If the IsFsctl field is set to zero, the server SHOULD fail the request with STATUS_NOT_SUPPORTED header.Status = NTStatus.STATUS_NOT_SUPPORTED; return(null); } }
private static NTTransactIOCTLResponse GetSubcommandResponse(SMBHeader header, NTTransactIOCTLRequest subcommand) { const uint FSCTL_CREATE_OR_GET_OBJECT_ID = 0x900C0; NTTransactIOCTLResponse response = new NTTransactIOCTLResponse(); if (subcommand.IsFsctl) { if (subcommand.FunctionCode == FSCTL_CREATE_OR_GET_OBJECT_ID) { ObjectIDBufferType1 objectID = new ObjectIDBufferType1(); objectID.ObjectId = Guid.NewGuid(); response.Data = objectID.GetBytes(); return(response); } } header.Status = NTStatus.STATUS_NOT_IMPLEMENTED; return(null); }