Files
whitemagic/WhiteMagic/Magic.cs
kbe 3e294dc846 Add process discovery helpers and Magic facade accessors
Introduces ApplicationFinder (by name/title/handle), Magic.Open overloads, and Magic.Threads/Regions/QueryRegion accessors. Closes section 3 of add-thread-region-finder and updates tasks/comparison doc.
2026-07-22 16:04:53 +02:00

114 lines
3.7 KiB
C#

using System.Collections.Generic;
using System.Diagnostics;
using Process = System.Diagnostics.Process;
using WhiteMagic.Execution;
using WhiteMagic.Hooking;
using WhiteMagic.Memory;
using WhiteMagic.ProcessDiscovery;
using WhiteMagic.Thread;
using WhiteMagic.Windows;
namespace WhiteMagic;
/// <summary>
/// High-level entry point for a WhiteMagic session. Opens a process, exposes the
/// memory reader, execution tiers, hooking managers, and the <see cref="RemotePointer"/>
/// indexer.
/// </summary>
public sealed class Magic : IDisposable
{
/// <summary>The underlying memory reader for this session.</summary>
public MemoryBase Memory { get; }
/// <summary>Out-of-process execution via <c>CreateRemoteThread</c>.</summary>
public RemoteThreadExecutor RemoteThread { get; }
/// <summary>Named byte-patch manager.</summary>
public PatchManager PatchManager => Memory.PatchManager;
/// <summary>Inline-detour manager (in-process only).</summary>
public DetourManager DetourManager => Memory.DetourManager;
/// <summary>
/// Returns the memory region that contains <paramref name="address"/>.
/// </summary>
public MemoryRegion QueryRegion(IntPtr address) => Memory.QueryRegion(address);
/// <summary>
/// Enumerates the committed and reserved regions of the target process address space.
/// </summary>
public IEnumerable<MemoryRegion> Regions => Memory.EnumerateRegions();
/// <summary>
/// Factory for discovering and operating on the target process's threads.
/// </summary>
public ThreadFactory Threads => new ThreadFactory(Memory);
private Magic(MemoryBase memory)
{
Memory = memory;
RemoteThread = new RemoteThreadExecutor(memory);
}
/// <summary>Opens an external process for reading, writing, and execution.</summary>
public static Magic Open(Process process)
{
return new Magic(new ExternalReader(process));
}
/// <summary>
/// Opens a target process by its image name. Throws if zero or more than one match.
/// </summary>
public static Magic Open(string processName)
{
using Process process = ApplicationFinder.OpenProcess(processName);
return Open(process);
}
/// <summary>
/// Opens the process that owns the top-level window with the specified title.
/// </summary>
public static Magic OpenByWindowTitle(string title)
{
using Process process = ApplicationFinder.OpenByWindowTitle(title);
return Open(process);
}
/// <summary>
/// Opens the process that owns the specified window handle.
/// </summary>
public static Magic OpenByWindowHandle(IntPtr handle)
{
using Process process = ApplicationFinder.OpenByWindowHandle(handle);
return Open(process);
}
/// <summary>Creates an in-process session for the current process.</summary>
public static Magic OpenInProcess()
{
return new Magic(new InProcessReader());
}
/// <summary>
/// Creates a main-thread pump that hooks the per-frame function at
/// <paramref name="frameAddress"/>.
/// </summary>
public MainThreadPump CreateMainThreadPump(IntPtr frameAddress)
{
return new MainThreadPump(DetourManager, frameAddress);
}
/// <summary>Returns a <see cref="RemotePointer"/> at <paramref name="address"/>.</summary>
public RemotePointer this[IntPtr address] => new RemotePointer(Memory, address);
/// <summary>Returns the loaded <see cref="RemoteModule"/> named <paramref name="moduleName"/>
/// (e.g. <c>magic["user32"]["MessageBoxA"]</c>).</summary>
public RemoteModule this[string moduleName] => new RemoteModule(this, moduleName);
/// <inheritdoc />
public void Dispose()
{
Memory.Dispose();
}
}