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
+98
View File
@@ -0,0 +1,98 @@
using System.Runtime.InteropServices;
using WhiteMagic.Native;
namespace WhiteMagic.ThreadEnvironment;
/// <summary>
/// Managed reader for a target thread's Thread Environment Block (TEB).
/// </summary>
public sealed class ManagedTeb : IDisposable
{
private readonly MemoryBase _memory;
private readonly SafeMemoryHandle _threadHandle;
private readonly IntPtr _tebAddress;
private bool _disposed;
/// <summary>
/// Creates a TEB reader for the specified thread in the process associated
/// with the provided memory facade.
/// </summary>
public ManagedTeb(MemoryBase memory, int threadId)
{
_memory = memory ?? throw new ArgumentNullException(nameof(memory));
_threadHandle = NativeMethods.OpenThread(
ThreadAccess.QueryInformation,
false,
threadId);
if (_threadHandle.IsInvalid)
{
int error = Marshal.GetLastPInvokeError();
throw new InvalidOperationException(
$"OpenThread failed for thread {threadId}: error {error}.");
}
_tebAddress = QueryTebAddress();
}
/// <summary>Returns the native address of the TEB in the target process.</summary>
public IntPtr ReadTebAddress() => _tebAddress;
/// <summary>Reads the stack base pointer stored in the TEB.</summary>
public IntPtr ReadStackBase()
{
int offset = _memory.Is64Bit ? 0x08 : 0x04;
return ReadPointer(offset);
}
/// <summary>Reads the stack limit pointer stored in the TEB.</summary>
public IntPtr ReadStackLimit()
{
int offset = _memory.Is64Bit ? 0x10 : 0x08;
return ReadPointer(offset);
}
/// <inheritdoc />
public void Dispose()
{
if (!_disposed)
{
_disposed = true;
_threadHandle.Dispose();
}
}
private IntPtr QueryTebAddress()
{
var info = new ThreadBasicInformation();
int status = NativeMethods.NtQueryInformationThread(
_threadHandle,
0,
ref info,
(uint)Marshal.SizeOf<ThreadBasicInformation>(),
out _);
if (status < 0 || info.TebBaseAddress == IntPtr.Zero)
{
throw new InvalidOperationException(
$"NtQueryInformationThread failed to retrieve the TEB (NTSTATUS {status:X8}).");
}
return info.TebBaseAddress;
}
private IntPtr ReadPointer(int offset)
{
IntPtr address = _tebAddress + offset;
if (_memory.Is64Bit)
{
ulong raw = _memory.Read<ulong>(address);
return new IntPtr((long)raw);
}
uint raw32 = _memory.Read<uint>(address);
return new IntPtr((int)raw32);
}
}