Skip to content

Commit 0bb9d3b

Browse files
committed
Added IComplexScanComparer.
Implemented RegexStringMemoryComparer. Implemented ComplexScannerWorker.
1 parent 30f5320 commit 0bb9d3b

File tree

6 files changed

+178
-1
lines changed

6 files changed

+178
-1
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using System.Collections.Generic;
2+
3+
namespace ReClassNET.MemoryScanner.Comparer
4+
{
5+
public interface IComplexScanComparer : IScanComparer
6+
{
7+
/// <summary>
8+
/// Compares all data to the current <see cref="IScanComparer.CompareType"/>.
9+
/// </summary>
10+
/// <param name="data">The byte array to be compared.</param>
11+
/// <param name="size">The index into the byte array.</param>
12+
/// <returns>List of matches.</returns>
13+
IEnumerable<ScanResult> Compare(byte[] data, int size);
14+
15+
/// <summary>
16+
/// Compares all data to the current <see cref="IScanComparer.CompareType"/>.
17+
/// The previous results may be used.
18+
/// </summary>
19+
/// <param name="data">The byte array to be compared.</param>
20+
/// <param name="size">The index into the byte array.</param>
21+
/// <param name="previous">Scan result to be compared.</param>
22+
/// <param name="result">[out] The scan result if the <see cref="IScanComparer.CompareType"/> matched.</param>
23+
/// <returns>True if matched.</returns>
24+
bool CompareWithPrevious(byte[] data, int size, ScanResult previous, out ScanResult result);
25+
}
26+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
using System.Text.RegularExpressions;
5+
6+
namespace ReClassNET.MemoryScanner.Comparer
7+
{
8+
public class RegexStringMemoryComparer : IComplexScanComparer
9+
{
10+
public ScanCompareType CompareType => ScanCompareType.Equal;
11+
12+
public Regex Pattern { get; }
13+
14+
public Encoding Encoding { get; }
15+
16+
public RegexStringMemoryComparer(string pattern, Encoding encoding)
17+
{
18+
Pattern = new Regex(pattern, RegexOptions.Singleline | RegexOptions.Compiled);
19+
20+
Encoding = encoding;
21+
}
22+
23+
public IEnumerable<ScanResult> Compare(byte[] data, int size)
24+
{
25+
var buffer = Encoding.GetString(data, 0, size);
26+
var bufferArray = buffer.ToCharArray();
27+
28+
var lastIndex = 0;
29+
var lastOffset = 0;
30+
31+
var match = Pattern.Match(buffer);
32+
while (match.Success)
33+
{
34+
var byteOffset = Encoding.GetByteCount(bufferArray, lastIndex, match.Index) + lastOffset;
35+
36+
lastIndex = match.Index;
37+
lastOffset = byteOffset;
38+
39+
yield return new RegexStringScanResult(match.Value, Encoding)
40+
{
41+
Address = (IntPtr)byteOffset
42+
};
43+
44+
match = match.NextMatch();
45+
}
46+
}
47+
48+
public bool CompareWithPrevious(byte[] data, int size, ScanResult previous, out ScanResult result)
49+
{
50+
result = null;
51+
52+
var byteOffset = previous.Address.ToInt32();
53+
if (byteOffset >= size)
54+
{
55+
return false;
56+
}
57+
58+
var buffer = Encoding.GetString(data, byteOffset, size - byteOffset);
59+
60+
var match = Pattern.Match(buffer);
61+
if (!match.Success)
62+
{
63+
return false;
64+
}
65+
66+
result = new RegexStringScanResult(match.Value, Encoding)
67+
{
68+
Address = (IntPtr)byteOffset
69+
};
70+
71+
return true;
72+
}
73+
}
74+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
using System.Collections.Generic;
2+
using System.Threading;
3+
using ReClassNET.MemoryScanner.Comparer;
4+
5+
namespace ReClassNET.MemoryScanner
6+
{
7+
internal class ComplexScannerWorker : IScannerWorker
8+
{
9+
private readonly ScanSettings settings;
10+
private readonly IComplexScanComparer comparer;
11+
12+
public ComplexScannerWorker(ScanSettings settings, IComplexScanComparer comparer)
13+
{
14+
this.settings = settings;
15+
this.comparer = comparer;
16+
}
17+
18+
public IList<ScanResult> Search(byte[] data, int count, CancellationToken ct)
19+
{
20+
var results = new List<ScanResult>();
21+
22+
foreach (var result in comparer.Compare(data, count))
23+
{
24+
results.Add(result);
25+
26+
if (ct.IsCancellationRequested)
27+
{
28+
break;
29+
}
30+
}
31+
32+
return results;
33+
}
34+
35+
public IList<ScanResult> Search(byte[] data, int count, IEnumerable<ScanResult> previousResults, CancellationToken ct)
36+
{
37+
var results = new List<ScanResult>();
38+
39+
foreach (var previousResult in previousResults)
40+
{
41+
if (ct.IsCancellationRequested)
42+
{
43+
break;
44+
}
45+
46+
if (comparer.CompareWithPrevious(data, count, previousResult, out var result))
47+
{
48+
result.Address = previousResult.Address;
49+
50+
results.Add(result);
51+
}
52+
}
53+
54+
return results;
55+
}
56+
}
57+
}

ReClass.NET/MemoryScanner/ScanResult.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,4 +295,18 @@ public override int GetHashCode()
295295
return Address.GetHashCode() * 19 + Value.GetHashCode() * 19 + Encoding.GetHashCode();
296296
}
297297
}
298+
299+
public class RegexStringScanResult : StringScanResult
300+
{
301+
public RegexStringScanResult(string value, Encoding encoding)
302+
: base(value, encoding)
303+
{
304+
305+
}
306+
307+
public override ScanResult Clone()
308+
{
309+
return new RegexStringScanResult(Value, Encoding) { Address = Address };
310+
}
311+
}
298312
}

