Browse Source

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

Tal Aloni 8 years ago
parent
commit
3f36591e14

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

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

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

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

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

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

+ 17 - 17
SMBLibrary/RPC/PDU/RPCPDU.cs

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

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

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

+ 3 - 3
SMBLibrary/RPC/PDU/ResponsePDU.cs

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

+ 1 - 1
SMBLibrary/Server/SMB1/ReadWriteResponseHelper.cs

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

+ 2 - 2
SMBLibrary/Server/SMB1/TransactionSubcommandHelper.cs

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