From 6a1c68faf70ea4389942ec46fb0b08d6379ccbae Mon Sep 17 00:00:00 2001 From: Tal Aloni Date: Sat, 16 Sep 2017 00:00:28 +0300 Subject: [PATCH] SMB1: Improved FindInformation implementation and corrected reading of FindInformation entries from buffer --- .../FindFileBothDirectoryInfo.cs | 6 ++-- .../FindInformation/FindFileDirectoryInfo.cs | 6 ++-- .../FindFileFullDirectoryInfo.cs | 6 ++-- .../FindFileIDBothDirectoryInfo.cs | 6 ++-- .../FindFileIDFullDirectoryInfo.cs | 6 ++-- .../FindInformation/FindFileNamesInfo.cs | 6 ++-- .../FindInformation/FindInformation.cs | 27 +++++++---------- .../FindInformation/FindInformationList.cs | 30 +++++-------------- 8 files changed, 36 insertions(+), 57 deletions(-) diff --git a/SMBLibrary/SMB1FileStore/Structures/FindInformation/FindFileBothDirectoryInfo.cs b/SMBLibrary/SMB1FileStore/Structures/FindInformation/FindFileBothDirectoryInfo.cs index 9cce17b..006db33 100644 --- a/SMBLibrary/SMB1FileStore/Structures/FindInformation/FindFileBothDirectoryInfo.cs +++ b/SMBLibrary/SMB1FileStore/Structures/FindInformation/FindFileBothDirectoryInfo.cs @@ -18,7 +18,7 @@ namespace SMBLibrary.SMB1 { public const int FixedLength = 94; - public uint NextEntryOffset; + // uint NextEntryOffset; public uint FileIndex; // SHOULD be set to zero when sent in a response and SHOULD be ignored when received by the client public DateTime? CreationTime; public DateTime? LastAccessTime; @@ -38,11 +38,11 @@ namespace SMBLibrary.SMB1 // Will, in some rare but repeatable cases, cause issues with Windows XP SP3 as a client // (the client will display an error message that the folder "refers to a location that is unavailable"...) - public FindFileBothDirectoryInfo() : base(false) + public FindFileBothDirectoryInfo() : base() { } - public FindFileBothDirectoryInfo(byte[] buffer, ref int offset, bool isUnicode) : base(false) + public FindFileBothDirectoryInfo(byte[] buffer, int offset, bool isUnicode) : base() { NextEntryOffset = LittleEndianReader.ReadUInt32(buffer, ref offset); FileIndex = LittleEndianReader.ReadUInt32(buffer, ref offset); diff --git a/SMBLibrary/SMB1FileStore/Structures/FindInformation/FindFileDirectoryInfo.cs b/SMBLibrary/SMB1FileStore/Structures/FindInformation/FindFileDirectoryInfo.cs index 6038092..1ce5d54 100644 --- a/SMBLibrary/SMB1FileStore/Structures/FindInformation/FindFileDirectoryInfo.cs +++ b/SMBLibrary/SMB1FileStore/Structures/FindInformation/FindFileDirectoryInfo.cs @@ -18,7 +18,7 @@ namespace SMBLibrary.SMB1 { public const int FixedLength = 64; - public uint NextEntryOffset; + // uint NextEntryOffset; public uint FileIndex; // SHOULD be set to zero when sent in a response and SHOULD be ignored when received by the client public DateTime? CreationTime; public DateTime? LastAccessTime; @@ -30,11 +30,11 @@ namespace SMBLibrary.SMB1 //uint FileNameLength; // In bytes, MUST exclude the null termination. public string FileName; // OEM / Unicode character array. MUST be written as SMB_STRING, and read as fixed length string. - public FindFileDirectoryInfo() : base(false) + public FindFileDirectoryInfo() : base() { } - public FindFileDirectoryInfo(byte[] buffer, ref int offset, bool isUnicode) : base(false) + public FindFileDirectoryInfo(byte[] buffer, int offset, bool isUnicode) : base() { NextEntryOffset = LittleEndianReader.ReadUInt32(buffer, ref offset); FileIndex = LittleEndianReader.ReadUInt32(buffer, ref offset); diff --git a/SMBLibrary/SMB1FileStore/Structures/FindInformation/FindFileFullDirectoryInfo.cs b/SMBLibrary/SMB1FileStore/Structures/FindInformation/FindFileFullDirectoryInfo.cs index 6105925..ea72406 100644 --- a/SMBLibrary/SMB1FileStore/Structures/FindInformation/FindFileFullDirectoryInfo.cs +++ b/SMBLibrary/SMB1FileStore/Structures/FindInformation/FindFileFullDirectoryInfo.cs @@ -18,7 +18,7 @@ namespace SMBLibrary.SMB1 { public const int FixedLength = 68; - public uint NextEntryOffset; + // uint NextEntryOffset; public uint FileIndex; // SHOULD be set to zero when sent in a response and SHOULD be ignored when received by the client public DateTime? CreationTime; public DateTime? LastAccessTime; @@ -31,11 +31,11 @@ namespace SMBLibrary.SMB1 public uint EASize; public string FileName; // OEM / Unicode character array. MUST be written as SMB_STRING, and read as fixed length string. - public FindFileFullDirectoryInfo() : base(false) + public FindFileFullDirectoryInfo() : base() { } - public FindFileFullDirectoryInfo(byte[] buffer, ref int offset, bool isUnicode) : base(false) + public FindFileFullDirectoryInfo(byte[] buffer, int offset, bool isUnicode) : base() { NextEntryOffset = LittleEndianReader.ReadUInt32(buffer, ref offset); FileIndex = LittleEndianReader.ReadUInt32(buffer, ref offset); diff --git a/SMBLibrary/SMB1FileStore/Structures/FindInformation/FindFileIDBothDirectoryInfo.cs b/SMBLibrary/SMB1FileStore/Structures/FindInformation/FindFileIDBothDirectoryInfo.cs index 717de41..8a1f45d 100644 --- a/SMBLibrary/SMB1FileStore/Structures/FindInformation/FindFileIDBothDirectoryInfo.cs +++ b/SMBLibrary/SMB1FileStore/Structures/FindInformation/FindFileIDBothDirectoryInfo.cs @@ -18,7 +18,7 @@ namespace SMBLibrary.SMB1 { public const int FixedLength = 104; - public uint NextEntryOffset; + // uint NextEntryOffset; public uint FileIndex; // SHOULD be set to zero when sent in a response and SHOULD be ignored when received by the client public DateTime? CreationTime; public DateTime? LastAccessTime; @@ -40,11 +40,11 @@ namespace SMBLibrary.SMB1 // Will, in some rare but repeatable cases, cause issues with Windows XP SP3 as a client // (the client will display an error message that the folder "refers to a location that is unavailable"...) - public FindFileIDBothDirectoryInfo() : base(false) + public FindFileIDBothDirectoryInfo() : base() { } - public FindFileIDBothDirectoryInfo(byte[] buffer, ref int offset, bool isUnicode) : base(false) + public FindFileIDBothDirectoryInfo(byte[] buffer, int offset, bool isUnicode) : base() { NextEntryOffset = LittleEndianReader.ReadUInt32(buffer, ref offset); FileIndex = LittleEndianReader.ReadUInt32(buffer, ref offset); diff --git a/SMBLibrary/SMB1FileStore/Structures/FindInformation/FindFileIDFullDirectoryInfo.cs b/SMBLibrary/SMB1FileStore/Structures/FindInformation/FindFileIDFullDirectoryInfo.cs index 627bea7..100fe2c 100644 --- a/SMBLibrary/SMB1FileStore/Structures/FindInformation/FindFileIDFullDirectoryInfo.cs +++ b/SMBLibrary/SMB1FileStore/Structures/FindInformation/FindFileIDFullDirectoryInfo.cs @@ -18,7 +18,7 @@ namespace SMBLibrary.SMB1 { public const int FixedLength = 80; - public uint NextEntryOffset; + // uint NextEntryOffset; public uint FileIndex; // SHOULD be set to zero when sent in a response and SHOULD be ignored when received by the client public DateTime? CreationTime; public DateTime? LastAccessTime; @@ -33,11 +33,11 @@ namespace SMBLibrary.SMB1 public ulong FileID; public string FileName; // OEM / Unicode character array. MUST be written as SMB_STRING, and read as fixed length string. - public FindFileIDFullDirectoryInfo() : base(false) + public FindFileIDFullDirectoryInfo() : base() { } - public FindFileIDFullDirectoryInfo(byte[] buffer, ref int offset, bool isUnicode) : base(false) + public FindFileIDFullDirectoryInfo(byte[] buffer, int offset, bool isUnicode) : base() { NextEntryOffset = LittleEndianReader.ReadUInt32(buffer, ref offset); FileIndex = LittleEndianReader.ReadUInt32(buffer, ref offset); diff --git a/SMBLibrary/SMB1FileStore/Structures/FindInformation/FindFileNamesInfo.cs b/SMBLibrary/SMB1FileStore/Structures/FindInformation/FindFileNamesInfo.cs index 37cba04..e4b07f2 100644 --- a/SMBLibrary/SMB1FileStore/Structures/FindInformation/FindFileNamesInfo.cs +++ b/SMBLibrary/SMB1FileStore/Structures/FindInformation/FindFileNamesInfo.cs @@ -18,16 +18,16 @@ namespace SMBLibrary.SMB1 { public const int FixedLength = 12; - public uint NextEntryOffset; + // uint NextEntryOffset; public uint FileIndex; // SHOULD be set to zero when sent in a response and SHOULD be ignored when received by the client //uint FileNameLength; // In bytes, MUST exclude the null termination. public string FileName; // OEM / Unicode character array. MUST be written as SMB_STRING, and read as fixed length string. - public FindFileNamesInfo() : base(false) + public FindFileNamesInfo() : base() { } - public FindFileNamesInfo(byte[] buffer, ref int offset, bool isUnicode) : base(false) + public FindFileNamesInfo(byte[] buffer, int offset, bool isUnicode) : base() { NextEntryOffset = LittleEndianReader.ReadUInt32(buffer, ref offset); FileIndex = LittleEndianReader.ReadUInt32(buffer, ref offset); diff --git a/SMBLibrary/SMB1FileStore/Structures/FindInformation/FindInformation.cs b/SMBLibrary/SMB1FileStore/Structures/FindInformation/FindInformation.cs index 987ba05..c451290 100644 --- a/SMBLibrary/SMB1FileStore/Structures/FindInformation/FindInformation.cs +++ b/SMBLibrary/SMB1FileStore/Structures/FindInformation/FindInformation.cs @@ -12,42 +12,37 @@ namespace SMBLibrary.SMB1 { public abstract class FindInformation { - private bool m_returnResumeKeys; + public uint NextEntryOffset; - public FindInformation(bool returnResumeKeys) + public FindInformation() { - m_returnResumeKeys = returnResumeKeys; } public abstract void WriteBytes(byte[] buffer, ref int offset, bool isUnicode); public abstract int GetLength(bool isUnicode); - public bool ReturnResumeKeys - { - get - { - return m_returnResumeKeys; - } - } - public abstract FindInformationLevel InformationLevel { get; } - public static FindInformation ReadEntry(byte[] buffer, ref int offset, FindInformationLevel informationLevel, bool isUnicode, bool returnResumeKeys) + public static FindInformation ReadEntry(byte[] buffer, int offset, FindInformationLevel informationLevel, bool isUnicode, bool returnResumeKeys) { switch (informationLevel) { case FindInformationLevel.SMB_FIND_FILE_DIRECTORY_INFO: - return new FindFileDirectoryInfo(buffer, ref offset, isUnicode); + return new FindFileDirectoryInfo(buffer, offset, isUnicode); case FindInformationLevel.SMB_FIND_FILE_FULL_DIRECTORY_INFO: - return new FindFileFullDirectoryInfo(buffer, ref offset, isUnicode); + return new FindFileFullDirectoryInfo(buffer, offset, isUnicode); case FindInformationLevel.SMB_FIND_FILE_NAMES_INFO: - return new FindFileNamesInfo(buffer, ref offset, isUnicode); + return new FindFileNamesInfo(buffer, offset, isUnicode); case FindInformationLevel.SMB_FIND_FILE_BOTH_DIRECTORY_INFO: - return new FindFileBothDirectoryInfo(buffer, ref offset, isUnicode); + return new FindFileBothDirectoryInfo(buffer, offset, isUnicode); + case FindInformationLevel.SMB_FIND_FILE_ID_FULL_DIRECTORY_INFO: + return new FindFileIDFullDirectoryInfo(buffer, offset, isUnicode); + case FindInformationLevel.SMB_FIND_FILE_ID_BOTH_DIRECTORY_INFO: + return new FindFileIDBothDirectoryInfo(buffer, offset, isUnicode); default: throw new UnsupportedInformationLevelException(); } diff --git a/SMBLibrary/SMB1FileStore/Structures/FindInformation/FindInformationList.cs b/SMBLibrary/SMB1FileStore/Structures/FindInformation/FindInformationList.cs index 73111d2..9f29eec 100644 --- a/SMBLibrary/SMB1FileStore/Structures/FindInformation/FindInformationList.cs +++ b/SMBLibrary/SMB1FileStore/Structures/FindInformation/FindInformationList.cs @@ -22,36 +22,20 @@ namespace SMBLibrary.SMB1 int offset = 0; while (offset < buffer.Length) { - FindInformation entry = FindInformation.ReadEntry(buffer, ref offset, informationLevel, isUnicode, returnResumeKeys); + FindInformation entry = FindInformation.ReadEntry(buffer, offset, informationLevel, isUnicode, returnResumeKeys); this.Add(entry); + offset += (int)entry.NextEntryOffset; } } public byte[] GetBytes(bool isUnicode) { - for(int index = 0; index < this.Count; index++) + for(int index = 0; index < this.Count - 1; index++) { - if (index < this.Count - 1) - { - FindInformation entry = this[index]; - int entryLength = entry.GetLength(isUnicode); - if (entry is FindFileBothDirectoryInfo) - { - ((FindFileBothDirectoryInfo)entry).NextEntryOffset = (uint)entryLength; - } - else if (entry is FindFileDirectoryInfo) - { - ((FindFileDirectoryInfo)entry).NextEntryOffset = (uint)entryLength; - } - else if (entry is FindFileFullDirectoryInfo) - { - ((FindFileFullDirectoryInfo)entry).NextEntryOffset = (uint)entryLength; - } - else if (entry is FindFileNamesInfo) - { - ((FindFileNamesInfo)entry).NextEntryOffset = (uint)entryLength; - } - } + FindInformation entry = this[index]; + int entryLength = entry.GetLength(isUnicode); + entry.NextEntryOffset = (uint)entryLength; + } int length = GetLength(isUnicode); byte[] buffer = new byte[length];