Browse Source

Improved implementation of RPC PDUs

Tal Aloni 7 years ago
parent
commit
ed00ad4067

+ 5 - 3
SMBLibrary/RPC/PDU/BindAckPDU.cs

@@ -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);

+ 5 - 3
SMBLibrary/RPC/PDU/BindPDU.cs

@@ -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);

+ 5 - 3
SMBLibrary/RPC/PDU/FaultPDU.cs

@@ -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);

+ 5 - 3
SMBLibrary/RPC/PDU/RequestPDU.cs

@@ -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);

+ 6 - 5
SMBLibrary/RPC/PDU/ResponsePDU.cs

@@ -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);

+ 1 - 0
SMBLibrary/Services/RemoteServiceHelper.cs

@@ -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;
         }