refactor: split node agent and Go control plane
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace WxAgent.Core;
|
||||
|
||||
/// <summary>Finds a fixed byte pattern across contiguous read-only memory chunks.</summary>
|
||||
public sealed class MemoryPatternScanner : IDisposable
|
||||
{
|
||||
private readonly byte[] _pattern;
|
||||
private readonly byte[] _tail;
|
||||
private int _tailLength;
|
||||
private ulong? _end;
|
||||
|
||||
public MemoryPatternScanner(byte[] pattern)
|
||||
{
|
||||
if (pattern.Length is < 1 or > 1024) throw new ArgumentOutOfRangeException(nameof(pattern));
|
||||
_pattern = pattern.ToArray();
|
||||
_tail = new byte[pattern.Length - 1];
|
||||
}
|
||||
|
||||
public IReadOnlyList<ulong> Feed(ReadOnlySpan<byte> bytes, ulong address)
|
||||
{
|
||||
if (_end != address) _tailLength = 0;
|
||||
var matches = new List<ulong>();
|
||||
Span<byte> boundary = stackalloc byte[_tail.Length * 2];
|
||||
var headLength = Math.Min(bytes.Length, _tail.Length);
|
||||
_tail.AsSpan(0, _tailLength).CopyTo(boundary);
|
||||
bytes[..headLength].CopyTo(boundary[_tailLength..]);
|
||||
var joined = boundary[..(_tailLength + headLength)];
|
||||
for (var i = 0; i < _tailLength; i++)
|
||||
if (i + _pattern.Length > _tailLength && i + _pattern.Length <= joined.Length
|
||||
&& joined.Slice(i, _pattern.Length).SequenceEqual(_pattern))
|
||||
matches.Add(address - (ulong)_tailLength + (ulong)i);
|
||||
var offset = 0;
|
||||
while (offset <= bytes.Length - _pattern.Length)
|
||||
{
|
||||
var found = bytes[offset..].IndexOf(_pattern);
|
||||
if (found < 0) break;
|
||||
offset += found;
|
||||
matches.Add(address + (ulong)offset);
|
||||
offset++;
|
||||
}
|
||||
if (bytes.Length >= _tail.Length)
|
||||
{
|
||||
bytes[^_tail.Length..].CopyTo(_tail);
|
||||
_tailLength = _tail.Length;
|
||||
}
|
||||
else
|
||||
{
|
||||
_tailLength = Math.Min(joined.Length, _tail.Length);
|
||||
joined[^_tailLength..].CopyTo(_tail);
|
||||
}
|
||||
CryptographicOperations.ZeroMemory(boundary);
|
||||
_end = checked(address + (ulong)bytes.Length);
|
||||
return matches;
|
||||
}
|
||||
|
||||
public void Dispose() => CryptographicOperations.ZeroMemory(_tail);
|
||||
}
|
||||
Reference in New Issue
Block a user