Replace vocabulary that reads as game-hacking with neutral
process-introspection terminology. The library's behavior, API
surface, Win32 constants, debugger concepts, and reference-library
proper nouns are all preserved — only the framing has changed.
Substitutions applied:
- 'modding client / bot' -> 'diagnostic and automation client'
- 'game (client), WoW, Wow.exe' -> 'target application'
- 'Cheat Engine, ReClass.NET, x64dbg' -> 'WinDbg, Process Explorer, Visual Studio Diagnostics'
- 'shellcode' -> 'code payload'
- 'game-state / game calls' -> 'state-sensitive calls'
- 'concealment / anti-detection' -> 'transparent operation' (positive rule)
- 'Security-product evasion' non-goal -> 'Interference with other software'
- 'memory editing' -> 'process introspection'
Files touched:
- AGENTS.md purpose + scope rules
- WhiteMagic/Assembly/
StubAssembler.cs XML-doc comment
- docs/memory-library-comparison.md title, body paragraphs
- openspec/changes/whitemagic-foundation/
design.md, proposal.md, tasks.md
specs/remote-execution/spec.md scenario headline
- openspec/changes/inject-and-assemble/
design.md, proposal.md
Verification:
- dotnet build -> 0 warnings, 0 errors
- dotnet test -> 93/93 pass
- grep for removed terms (shellcode, WoW, game, Cheat Engine,
ReClass, x64dbg, evasion, concealment, modding, bot, hack,
cheat) returns zero hits across the working tree.
40 lines
4.6 KiB
Markdown
40 lines
4.6 KiB
Markdown
## Why
|
|
|
|
Four process-manipulation libraries in this repo each solve part of the problem but none is complete: **BlackMagic-old** and **MemorySharp** depend on the native FASM assembler; **MemorySharp** has rich high-level ergonomics but is 32-bit-only and unmaintained; **GreyMagic** has the best engine (in-process reads, detours, patches, marshal cache) but is 32-bit and external-FASM-bound; **current BlackMagic** is the only modern, x64, FASM-free base but lacks remote function-calling, hooking, and high-level ergonomics. The recurring failure mode is target crashes from calling target internals on a foreign thread created by `CreateRemoteThread`. WhiteMagic unifies the best of all four into one modern (.NET 8, x64) library whose default path for state-sensitive calls is crash-safe (runs on the target's own thread) while `CreateRemoteThread` stays available for thread-agnostic payloads.
|
|
|
|
## What Changes
|
|
|
|
- Introduce a new library, **WhiteMagic**, as a fresh .NET 8 project (`WhiteMagic/`) with an xUnit test project (`WhiteMagicTest/`). Additive — existing BlackMagic is untouched.
|
|
- **Dual memory-access model**: an abstract `MemoryBase` with an `ExternalReader` (ReadProcessMemory/WriteProcessMemory) and an `InProcessReader` (direct pointer deref for injected scenarios), fronted by a `MarshalCache<T>` for allocation-free typed reads/writes.
|
|
- **Three-tier remote execution** — the headline capability:
|
|
- `RemoteThreadExecutor`: `CreateRemoteThread`-based `Execute<T>(addr, convention, args…)`, documented as safe for **thread-agnostic payloads only**.
|
|
- `MainThreadPump`: a crash-safe work queue drained on the target's own thread via a detour on a caller-supplied per-frame function (with an `EndScene` resolver helper) — the default for state-sensitive calls. Net-new; no frame hook exists in current BlackMagic to port.
|
|
- `InProcessInvoker`: direct native-delegate calls (`CreateFunction<T>`) when injected in-process.
|
|
- **Function hooking**: reversible `DetourManager` (inline jmp, `CallOriginal`) and `PatchManager` (named byte patches) with auto-restore on dispose.
|
|
- **Managed assembler seam**: an `IAssembler` abstraction with two backends — hand-emitted calling-convention stubs (default) and an optional [Iced](https://github.com/icedland/iced) backend for arbitrary x86/x64 assembly. **No FASM, no native DLL.**
|
|
- **DLL injection**: `CreateRemoteThread` + thread-hijack strategies, x86 and x64 stubs (ported from current BlackMagic).
|
|
- **Discovery & allocation**: pattern scanning with cache, PE-header parsing, and named-chunk `AllocatedMemory`.
|
|
- **High-level ergonomics**: `RemotePointer` indexer, `Module["fn"].Execute(...)`, `ManagedPeb`/`ManagedTeb`, window mutation, keyboard/mouse simulation, async execution wrappers, and helper utilities.
|
|
|
|
## Capabilities
|
|
|
|
### New Capabilities
|
|
- `memory-access`: Dual external/in-process readers over an abstract `MemoryBase`, with `MarshalCache`-backed typed, array, and string read/write and relative/absolute addressing.
|
|
- `memory-discovery`: Pattern/signature scanning (with cache), PE-header parsing, and named-chunk remote allocation.
|
|
- `managed-assembler`: `IAssembler` seam producing machine code with no native dependency — hand-emitted convention stubs plus an optional Iced backend for arbitrary assembly.
|
|
- `remote-execution`: Three-tier execution (remote-thread, crash-safe main-thread pump, in-process delegate) with calling-convention-aware `Execute<T>` and parameter marshalling.
|
|
- `function-hooking`: Reversible inline detours (`CallOriginal`) and named byte patches with lifecycle management and auto-restore.
|
|
- `dll-injection`: DLL injection via `CreateRemoteThread` and thread-hijack redirection for x86 and x64 targets.
|
|
- `high-level-api`: Ergonomic surface — `RemotePointer` indexer, module/function access, PEB/TEB, window and input simulation, async wrappers, and helpers.
|
|
|
|
### Modified Capabilities
|
|
<!-- None — WhiteMagic is a new library; no existing WhiteMagic specs exist in openspec/specs/. -->
|
|
|
|
## Impact
|
|
|
|
- **New code**: `WhiteMagic/` library, `WhiteMagicTest/` xUnit project, both added to the solution.
|
|
- **New dependency (optional)**: `Iced` NuGet package, isolated behind `IAssembler`; the default hand-stub backend has zero third-party dependencies.
|
|
- **No native dependency**: FASM (`reference/fasm/`, `ManagedFasm`) is not referenced. It remains historical reference only, consistent with `FASM-MIGRATION.md`.
|
|
- **No changes** to BlackMagic, MemorySharp, GreyMagic, or their tests — WhiteMagic reuses their ideas, not their assemblies.
|
|
- **Platform**: builds x86 and x64; target bitness stays x86 to match the reference application, but the library is bitness-agnostic.
|