ReClass.NET/MemoryScanner/Scanner.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,9 @@ private static IScannerWorker CreateWorker(ScanSettings settings, IScanComparer
406406
{
407407
return new SimpleScannerWorker(settings, simpleScanComparer);
408408
}
409+
if (comparer is IComplexScanComparer complexScanComparer)
410+
{
411+
return new ComplexScannerWorker(settings, complexScanComparer);
409412
}
410413

411414
throw new Exception();

ReClass.NET/ReClass.NET.csproj

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<?xml version="1.0" encoding="utf-8"?>
1+
<?xml version="1.0" encoding="utf-8"?>
22
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
33
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
44
<PropertyGroup>
@@ -242,12 +242,15 @@
242242
<Compile Include="MemoryScanner\Comparer\ByteMemoryComparer.cs" />
243243
<Compile Include="MemoryScanner\Comparer\DoubleMemoryComparer.cs" />
244244
<Compile Include="MemoryScanner\Comparer\FloatMemoryComparer.cs" />
245+
<Compile Include="MemoryScanner\Comparer\IComplexScanComparer.cs" />
245246
<Compile Include="MemoryScanner\Comparer\IScanComparer.cs" />
246247
<Compile Include="MemoryScanner\Comparer\IntegerMemoryComparer.cs" />
247248
<Compile Include="MemoryScanner\Comparer\ISimpleScanComparer.cs" />
248249
<Compile Include="MemoryScanner\Comparer\LongMemoryComparer.cs" />
250+
<Compile Include="MemoryScanner\Comparer\RegexStringMemoryComparer.cs" />
249251
<Compile Include="MemoryScanner\Comparer\ShortMemoryComparer.cs" />
250252
<Compile Include="MemoryScanner\Comparer\StringMemoryComparer.cs" />
253+
<Compile Include="MemoryScanner\ComplexScannerWorker.cs" />
251254
<Compile Include="MemoryScanner\InputCorrelatedScanner.cs" />
252255
<Compile Include="MemoryScanner\IScannerWorker.cs" />
253256
<Compile Include="MemoryScanner\MemoryRecord.cs" />

0 commit comments

Comments
 (0)