Improved implementation of RPC PDUs

This commit is contained in:
Tal Aloni 2017-07-11 22:02:21 +03:00
parent d2a8c251be
commit ed00ad4067
6 changed files with 27 additions and 17 deletions

View file

@ -16,6 +16,8 @@ namespace SMBLibrary.RPC
/// </summary>
public class BindAckPDU : RPCPDU
{
public const int BindAckFieldsFixedLength = 8;
public ushort MaxTransmitFragmentSize; // max_xmit_frag
public ushort MaxReceiveFragmentSize; // max_recv_frag
public uint AssociationGroupID; // assoc_group_id
@ -35,7 +37,7 @@ namespace SMBLibrary.RPC
public BindAckPDU(byte[] buffer, int offset) : base(buffer, offset)
{
int startOffset = offset;
offset += RPCPDU.CommonFieldsLength;
offset += CommonFieldsLength;
MaxTransmitFragmentSize = LittleEndianReader.ReadUInt16(buffer, ref offset);
MaxReceiveFragmentSize = LittleEndianReader.ReadUInt16(buffer, ref offset);
AssociationGroupID = LittleEndianReader.ReadUInt32(buffer, ref offset);
@ -51,10 +53,10 @@ namespace SMBLibrary.RPC
{
AuthLength = (ushort)AuthVerifier.Length;
int padding = (4 - ((SecondaryAddress.Length + 3) % 4)) % 4;
FragmentLength = (ushort)(RPCPDU.CommonFieldsLength + 8 + SecondaryAddress.Length + 3 + padding + ResultList.Length + AuthLength);
FragmentLength = (ushort)(CommonFieldsLength + BindAckFieldsFixedLength + SecondaryAddress.Length + 3 + padding + ResultList.Length + AuthLength);
byte[] buffer = new byte[FragmentLength];
WriteCommonFieldsBytes(buffer);
int offset = RPCPDU.CommonFieldsLength;
int offset = CommonFieldsLength;
LittleEndianWriter.WriteUInt16(buffer, ref offset, MaxTransmitFragmentSize);
LittleEndianWriter.WriteUInt16(buffer, ref offset, MaxReceiveFragmentSize);
LittleEndianWriter.WriteUInt32(buffer, ref offset, AssociationGroupID);

View file

@ -16,6 +16,8 @@ namespace SMBLibrary.RPC
/// </summary>
public class BindPDU : RPCPDU
{
public const int BindFieldsFixedLength = 8;
public ushort MaxTransmitFragmentSize; // max_xmit_frag
public ushort MaxReceiveFragmentSize; // max_recv_frag
public uint AssociationGroupID; // assoc_group_id
@ -31,7 +33,7 @@ namespace SMBLibrary.RPC
public BindPDU(byte[] buffer, int offset) : base(buffer, offset)
{
offset += RPCPDU.CommonFieldsLength;
offset += CommonFieldsLength;
MaxTransmitFragmentSize = LittleEndianReader.ReadUInt16(buffer, ref offset);
MaxReceiveFragmentSize = LittleEndianReader.ReadUInt16(buffer, ref offset);
AssociationGroupID = LittleEndianReader.ReadUInt32(buffer, ref offset);
@ -43,10 +45,10 @@ namespace SMBLibrary.RPC
public override byte[] GetBytes()
{
AuthLength =(ushort)AuthVerifier.Length;
FragmentLength = (ushort)(RPCPDU.CommonFieldsLength + 8 + ContextList.Length + AuthLength);
FragmentLength = (ushort)(CommonFieldsLength + BindFieldsFixedLength + ContextList.Length + AuthLength);
byte[] buffer = new byte[FragmentLength];
WriteCommonFieldsBytes(buffer);
int offset = RPCPDU.CommonFieldsLength;
int offset = CommonFieldsLength;
LittleEndianWriter.WriteUInt16(buffer, ref offset, MaxTransmitFragmentSize);
LittleEndianWriter.WriteUInt16(buffer, ref offset, MaxReceiveFragmentSize);
LittleEndianWriter.WriteUInt32(buffer, ref offset, AssociationGroupID);

View file

@ -16,6 +16,8 @@ namespace SMBLibrary.RPC
/// </summary>
public class FaultPDU : RPCPDU
{
public const int FaultFieldsLength = 16;
public uint AllocationHint;
public ushort ContextID;
public byte CancelCount;
@ -33,7 +35,7 @@ namespace SMBLibrary.RPC
public FaultPDU(byte[] buffer, int offset) : base(buffer, offset)
{
offset += RPCPDU.CommonFieldsLength;
offset += CommonFieldsLength;
AllocationHint = LittleEndianReader.ReadUInt32(buffer, ref offset);
ContextID = LittleEndianReader.ReadUInt16(buffer, ref offset);
CancelCount = ByteReader.ReadByte(buffer, ref offset);
@ -48,10 +50,10 @@ namespace SMBLibrary.RPC
public override byte[] GetBytes()
{
AuthLength = (ushort)AuthVerifier.Length;
FragmentLength = (ushort)(RPCPDU.CommonFieldsLength + 16 + Data.Length + AuthVerifier.Length);
FragmentLength = (ushort)(CommonFieldsLength + FaultFieldsLength + Data.Length + AuthVerifier.Length);
byte[] buffer = new byte[FragmentLength];
WriteCommonFieldsBytes(buffer);
int offset = RPCPDU.CommonFieldsLength;
int offset = CommonFieldsLength;
LittleEndianWriter.WriteUInt32(buffer, ref offset, AllocationHint);
LittleEndianWriter.WriteUInt16(buffer, ref offset, ContextID);
ByteWriter.WriteByte(buffer, ref offset, CancelCount);

View file

@ -16,6 +16,8 @@ namespace SMBLibrary.RPC
/// </summary>
public class RequestPDU : RPCPDU
{
public const int RequestFieldsFixedLength = 8;
public uint AllocationHint; // alloc_hint
public ushort ContextID;
public ushort OpNum;
@ -31,7 +33,7 @@ namespace SMBLibrary.RPC
public RequestPDU(byte[] buffer, int offset) : base(buffer, offset)
{
offset += RPCPDU.CommonFieldsLength;
offset += CommonFieldsLength;
AllocationHint = LittleEndianReader.ReadUInt32(buffer, ref offset);
ContextID = LittleEndianReader.ReadUInt16(buffer, ref offset);
OpNum = LittleEndianReader.ReadUInt16(buffer, ref offset);
@ -47,14 +49,14 @@ namespace SMBLibrary.RPC
public override byte[] GetBytes()
{
AuthLength = (ushort)AuthVerifier.Length;
FragmentLength = (ushort)(RPCPDU.CommonFieldsLength + 8 + Data.Length + AuthVerifier.Length);
FragmentLength = (ushort)(CommonFieldsLength + RequestFieldsFixedLength + Data.Length + AuthVerifier.Length);
if ((Flags & PacketFlags.ObjectUUID) > 0)
{
FragmentLength += 16;
}
byte[] buffer = new byte[FragmentLength];
WriteCommonFieldsBytes(buffer);
int offset = RPCPDU.CommonFieldsLength;
int offset = CommonFieldsLength;
LittleEndianWriter.WriteUInt32(buffer, ref offset, AllocationHint);
LittleEndianWriter.WriteUInt16(buffer, ref offset, ContextID);
LittleEndianWriter.WriteUInt16(buffer, ref offset, OpNum);

View file

@ -16,7 +16,9 @@ namespace SMBLibrary.RPC
/// </summary>
public class ResponsePDU : RPCPDU
{
private uint AllocationHint;
public const int ResponseFieldsLength = 8;
public uint AllocationHint;
public ushort ContextID;
public byte CancelCount;
public byte Reserved;
@ -31,7 +33,7 @@ namespace SMBLibrary.RPC
public ResponsePDU(byte[] buffer, int offset) : base(buffer, offset)
{
offset += RPCPDU.CommonFieldsLength;
offset += CommonFieldsLength;
AllocationHint = LittleEndianReader.ReadUInt32(buffer, ref offset);
ContextID = LittleEndianReader.ReadUInt16(buffer, ref offset);
CancelCount = ByteReader.ReadByte(buffer, ref offset);
@ -44,12 +46,11 @@ namespace SMBLibrary.RPC
public override byte[] GetBytes()
{
AuthLength = (ushort)AuthVerifier.Length;
FragmentLength = (ushort)(RPCPDU.CommonFieldsLength + 8 + Data.Length + AuthVerifier.Length);
AllocationHint = (ushort)Data.Length;
FragmentLength = (ushort)(CommonFieldsLength + ResponseFieldsLength + Data.Length + AuthVerifier.Length);
byte[] buffer = new byte[FragmentLength];
WriteCommonFieldsBytes(buffer);
int offset = RPCPDU.CommonFieldsLength;
int offset = CommonFieldsLength;
LittleEndianWriter.WriteUInt32(buffer, ref offset, AllocationHint);
LittleEndianWriter.WriteUInt16(buffer, ref offset, ContextID);
ByteWriter.WriteByte(buffer, ref offset, CancelCount);

View file

@ -122,6 +122,7 @@ namespace SMBLibrary.Services
ResponsePDU responsePDU = new ResponsePDU();
PrepareReply(responsePDU, requestPDU);
responsePDU.Data = service.GetResponseBytes(requestPDU.OpNum, requestPDU.Data);
responsePDU.AllocationHint = (uint)responsePDU.Data.Length;
return responsePDU;
}