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
* the GNU Lesser Public License as published by the Free Software Foundation,
@ -32,14 +32,15 @@ namespace SMBLibrary.RPC
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);
MaxReceiveFragmentSize = LittleEndianReader.ReadUInt16(buffer, ref offset);
AssociationGroupID = LittleEndianReader.ReadUInt32(buffer, ref offset);
SecondaryAddress = RPCHelper.ReadPortAddress(buffer, ref offset);
int padding = (4 - (offset % 4)) % 4;
int padding = (4 - ((offset - startOffset) % 4)) % 4;
offset += padding;
ResultList = new ResultList(buffer, offset);
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
* the GNU Lesser Public License as published by the Free Software Foundation,
@ -29,9 +29,9 @@ namespace SMBLibrary.RPC
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);
MaxReceiveFragmentSize = LittleEndianReader.ReadUInt16(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
* the GNU Lesser Public License as published by the Free Software Foundation,
@ -31,9 +31,9 @@ namespace SMBLibrary.RPC
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);
ContextID = LittleEndianReader.ReadUInt16(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
* the GNU Lesser Public License as published by the Free Software Foundation,
@ -24,7 +24,7 @@ namespace SMBLibrary.RPC
public PacketTypeName PacketType;
public PacketFlags Flags;
public DataRepresentationFormat DataRepresentation;
public ushort FragmentLength;
public ushort FragmentLength; // The length of the entire PDU
public ushort AuthLength;
public uint CallID;
@ -34,16 +34,16 @@ namespace SMBLibrary.RPC
VersionMinor = 0;
}
public RPCPDU(byte[] buffer)
public RPCPDU(byte[] buffer, int offset)
{
VersionMajor = ByteReader.ReadByte(buffer, 0);
VersionMinor = ByteReader.ReadByte(buffer, 1);
PacketType = (PacketTypeName)ByteReader.ReadByte(buffer, 2);
Flags = (PacketFlags)ByteReader.ReadByte(buffer, 3);
DataRepresentation = new DataRepresentationFormat(buffer, 4);
FragmentLength = LittleEndianConverter.ToUInt16(buffer, 8);
AuthLength = LittleEndianConverter.ToUInt16(buffer, 10);
CallID = LittleEndianConverter.ToUInt32(buffer, 12);
VersionMajor = ByteReader.ReadByte(buffer, offset + 0);
VersionMinor = ByteReader.ReadByte(buffer, offset + 1);
PacketType = (PacketTypeName)ByteReader.ReadByte(buffer, offset + 2);
Flags = (PacketFlags)ByteReader.ReadByte(buffer, offset + 3);
DataRepresentation = new DataRepresentationFormat(buffer, offset + 4);
FragmentLength = LittleEndianConverter.ToUInt16(buffer, offset + 8);
AuthLength = LittleEndianConverter.ToUInt16(buffer, offset + 10);
CallID = LittleEndianConverter.ToUInt32(buffer, offset + 12);
}
public abstract byte[] GetBytes();
@ -60,21 +60,21 @@ namespace SMBLibrary.RPC
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);
switch (packetType)
{
case PacketTypeName.Request:
return new RequestPDU(buffer);
return new RequestPDU(buffer, offset);
case PacketTypeName.Response:
return new ResponsePDU(buffer);
return new ResponsePDU(buffer, offset);
case PacketTypeName.Fault:
return new FaultPDU(buffer);
return new FaultPDU(buffer, offset);
case PacketTypeName.Bind:
return new BindPDU(buffer);
return new BindPDU(buffer, offset);
case PacketTypeName.BindAck:
return new BindAckPDU(buffer);
return new BindAckPDU(buffer, offset);
default:
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
* the GNU Lesser Public License as published by the Free Software Foundation,
@ -29,9 +29,9 @@ namespace SMBLibrary.RPC
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);
ContextID = 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
* the GNU Lesser Public License as published by the Free Software Foundation,
@ -29,9 +29,9 @@ namespace SMBLibrary.RPC
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);
ContextID = LittleEndianReader.ReadUInt16(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);
if (service != null)
{
RPCPDU rpcRequest = RPCPDU.GetPDU(data);
RPCPDU rpcRequest = RPCPDU.GetPDU(data, 0);
RPCPDU rpcReply = RemoteServiceHelper.GetRPCReply(rpcRequest, service);
byte[] replyData = rpcReply.GetBytes();
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
* 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);
if (service != null)
{
RPCPDU rpcRequest = RPCPDU.GetPDU(subcommand.WriteData);
RPCPDU rpcRequest = RPCPDU.GetPDU(subcommand.WriteData, 0);
RPCPDU rpcReply = RemoteServiceHelper.GetRPCReply(rpcRequest, service);
response.ReadData = rpcReply.GetBytes();
return response;