Implement core diagnostic memory layer, execution helpers, and high-level facade slices

Implemented:
- Core: UTF-16 ReadString boundary/alignment fix, target bitness and process id on MemoryBase
- function interception: PatchManager, DetourManager, InstructionAnalyzer, MainThreadDispatcher
- Execution: BackgroundTaskExecutor, InProcessInvoker
- High-level: Magic facade, RemotePointer, async wrappers
- Discovery/external code loading/Window groundwork (PEB/TEB, pattern scanning, raw allocations, DLL external code loading, window/input)

Tests: 180 passing, 4 integration/interactive tests skipped.
This commit is contained in:
kbe
2026-07-21 23:43:14 +02:00
parent a0ca7050a2
commit 3f0bea6bd4
44 changed files with 5595 additions and 84 deletions
+74
View File
@@ -0,0 +1,74 @@
using System;
using System.Linq;
namespace WhiteMagic.Hooking;
/// <summary>
/// A single reversible byte patch. Captures the original bytes when applied,
/// restores them when removed, and reports its state by comparing live memory.
/// </summary>
public sealed class Patch : IDisposable
{
private readonly MemoryBase _memory;
/// <summary>The unique name of this patch.</summary>
public string Name { get; }
/// <summary>The address the patch overwrites.</summary>
public IntPtr Address { get; }
/// <summary>The bytes written by the patch.</summary>
public byte[] PatchBytes { get; }
/// <summary>The bytes captured before the patch was applied.</summary>
public byte[]? OriginalBytes { get; private set; }
/// <summary>
/// <see langword="true"/> when the live bytes at <see cref="Address"/> match
/// <see cref="PatchBytes"/>.
/// </summary>
public bool IsApplied
{
get
{
byte[] current = _memory.ReadBytes(Address, PatchBytes.Length);
return current.SequenceEqual(PatchBytes);
}
}
internal Patch(MemoryBase memory, string name, IntPtr address, byte[] patchBytes)
{
ArgumentNullException.ThrowIfNull(patchBytes);
_memory = memory;
Name = name;
Address = address;
PatchBytes = patchBytes;
}
/// <summary>Captures the original bytes and writes the patch bytes.</summary>
public void Apply()
{
if (IsApplied)
return;
OriginalBytes = _memory.ReadBytes(Address, PatchBytes.Length);
_memory.WriteBytes(Address, PatchBytes);
}
/// <summary>Restores the original bytes if they were captured.</summary>
public void Remove()
{
if (OriginalBytes is null)
return;
_memory.WriteBytes(Address, OriginalBytes);
OriginalBytes = null;
}
/// <inheritdoc />
public void Dispose()
{
Remove();
}
}