From 38af5d0bfee5c6fead83c8d53b80eb27920635d8 Mon Sep 17 00:00:00 2001 From: KN4CK3R Date: Mon, 2 Apr 2018 21:18:17 +0200 Subject: [PATCH 1/4] Use unsafe methods to improve performance. --- ReClass.NET/MemoryScanner/BytePattern.cs | 16 +++++- .../Comparer/ArrayOfBytesMemoryComparer.cs | 21 +++++--- .../Comparer/ByteMemoryComparer.cs | 12 ++--- .../Comparer/DoubleMemoryComparer.cs | 12 ++--- .../Comparer/FloatMemoryComparer.cs | 12 ++--- .../MemoryScanner/Comparer/IScanComparer.cs | 15 ++---- .../Comparer/IntegerMemoryComparer.cs | 15 +++--- .../Comparer/LongMemoryComparer.cs | 15 +++--- .../Comparer/ShortMemoryComparer.cs | 15 +++--- .../Comparer/StringMemoryComparer.cs | 30 ++++------- ReClass.NET/MemoryScanner/ScannerWorker.cs | 52 ++++++++++++------- ReClass.NET/ReClass.NET.csproj | 6 ++- 12 files changed, 117 insertions(+), 104 deletions(-) diff --git a/ReClass.NET/MemoryScanner/BytePattern.cs b/ReClass.NET/MemoryScanner/BytePattern.cs index 414d2494..aa6752e6 100644 --- a/ReClass.NET/MemoryScanner/BytePattern.cs +++ b/ReClass.NET/MemoryScanner/BytePattern.cs @@ -5,7 +5,6 @@ using System.Linq; using System.Text; using ReClassNET.Extensions; -using ReClassNET.Util; namespace ReClassNET.MemoryScanner { @@ -223,6 +222,21 @@ public bool Equals(byte[] data, int index) return true; } + public unsafe bool Equals(byte* data) + { + Contract.Requires(data != null); + + for (var j = 0; j < pattern.Count; ++j) + { + if (!pattern[j].Equals(*(data + j))) + { + return false; + } + } + + return true; + } + /// /// Converts this to a byte array. /// diff --git a/ReClass.NET/MemoryScanner/Comparer/ArrayOfBytesMemoryComparer.cs b/ReClass.NET/MemoryScanner/Comparer/ArrayOfBytesMemoryComparer.cs index e7e2bcbc..a09dbb91 100644 --- a/ReClass.NET/MemoryScanner/Comparer/ArrayOfBytesMemoryComparer.cs +++ b/ReClass.NET/MemoryScanner/Comparer/ArrayOfBytesMemoryComparer.cs @@ -1,5 +1,4 @@ -using System; -using System.Diagnostics; +using System.Diagnostics; using System.Diagnostics.Contracts; namespace ReClassNET.MemoryScanner.Comparer @@ -31,7 +30,7 @@ public ArrayOfBytesMemoryComparer(byte[] pattern) byteArray = pattern; } - public bool Compare(byte[] data, int index, out ScanResult result) + public unsafe bool Compare(byte* data, out ScanResult result) { result = null; @@ -39,31 +38,37 @@ public bool Compare(byte[] data, int index, out ScanResult result) { for (var i = 0; i < byteArray.Length; ++i) { - if (data[index + i] != byteArray[i]) + if (*(data + i) != byteArray[i]) { return false; } } } - else if (!bytePattern.Equals(data, index)) + else if (!bytePattern.Equals(data)) { return false; } var temp = new byte[ValueSize]; - Array.Copy(data, index, temp, 0, temp.Length); + fixed (byte* cpy = &temp[0]) + { + for (var i = 0; i < ValueSize; ++i) + { + *(cpy + i) = *(data + i); + } + } result = new ArrayOfBytesScanResult(temp); return true; } - public bool Compare(byte[] data, int index, ScanResult previous, out ScanResult result) + public unsafe bool Compare(byte* data, ScanResult previous, out ScanResult result) { #if DEBUG Debug.Assert(previous is ArrayOfBytesScanResult); #endif - return Compare(data, index, out result); + return Compare(data, out result); } } } diff --git a/ReClass.NET/MemoryScanner/Comparer/ByteMemoryComparer.cs b/ReClass.NET/MemoryScanner/Comparer/ByteMemoryComparer.cs index 4d175d9f..a79672d1 100644 --- a/ReClass.NET/MemoryScanner/Comparer/ByteMemoryComparer.cs +++ b/ReClass.NET/MemoryScanner/Comparer/ByteMemoryComparer.cs @@ -26,11 +26,11 @@ public ByteMemoryComparer(ScanCompareType compareType, byte value1, byte value2) Value2 = value2; } - public bool Compare(byte[] data, int index, out ScanResult result) + public unsafe bool Compare(byte* data, out ScanResult result) { result = null; - var value = data[index]; + var value = *data; bool IsMatch() { @@ -69,20 +69,20 @@ bool IsMatch() return true; } - public bool Compare(byte[] data, int index, ScanResult previous, out ScanResult result) + public unsafe bool Compare(byte* data, ScanResult previous, out ScanResult result) { #if DEBUG Debug.Assert(previous is ByteScanResult); #endif - return Compare(data, index, (ByteScanResult)previous, out result); + return Compare(data, (ByteScanResult)previous, out result); } - public bool Compare(byte[] data, int index, ByteScanResult previous, out ScanResult result) + public unsafe bool Compare(byte* data, ByteScanResult previous, out ScanResult result) { result = null; - var value = data[index]; + var value = *data; bool IsMatch() { diff --git a/ReClass.NET/MemoryScanner/Comparer/DoubleMemoryComparer.cs b/ReClass.NET/MemoryScanner/Comparer/DoubleMemoryComparer.cs index 56c50164..266addc7 100644 --- a/ReClass.NET/MemoryScanner/Comparer/DoubleMemoryComparer.cs +++ b/ReClass.NET/MemoryScanner/Comparer/DoubleMemoryComparer.cs @@ -55,11 +55,11 @@ private bool CheckRoundedEquality(double value) } } - public bool Compare(byte[] data, int index, out ScanResult result) + public unsafe bool Compare(byte* data, out ScanResult result) { result = null; - var value = BitConverter.ToDouble(data, index); + var value = *(double*)data; bool IsMatch() { @@ -98,20 +98,20 @@ bool IsMatch() return true; } - public bool Compare(byte[] data, int index, ScanResult previous, out ScanResult result) + public unsafe bool Compare(byte* data, ScanResult previous, out ScanResult result) { #if DEBUG Debug.Assert(previous is DoubleScanResult); #endif - return Compare(data, index, (DoubleScanResult)previous, out result); + return Compare(data, (DoubleScanResult)previous, out result); } - public bool Compare(byte[] data, int index, DoubleScanResult previous, out ScanResult result) + public unsafe bool Compare(byte* data, DoubleScanResult previous, out ScanResult result) { result = null; - var value = BitConverter.ToDouble(data, index); + var value = *(double*)data; bool IsMatch() { diff --git a/ReClass.NET/MemoryScanner/Comparer/FloatMemoryComparer.cs b/ReClass.NET/MemoryScanner/Comparer/FloatMemoryComparer.cs index 52e96974..86db6bf8 100644 --- a/ReClass.NET/MemoryScanner/Comparer/FloatMemoryComparer.cs +++ b/ReClass.NET/MemoryScanner/Comparer/FloatMemoryComparer.cs @@ -55,11 +55,11 @@ private bool CheckRoundedEquality(float value) } } - public bool Compare(byte[] data, int index, out ScanResult result) + public unsafe bool Compare(byte* data, out ScanResult result) { result = null; - var value = BitConverter.ToSingle(data, index); + var value = *(float*)data; bool IsMatch() { @@ -98,20 +98,20 @@ bool IsMatch() return true; } - public bool Compare(byte[] data, int index, ScanResult previous, out ScanResult result) + public unsafe bool Compare(byte* data, ScanResult previous, out ScanResult result) { #if DEBUG Debug.Assert(previous is FloatScanResult); #endif - return Compare(data, index, (FloatScanResult)previous, out result); + return Compare(data, (FloatScanResult)previous, out result); } - public bool Compare(byte[] data, int index, FloatScanResult previous, out ScanResult result) + public unsafe bool Compare(byte* data, FloatScanResult previous, out ScanResult result) { result = null; - var value = BitConverter.ToSingle(data, index); + var value = *(float*)data; bool IsMatch() { diff --git a/ReClass.NET/MemoryScanner/Comparer/IScanComparer.cs b/ReClass.NET/MemoryScanner/Comparer/IScanComparer.cs index 35be65f5..8537334f 100644 --- a/ReClass.NET/MemoryScanner/Comparer/IScanComparer.cs +++ b/ReClass.NET/MemoryScanner/Comparer/IScanComparer.cs @@ -13,21 +13,19 @@ public interface IScanComparer /// Compares the data at the provided index to the current . /// /// The byte array to be compared. - /// The index into the byte array. /// [out] The scan result if the matched. /// True if matched. - bool Compare(byte[] data, int index, out ScanResult result); + unsafe bool Compare(byte* data, out ScanResult result); /// /// Compares the data at the provided index to the current . /// The previous results may be used. /// /// The byte array to be compared. - /// The index into the byte array. /// Scan result to be compared. /// [out] The scan result if the matched. /// True if matched. - bool Compare(byte[] data, int index, ScanResult previous, out ScanResult result); + unsafe bool Compare(byte* data, ScanResult previous, out ScanResult result); } [ContractClassFor(typeof(IScanComparer))] @@ -44,18 +42,13 @@ public int ValueSize throw new NotImplementedException(); } } - public bool Compare(byte[] data, int index, out ScanResult result) + public unsafe bool Compare(byte* data, out ScanResult result) { - Contract.Requires(data != null); - Contract.Requires(index >= 0); - throw new NotImplementedException(); } - public bool Compare(byte[] data, int index, ScanResult previous, out ScanResult result) + public unsafe bool Compare(byte* data, ScanResult previous, out ScanResult result) { - Contract.Requires(data != null); - Contract.Requires(index >= 0); Contract.Requires(previous != null); throw new NotImplementedException(); diff --git a/ReClass.NET/MemoryScanner/Comparer/IntegerMemoryComparer.cs b/ReClass.NET/MemoryScanner/Comparer/IntegerMemoryComparer.cs index 3a8b97ba..e7505916 100644 --- a/ReClass.NET/MemoryScanner/Comparer/IntegerMemoryComparer.cs +++ b/ReClass.NET/MemoryScanner/Comparer/IntegerMemoryComparer.cs @@ -1,5 +1,4 @@ -using System; -using System.Diagnostics; +using System.Diagnostics; using ReClassNET.Util; namespace ReClassNET.MemoryScanner.Comparer @@ -27,11 +26,11 @@ public IntegerMemoryComparer(ScanCompareType compareType, int value1, int value2 Value2 = value2; } - public bool Compare(byte[] data, int index, out ScanResult result) + public unsafe bool Compare(byte* data, out ScanResult result) { result = null; - var value = BitConverter.ToInt32(data, index); + var value = *(int*)data; bool IsMatch() { @@ -70,20 +69,20 @@ bool IsMatch() return true; } - public bool Compare(byte[] data, int index, ScanResult previous, out ScanResult result) + public unsafe bool Compare(byte* data, ScanResult previous, out ScanResult result) { #if DEBUG Debug.Assert(previous is IntegerScanResult); #endif - return Compare(data, index, (IntegerScanResult)previous, out result); + return Compare(data, (IntegerScanResult)previous, out result); } - public bool Compare(byte[] data, int index, IntegerScanResult previous, out ScanResult result) + public unsafe bool Compare(byte* data, IntegerScanResult previous, out ScanResult result) { result = null; - var value = BitConverter.ToInt32(data, index); + var value = *(int*)data; bool IsMatch() { diff --git a/ReClass.NET/MemoryScanner/Comparer/LongMemoryComparer.cs b/ReClass.NET/MemoryScanner/Comparer/LongMemoryComparer.cs index 662f1a99..b3e9d992 100644 --- a/ReClass.NET/MemoryScanner/Comparer/LongMemoryComparer.cs +++ b/ReClass.NET/MemoryScanner/Comparer/LongMemoryComparer.cs @@ -1,5 +1,4 @@ -using System; -using System.Diagnostics; +using System.Diagnostics; using ReClassNET.Util; namespace ReClassNET.MemoryScanner.Comparer @@ -27,11 +26,11 @@ public LongMemoryComparer(ScanCompareType compareType, long value1, long value2) Value2 = value2; } - public bool Compare(byte[] data, int index, out ScanResult result) + public unsafe bool Compare(byte* data, out ScanResult result) { result = null; - var value = BitConverter.ToInt64(data, index); + var value = *(long*)data; bool IsMatch() { @@ -70,20 +69,20 @@ bool IsMatch() return true; } - public bool Compare(byte[] data, int index, ScanResult previous, out ScanResult result) + public unsafe bool Compare(byte* data, ScanResult previous, out ScanResult result) { #if DEBUG Debug.Assert(previous is LongScanResult); #endif - return Compare(data, index, (LongScanResult)previous, out result); + return Compare(data, (LongScanResult)previous, out result); } - public bool Compare(byte[] data, int index, LongScanResult previous, out ScanResult result) + public unsafe bool Compare(byte* data, LongScanResult previous, out ScanResult result) { result = null; - var value = BitConverter.ToInt64(data, index); + var value = *(long*)data; bool IsMatch() { diff --git a/ReClass.NET/MemoryScanner/Comparer/ShortMemoryComparer.cs b/ReClass.NET/MemoryScanner/Comparer/ShortMemoryComparer.cs index 8e541704..08a97bb0 100644 --- a/ReClass.NET/MemoryScanner/Comparer/ShortMemoryComparer.cs +++ b/ReClass.NET/MemoryScanner/Comparer/ShortMemoryComparer.cs @@ -1,5 +1,4 @@ -using System; -using System.Diagnostics; +using System.Diagnostics; using ReClassNET.Util; namespace ReClassNET.MemoryScanner.Comparer @@ -27,11 +26,11 @@ public ShortMemoryComparer(ScanCompareType compareType, short value1, short valu Value2 = value2; } - public bool Compare(byte[] data, int index, out ScanResult result) + public unsafe bool Compare(byte* data, out ScanResult result) { result = null; - var value = BitConverter.ToInt16(data, index); + var value = *(short*)data; bool IsMatch() { @@ -70,20 +69,20 @@ bool IsMatch() return true; } - public bool Compare(byte[] data, int index, ScanResult previous, out ScanResult result) + public unsafe bool Compare(byte* data, ScanResult previous, out ScanResult result) { #if DEBUG Debug.Assert(previous is ShortScanResult); #endif - return Compare(data, index, (ShortScanResult)previous, out result); + return Compare(data, (ShortScanResult)previous, out result); } - public bool Compare(byte[] data, int index, ShortScanResult previous, out ScanResult result) + public unsafe bool Compare(byte* data, ShortScanResult previous, out ScanResult result) { result = null; - var value = BitConverter.ToInt16(data, index); + var value = *(short*)data; bool IsMatch() { diff --git a/ReClass.NET/MemoryScanner/Comparer/StringMemoryComparer.cs b/ReClass.NET/MemoryScanner/Comparer/StringMemoryComparer.cs index 44b958ed..b0441711 100644 --- a/ReClass.NET/MemoryScanner/Comparer/StringMemoryComparer.cs +++ b/ReClass.NET/MemoryScanner/Comparer/StringMemoryComparer.cs @@ -1,8 +1,7 @@ using System; using System.Diagnostics; +using System.Linq; using System.Text; -using ReClassNET.Extensions; -using ReClassNET.Util; namespace ReClassNET.MemoryScanner.Comparer { @@ -12,39 +11,30 @@ public class StringMemoryComparer : IScanComparer public bool CaseSensitive { get; } public Encoding Encoding { get; } public string Value { get; } + public char[] Chars { get; } public int ValueSize { get; } public StringMemoryComparer(string value, Encoding encoding, bool caseSensitive) { - Value = value; - Encoding = encoding; CaseSensitive = caseSensitive; - ValueSize = Value.Length * Encoding.GetSimpleByteCountPerChar(); + Encoding = encoding; + Value = value; + Chars = value.Select(c => caseSensitive ? c : char.ToUpperInvariant(c)).ToArray(); + ValueSize = encoding.GetByteCount(value); } - public bool Compare(byte[] data, int index, out ScanResult result) + public unsafe bool Compare(byte* data, out ScanResult result) { - result = null; - - var value = Encoding.GetString(data, index, Value.Length); - - if (!Value.Equals(value, CaseSensitive ? StringComparison.InvariantCulture : StringComparison.InvariantCultureIgnoreCase)) - { - return false; - } - - result = new StringScanResult(value, Encoding); - - return true; + throw new NotImplementedException(); } - public bool Compare(byte[] data, int index, ScanResult previous, out ScanResult result) + public unsafe bool Compare(byte* data, ScanResult previous, out ScanResult result) { #if DEBUG Debug.Assert(previous is StringScanResult); #endif - return Compare(data, index, out result); + return Compare(data, out result); } } } diff --git a/ReClass.NET/MemoryScanner/ScannerWorker.cs b/ReClass.NET/MemoryScanner/ScannerWorker.cs index b83dc714..21b642ee 100644 --- a/ReClass.NET/MemoryScanner/ScannerWorker.cs +++ b/ReClass.NET/MemoryScanner/ScannerWorker.cs @@ -35,18 +35,24 @@ public IList Search(byte[] data, int count, CancellationToken ct) var endIndex = count - comparer.ValueSize; - for (var i = 0; i < endIndex; i += settings.FastScanAlignment) + unsafe { - if (ct.IsCancellationRequested) + fixed (byte* ptr = &data[0]) { - break; - } + for (var i = 0; i < endIndex; i += settings.FastScanAlignment) + { + if (ct.IsCancellationRequested) + { + break; + } - if (comparer.Compare(data, i, out var result)) - { - result.Address = (IntPtr)i; + if (comparer.Compare(ptr + i, out var result)) + { + result.Address = (IntPtr)i; - results.Add(result); + results.Add(result); + } + } } } @@ -71,21 +77,27 @@ public IList Search(byte[] data, int count, IEnumerable var endIndex = count - comparer.ValueSize; - foreach (var previousResult in previousResults) + unsafe { - if (ct.IsCancellationRequested) + fixed (byte* ptr = &data[0]) { - break; - } - - var offset = previousResult.Address.ToInt32(); - if (offset <= endIndex) - { - if (comparer.Compare(data, offset, previousResult, out var result)) + foreach (var previousResult in previousResults) { - result.Address = previousResult.Address; - - results.Add(result); + if (ct.IsCancellationRequested) + { + break; + } + + var offset = previousResult.Address.ToInt32(); + if (offset <= endIndex) + { + if (comparer.Compare(ptr + offset, previousResult, out var result)) + { + result.Address = previousResult.Address; + + results.Add(result); + } + } } } } diff --git a/ReClass.NET/ReClass.NET.csproj b/ReClass.NET/ReClass.NET.csproj index c8241085..96d8765c 100644 --- a/ReClass.NET/ReClass.NET.csproj +++ b/ReClass.NET/ReClass.NET.csproj @@ -26,7 +26,7 @@ TRACE;DEBUG;RECLASSNET32 prompt 4 - false + true False False True @@ -80,6 +80,7 @@ TRACE;RECLASSNET32;RELEASE prompt 4 + true x64 @@ -91,7 +92,7 @@ TRACE;DEBUG;RECLASSNET64 prompt 4 - false + true x64 @@ -102,6 +103,7 @@ TRACE;RECLASSNET64;RELEASE prompt 4 + true Resources\Icon\ReClassNet.ico From f30748f19cc604ff1ae68b2771f43ce1e7e031fb Mon Sep 17 00:00:00 2001 From: KN4CK3R Date: Mon, 2 Apr 2018 21:20:04 +0200 Subject: [PATCH 2/4] Removed unused usings. --- ReClass.NET/MemoryScanner/ScanResultBlock.cs | 1 - ReClass.NET/MemoryScanner/ScanResultStore.cs | 1 - 2 files changed, 2 deletions(-) diff --git a/ReClass.NET/MemoryScanner/ScanResultBlock.cs b/ReClass.NET/MemoryScanner/ScanResultBlock.cs index 14aad1ac..ab657c15 100644 --- a/ReClass.NET/MemoryScanner/ScanResultBlock.cs +++ b/ReClass.NET/MemoryScanner/ScanResultBlock.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Diagnostics.Contracts; using ReClassNET.Extensions; -using ReClassNET.Util; namespace ReClassNET.MemoryScanner { diff --git a/ReClass.NET/MemoryScanner/ScanResultStore.cs b/ReClass.NET/MemoryScanner/ScanResultStore.cs index 70a03d04..08417ab5 100644 --- a/ReClass.NET/MemoryScanner/ScanResultStore.cs +++ b/ReClass.NET/MemoryScanner/ScanResultStore.cs @@ -4,7 +4,6 @@ using System.IO; using System.Text; using ReClassNET.Extensions; -using ReClassNET.Util; namespace ReClassNET.MemoryScanner { From 9d191fcb626aca4f77bb1bfc6d5b421c4458213b Mon Sep 17 00:00:00 2001 From: KN4CK3R Date: Tue, 3 Apr 2018 11:17:34 +0200 Subject: [PATCH 3/4] Implemented faster string search. --- .../Comparer/StringMemoryComparer.cs | 78 +++++++++++++++++-- 1 file changed, 70 insertions(+), 8 deletions(-) diff --git a/ReClass.NET/MemoryScanner/Comparer/StringMemoryComparer.cs b/ReClass.NET/MemoryScanner/Comparer/StringMemoryComparer.cs index b0441711..40b847fe 100644 --- a/ReClass.NET/MemoryScanner/Comparer/StringMemoryComparer.cs +++ b/ReClass.NET/MemoryScanner/Comparer/StringMemoryComparer.cs @@ -1,5 +1,4 @@ -using System; -using System.Diagnostics; +using System.Diagnostics; using System.Linq; using System.Text; @@ -8,24 +7,87 @@ namespace ReClassNET.MemoryScanner.Comparer public class StringMemoryComparer : IScanComparer { public ScanCompareType CompareType => ScanCompareType.Equal; - public bool CaseSensitive { get; } + public bool IsCaseSensitive { get; } public Encoding Encoding { get; } public string Value { get; } public char[] Chars { get; } public int ValueSize { get; } - public StringMemoryComparer(string value, Encoding encoding, bool caseSensitive) + private unsafe delegate char GetCharacter(byte* data, int index); + + private readonly GetCharacter getCharacter; + + public StringMemoryComparer(string value, Encoding encoding, bool isCaseSensitive) { - CaseSensitive = caseSensitive; + IsCaseSensitive = isCaseSensitive; Encoding = encoding; Value = value; - Chars = value.Select(c => caseSensitive ? c : char.ToUpperInvariant(c)).ToArray(); - ValueSize = encoding.GetByteCount(value); + Chars = value.Select(c => isCaseSensitive ? c : char.ToUpperInvariant(c)).ToArray(); + ValueSize = Encoding.GetByteCount(value); + + unsafe + { + getCharacter = Encoding == Encoding.UTF8 + ? IsCaseSensitive + ? (GetCharacter)GetCharacterCaseSensitiveUtf8 + : GetCharacterCaseInsensitiveUtf8 + : Encoding == Encoding.Unicode + ? IsCaseSensitive + ? (GetCharacter)GetCharacterCaseSensitiveUtf16 + : GetCharacterCaseInsensitiveUtf16 + : IsCaseSensitive + ? (GetCharacter)GetCharacterCaseSensitiveUtf32 + : GetCharacterCaseInsensitiveUtf32; + } + } + + private static unsafe char GetCharacterCaseSensitiveUtf8(byte* data, int index) + { + return (char)*(data + index); + } + + private static unsafe char GetCharacterCaseInsensitiveUtf8(byte* data, int index) + { + return char.ToUpperInvariant(GetCharacterCaseSensitiveUtf8(data, index)); + } + + private static unsafe char GetCharacterCaseSensitiveUtf16(byte* data, int index) + { + return *((char*)data + index); + } + + private static unsafe char GetCharacterCaseInsensitiveUtf16(byte* data, int index) + { + return char.ToUpperInvariant(GetCharacterCaseSensitiveUtf16(data, index)); + } + + private static unsafe char GetCharacterCaseSensitiveUtf32(byte* data, int index) + { + var dst = stackalloc char[1]; + Encoding.UTF32.GetChars(data + index * sizeof(int), 4, dst, 1); + return *dst; + } + + private static unsafe char GetCharacterCaseInsensitiveUtf32(byte* data, int index) + { + return char.ToUpperInvariant(GetCharacterCaseSensitiveUtf32(data, index)); } public unsafe bool Compare(byte* data, out ScanResult result) { - throw new NotImplementedException(); + result = null; + + for (var i = 0; i < Chars.Length; ++i) + { + if (Chars[i] != getCharacter(data, i)) + { + return false; + } + } + + result = new StringScanResult(Value, Encoding); + + return true; } public unsafe bool Compare(byte* data, ScanResult previous, out ScanResult result) From 267fac9d892c82814b88fa071ec9bfbf364abc2b Mon Sep 17 00:00:00 2001 From: KN4CK3R Date: Tue, 3 Apr 2018 15:31:07 +0200 Subject: [PATCH 4/4] Added Span code for future versions. --- ReClass.NET/MemoryScanner/BytePattern.cs | 21 +++++++++++++++++++ .../Comparer/ArrayOfBytesMemoryComparer.cs | 2 ++ ReClass.NET/MemoryScanner/PatternScanner.cs | 2 ++ 3 files changed, 25 insertions(+) diff --git a/ReClass.NET/MemoryScanner/BytePattern.cs b/ReClass.NET/MemoryScanner/BytePattern.cs index aa6752e6..46335046 100644 --- a/ReClass.NET/MemoryScanner/BytePattern.cs +++ b/ReClass.NET/MemoryScanner/BytePattern.cs @@ -201,6 +201,27 @@ public static BytePattern From(IEnumerable> data) return pattern; } + // TODO: Use System.Span after it is available + /*/// + /// Tests if the provided byte array matches the byte pattern at the provided index. + /// + /// The byte array to be compared. + /// True if the pattern matches, false if they are not. + public bool Equals(Span data) + { + Contract.Requires(data != null); + + for (var j = 0; j < pattern.Count; ++j) + { + if (!pattern[j].Equals(data[j])) + { + return false; + } + } + + return true; + }*/ + /// /// Tests if the provided byte array matches the byte pattern at the provided index. /// diff --git a/ReClass.NET/MemoryScanner/Comparer/ArrayOfBytesMemoryComparer.cs b/ReClass.NET/MemoryScanner/Comparer/ArrayOfBytesMemoryComparer.cs index a09dbb91..03f3c0d3 100644 --- a/ReClass.NET/MemoryScanner/Comparer/ArrayOfBytesMemoryComparer.cs +++ b/ReClass.NET/MemoryScanner/Comparer/ArrayOfBytesMemoryComparer.cs @@ -44,6 +44,8 @@ public unsafe bool Compare(byte* data, out ScanResult result) } } } + // TODO: Use System.Span after it is available + //else if (!bytePattern.Equals(new Span(data, ValueSize))) else if (!bytePattern.Equals(data)) { return false; diff --git a/ReClass.NET/MemoryScanner/PatternScanner.cs b/ReClass.NET/MemoryScanner/PatternScanner.cs index 33adb8dd..619f8b6b 100644 --- a/ReClass.NET/MemoryScanner/PatternScanner.cs +++ b/ReClass.NET/MemoryScanner/PatternScanner.cs @@ -79,6 +79,8 @@ private static int FindPattern(BytePattern pattern, byte[] data) var limit = data.Length - pattern.Length; for (var i = 0; i < limit; ++i) { + // TODO: Use System.Span after it is available + // if (pattern.Equals(new Span(data, i, pattern.Length))) if (pattern.Equals(data, i)) { return i;