RPC PDUs can now be read starting from a specified buffer offset

This commit is contained in:
Tal Aloni 2017-01-14 00:22:38 +02:00
parent f809d337c8
commit 3f36591e14
8 changed files with 37 additions and 36 deletions

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2014 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved. /* Copyright (C) 2014-2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
* *
* You can redistribute this program and/or modify it under the terms of * You can redistribute this program and/or modify it under the terms of
* the GNU Lesser Public License as published by the Free Software Foundation, * the GNU Lesser Public License as published by the Free Software Foundation,
@ -32,14 +32,15 @@ namespace SMBLibrary.RPC
AuthVerifier = new byte[0]; AuthVerifier = new byte[0];
} }
public BindAckPDU(byte[] buffer) : base(buffer) public BindAckPDU(byte[] buffer, int offset) : base(buffer, offset)
{ {
int offset = RPCPDU.CommonFieldsLength; int startOffset = offset;
offset += RPCPDU.CommonFieldsLength;
MaxTransmitFragmentSize = LittleEndianReader.ReadUInt16(buffer, ref offset); MaxTransmitFragmentSize = LittleEndianReader.ReadUInt16(buffer, ref offset);
MaxReceiveFragmentSize = LittleEndianReader.ReadUInt16(buffer, ref offset); MaxReceiveFragmentSize = LittleEndianReader.ReadUInt16(buffer, ref offset);
AssociationGroupID = LittleEndianReader.ReadUInt32(buffer, ref offset); AssociationGroupID = LittleEndianReader.ReadUInt32(buffer, ref offset);
SecondaryAddress = RPCHelper.ReadPortAddress(buffer, ref offset); SecondaryAddress = RPCHelper.ReadPortAddress(buffer, ref offset);
int padding = (4 - (offset % 4)) % 4; int padding = (4 - ((offset - startOffset) % 4)) % 4;
offset += padding; offset += padding;
ResultList = new ResultList(buffer, offset); ResultList = new ResultList(buffer, offset);
offset += ResultList.Length; offset += ResultList.Length;

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2014 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved. /* Copyright (C) 2014-2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
* *
* You can redistribute this program and/or modify it under the terms of * You can redistribute this program and/or modify it under the terms of
* the GNU Lesser Public License as published by the Free Software Foundation, * the GNU Lesser Public License as published by the Free Software Foundation,
@ -29,9 +29,9 @@ namespace SMBLibrary.RPC
AuthVerifier = new byte[0]; AuthVerifier = new byte[0];
} }
public BindPDU(byte[] buffer) : base(buffer) public BindPDU(byte[] buffer, int offset) : base(buffer, offset)
{ {
int offset = RPCPDU.CommonFieldsLength; offset += RPCPDU.CommonFieldsLength;
MaxTransmitFragmentSize = LittleEndianReader.ReadUInt16(buffer, ref offset); MaxTransmitFragmentSize = LittleEndianReader.ReadUInt16(buffer, ref offset);
MaxReceiveFragmentSize = LittleEndianReader.ReadUInt16(buffer, ref offset); MaxReceiveFragmentSize = LittleEndianReader.ReadUInt16(buffer, ref offset);
AssociationGroupID = LittleEndianReader.ReadUInt32(buffer, ref offset); AssociationGroupID = LittleEndianReader.ReadUInt32(buffer, ref offset);

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2014 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved. /* Copyright (C) 2014-2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
* *
* You can redistribute this program and/or modify it under the terms of * You can redistribute this program and/or modify it under the terms of
* the GNU Lesser Public License as published by the Free Software Foundation, * the GNU Lesser Public License as published by the Free Software Foundation,
@ -31,9 +31,9 @@ namespace SMBLibrary.RPC
AuthVerifier = new byte[0]; AuthVerifier = new byte[0];
} }
public FaultPDU(byte[] buffer) : base(buffer) public FaultPDU(byte[] buffer, int offset) : base(buffer, offset)
{ {
int offset = RPCPDU.CommonFieldsLength; offset += RPCPDU.CommonFieldsLength;
AllocationHint = LittleEndianReader.ReadUInt32(buffer, ref offset); AllocationHint = LittleEndianReader.ReadUInt32(buffer, ref offset);
ContextID = LittleEndianReader.ReadUInt16(buffer, ref offset); ContextID = LittleEndianReader.ReadUInt16(buffer, ref offset);
CancelCount = ByteReader.ReadByte(buffer, ref offset); CancelCount = ByteReader.ReadByte(buffer, ref offset);

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2014 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved. /* Copyright (C) 2014-2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
* *
* You can redistribute this program and/or modify it under the terms of * You can redistribute this program and/or modify it under the terms of
* the GNU Lesser Public License as published by the Free Software Foundation, * the GNU Lesser Public License as published by the Free Software Foundation,
@ -24,7 +24,7 @@ namespace SMBLibrary.RPC
public PacketTypeName PacketType; public PacketTypeName PacketType;
public PacketFlags Flags; public PacketFlags Flags;
public DataRepresentationFormat DataRepresentation; public DataRepresentationFormat DataRepresentation;
public ushort FragmentLength; public ushort FragmentLength; // The length of the entire PDU
public ushort AuthLength; public ushort AuthLength;
public uint CallID; public uint CallID;
@ -34,16 +34,16 @@ namespace SMBLibrary.RPC
VersionMinor = 0; VersionMinor = 0;
} }
public RPCPDU(byte[] buffer) public RPCPDU(byte[] buffer, int offset)
{ {
VersionMajor = ByteReader.ReadByte(buffer, 0); VersionMajor = ByteReader.ReadByte(buffer, offset + 0);
VersionMinor = ByteReader.ReadByte(buffer, 1); VersionMinor = ByteReader.ReadByte(buffer, offset + 1);
PacketType = (PacketTypeName)ByteReader.ReadByte(buffer, 2); PacketType = (PacketTypeName)ByteReader.ReadByte(buffer, offset + 2);
Flags = (PacketFlags)ByteReader.ReadByte(buffer, 3); Flags = (PacketFlags)ByteReader.ReadByte(buffer, offset + 3);
DataRepresentation = new DataRepresentationFormat(buffer, 4); DataRepresentation = new DataRepresentationFormat(buffer, offset + 4);
FragmentLength = LittleEndianConverter.ToUInt16(buffer, 8); FragmentLength = LittleEndianConverter.ToUInt16(buffer, offset + 8);
AuthLength = LittleEndianConverter.ToUInt16(buffer, 10); AuthLength = LittleEndianConverter.ToUInt16(buffer, offset + 10);
CallID = LittleEndianConverter.ToUInt32(buffer, 12); CallID = LittleEndianConverter.ToUInt32(buffer, offset + 12);
} }
public abstract byte[] GetBytes(); public abstract byte[] GetBytes();
@ -60,21 +60,21 @@ namespace SMBLibrary.RPC
LittleEndianWriter.WriteUInt32(buffer, 12, CallID); LittleEndianWriter.WriteUInt32(buffer, 12, CallID);
} }
public static RPCPDU GetPDU(byte[] buffer) public static RPCPDU GetPDU(byte[] buffer, int offset)
{ {
PacketTypeName packetType = (PacketTypeName)ByteReader.ReadByte(buffer, 2); PacketTypeName packetType = (PacketTypeName)ByteReader.ReadByte(buffer, 2);
switch (packetType) switch (packetType)
{ {
case PacketTypeName.Request: case PacketTypeName.Request:
return new RequestPDU(buffer); return new RequestPDU(buffer, offset);
case PacketTypeName.Response: case PacketTypeName.Response:
return new ResponsePDU(buffer); return new ResponsePDU(buffer, offset);
case PacketTypeName.Fault: case PacketTypeName.Fault:
return new FaultPDU(buffer); return new FaultPDU(buffer, offset);
case PacketTypeName.Bind: case PacketTypeName.Bind:
return new BindPDU(buffer); return new BindPDU(buffer, offset);
case PacketTypeName.BindAck: case PacketTypeName.BindAck:
return new BindAckPDU(buffer); return new BindAckPDU(buffer, offset);
default: default:
throw new NotImplementedException(); throw new NotImplementedException();
} }

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2014 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved. /* Copyright (C) 2014-2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
* *
* You can redistribute this program and/or modify it under the terms of * You can redistribute this program and/or modify it under the terms of
* the GNU Lesser Public License as published by the Free Software Foundation, * the GNU Lesser Public License as published by the Free Software Foundation,
@ -29,9 +29,9 @@ namespace SMBLibrary.RPC
AuthVerifier = new byte[0]; AuthVerifier = new byte[0];
} }
public RequestPDU(byte[] buffer) : base(buffer) public RequestPDU(byte[] buffer, int offset) : base(buffer, offset)
{ {
int offset = RPCPDU.CommonFieldsLength; offset += RPCPDU.CommonFieldsLength;
AllocationHint = LittleEndianReader.ReadUInt32(buffer, ref offset); AllocationHint = LittleEndianReader.ReadUInt32(buffer, ref offset);
ContextID = LittleEndianReader.ReadUInt16(buffer, ref offset); ContextID = LittleEndianReader.ReadUInt16(buffer, ref offset);
OpNum = LittleEndianReader.ReadUInt16(buffer, ref offset); OpNum = LittleEndianReader.ReadUInt16(buffer, ref offset);

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2014 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved. /* Copyright (C) 2014-2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
* *
* You can redistribute this program and/or modify it under the terms of * You can redistribute this program and/or modify it under the terms of
* the GNU Lesser Public License as published by the Free Software Foundation, * the GNU Lesser Public License as published by the Free Software Foundation,
@ -29,9 +29,9 @@ namespace SMBLibrary.RPC
AuthVerifier = new byte[0]; AuthVerifier = new byte[0];
} }
public ResponsePDU(byte[] buffer) : base(buffer) public ResponsePDU(byte[] buffer, int offset) : base(buffer, offset)
{ {
int offset = RPCPDU.CommonFieldsLength; offset += RPCPDU.CommonFieldsLength;
AllocationHint = LittleEndianReader.ReadUInt32(buffer, ref offset); AllocationHint = LittleEndianReader.ReadUInt32(buffer, ref offset);
ContextID = LittleEndianReader.ReadUInt16(buffer, ref offset); ContextID = LittleEndianReader.ReadUInt16(buffer, ref offset);
CancelCount = ByteReader.ReadByte(buffer, ref offset); CancelCount = ByteReader.ReadByte(buffer, ref offset);

View file

@ -182,7 +182,7 @@ namespace SMBLibrary.Server.SMB1
RemoteService service = ((NamedPipeShare)share).GetService(openedFilePath); RemoteService service = ((NamedPipeShare)share).GetService(openedFilePath);
if (service != null) if (service != null)
{ {
RPCPDU rpcRequest = RPCPDU.GetPDU(data); RPCPDU rpcRequest = RPCPDU.GetPDU(data, 0);
RPCPDU rpcReply = RemoteServiceHelper.GetRPCReply(rpcRequest, service); RPCPDU rpcReply = RemoteServiceHelper.GetRPCReply(rpcRequest, service);
byte[] replyData = rpcReply.GetBytes(); byte[] replyData = rpcReply.GetBytes();
state.StoreNamedPipeReply(FID, replyData); state.StoreNamedPipeReply(FID, replyData);

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2014 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved. /* Copyright (C) 2014-2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
* *
* You can redistribute this program and/or modify it under the terms of * You can redistribute this program and/or modify it under the terms of
* the GNU Lesser Public License as published by the Free Software Foundation, * the GNU Lesser Public License as published by the Free Software Foundation,
@ -29,7 +29,7 @@ namespace SMBLibrary.Server.SMB1
RemoteService service = share.GetService(openedFilePath); RemoteService service = share.GetService(openedFilePath);
if (service != null) if (service != null)
{ {
RPCPDU rpcRequest = RPCPDU.GetPDU(subcommand.WriteData); RPCPDU rpcRequest = RPCPDU.GetPDU(subcommand.WriteData, 0);
RPCPDU rpcReply = RemoteServiceHelper.GetRPCReply(rpcRequest, service); RPCPDU rpcReply = RemoteServiceHelper.GetRPCReply(rpcRequest, service);
response.ReadData = rpcReply.GetBytes(); response.ReadData = rpcReply.GetBytes();
return response; return response;