- Example5: Fix format string bugs (alignment specifier placement, SafeMemoryHandle formatting) - Example4: Fix DetourManager.Detour() → Create() in all doc strings - Example3: Fix MemoryBase.CreateFunction() → InProcessInvoker.CreateFunction() in doc strings - Examples 1-5: Correct all runtime errors and API mismatches vs actual WhiteMagic API - README: Fix DetourManager.Detour() examples to use Create(); add missing code fence markers - Add WhiteMagic.Examples project with 5 comprehensive example files (40+ sub-examples) - Add docfx.json and toc.md for DocFX API reference generation - Add 5 conceptual guides: architecture, memory-access, execution-models, hooking, troubleshooting - Ensure zero errors, zero warnings across all projects (net8.0-windows) Doc strings now teach correct APIs; runtime format bugs eliminated; build succeeds.
191 lines
6.4 KiB
Markdown
191 lines
6.4 KiB
Markdown
# WhiteMagic
|
|
|
|
WhiteMagic is a .NET 8 process-introspection library for Windows that provides managed wrappers over Win32 debugging APIs. It enables reading/writing memory, executing code remotely, hooking functions, and injecting DLLs into target processes.
|
|
|
|
## Overview
|
|
|
|
WhiteMagic is designed for diagnostic tools, debuggers, profilers, and automation clients that need to attach to and manipulate desktop applications. It unifies the best features from four legacy libraries (BlackMagic, MemorySharp, GreyMagic, and BlackMagic-old) into a modern, bitness-agnostic .NET 8 library with a crash-safe execution model.
|
|
|
|
## Key Features
|
|
|
|
- **Dual memory access**: External (ReadProcessMemory/WriteProcessMemory) and in-process readers over an abstract `MemoryBase`
|
|
- **Three-tier execution model**: Remote thread, crash-safe main-thread pump, and in-process delegates
|
|
- **Function hooking**: Reversible inline detours (`DetourManager`) and named byte patches (`PatchManager`) with auto-restore on dispose
|
|
- **Pattern scanning**: Memory pattern discovery with caching
|
|
- **Assembly seam**: `IAssembler` abstraction with hand-emitted stubs (default) and optional Iced backend
|
|
- **DLL injection**: CreateThread and thread-hijack strategies for x86 and x64
|
|
- **High-level API**: Ergonomic `RemotePointer` indexer, module/function access, PEB/TEB, window mutation, and input simulation
|
|
|
|
## Quick Start
|
|
|
|
### Installation
|
|
|
|
```bash
|
|
dotnet add package WhiteMagic
|
|
```
|
|
|
|
### Basic Memory Read/Write
|
|
|
|
```csharp
|
|
using WhiteMagic;
|
|
using var magic = Magic.Open(Process.GetProcessById(1234));
|
|
|
|
// Read an integer at an address
|
|
int health = magic.Memory.Read<int>(0x12345678);
|
|
|
|
// Write using the RemotePointer indexer
|
|
magic[0x12345678].Write(999);
|
|
|
|
// Read a string
|
|
string name = magic.Memory.ReadString(0x12345680, Encoding.UTF8);
|
|
```
|
|
|
|
### Remote Function Execution
|
|
|
|
```csharp
|
|
using WhiteMagic.Assembly;
|
|
|
|
// Resolve a function by module and export name
|
|
var msgBox = magic["user32"]["MessageBoxA"];
|
|
|
|
// Execute with calling convention and arguments
|
|
int result = msgBox.Execute<int>(
|
|
CallConvention.Stdcall,
|
|
IntPtr.Zero, // hWnd
|
|
"Hello World", // Text
|
|
"Caption", // Caption
|
|
0 // Type
|
|
);
|
|
```
|
|
|
|
### Crash-Safe Execution (Main-Thread Pump)
|
|
|
|
```csharp
|
|
// Create a pump that hooks a per-frame function
|
|
var pump = magic.CreateMainThreadPump(frameAddress);
|
|
|
|
// Enqueue work that runs on the target's main thread
|
|
int result = await pump.ExecuteAsync(() =>
|
|
{
|
|
// Safe to touch target's single-threaded state here
|
|
return magic.Memory.Read<int>(stateAddress);
|
|
});
|
|
```
|
|
|
|
### Function Hooking
|
|
|
|
```csharp
|
|
// Apply an inline detour (in-process only)
|
|
var detour = magic.DetourManager.Create(
|
|
"my_hook",
|
|
targetFunctionAddress,
|
|
myHookDelegate
|
|
);
|
|
|
|
detour.Apply();
|
|
// ... use the hook
|
|
detour.Remove(); // Automatically restored on dispose
|
|
```
|
|
|
|
### Pattern Scanning
|
|
|
|
```csharp
|
|
// Scan for a byte pattern in the target's memory
|
|
byte[] pattern = { 0x48, 0x8B, 0x05, 0x00, 0x00, 0x00, 0x00 };
|
|
string mask = "xxx????";
|
|
IntPtr found = PatternScanner.FindInModule(
|
|
magic.Memory,
|
|
pattern,
|
|
mask,
|
|
process.MainModule
|
|
);
|
|
```
|
|
## Documentation
|
|
|
|
- **API Reference**: See inline XML documentation in your IDE; generate with DocFX
|
|
- **Conceptual Guides**: [docs/](./docs/) directory
|
|
- **Examples**: [WhiteMagic.Examples](./WhiteMagic.Examples/) with 5 comprehensive example files
|
|
- **Architecture**: [openspec/changes/whitemagic-foundation/](./openspec/changes/whitemagic-foundation/)
|
|
|
|
## Execution Models
|
|
|
|
WhiteMagic provides three execution strategies, each designed for specific payload safety requirements:
|
|
|
|
### 1. RemoteThreadExecutor (CreateRemoteThread)
|
|
Use for **thread-agnostic payloads only**:
|
|
- Pure WinAPI calls
|
|
- Self-contained computations
|
|
- DLL injection (`LoadLibrary`)
|
|
|
|
**Avoid** for single-threaded target state (scripting engines, render operations, object traversal).
|
|
|
|
### 2. MainThreadPump (Crash-Safe)
|
|
Use for **state-sensitive calls** that touch the target's main-thread-affinity data:
|
|
- Game state modifications
|
|
- UI interactions
|
|
- Script engine calls
|
|
|
|
### 3. InProcessInvoker (Direct Delegates)
|
|
Use when **injected** into the target process:
|
|
- Direct native-delegate calls via `CreateFunction<T>`
|
|
- Zero thread crossing overhead
|
|
|
|
## Architecture
|
|
|
|
WhiteMagic is built in layers:
|
|
|
|
```
|
|
Magic (high-level facade)
|
|
├── Core: MemoryBase (abstract reader/writer)
|
|
│ ├── ExternalReader (RPM/WPM on target)
|
|
│ └── InProcessReader (in-process delegate access)
|
|
├── Discovery: PatternScanner, PeHeaderParser
|
|
├── Assembly: IAssembler → {StubAssembler | IcedAssembler}
|
|
├── Execution: RemoteThreadExecutor, MainThreadPump, InProcessInvoker
|
|
├── Hooking: DetourManager, PatchManager
|
|
└── High-level: RemotePointer, RemoteModule, RemoteWindow
|
|
```
|
|
|
|
## Platform Support
|
|
|
|
- **Target Framework**: .NET 8.0-windows
|
|
- **Architecture**: x86 and x64 (host and target)
|
|
- **Operating System**: Windows 10+
|
|
- **Dependencies**: None (default); optional Iced NuGet package for arbitrary assembly
|
|
|
|
## Safety
|
|
|
|
- All operations use `SafeMemoryHandle` for proper handle cleanup
|
|
- Detours and patches auto-restore on `Dispose`
|
|
- MainThreadPump prevents crashes from thread-affinity violations
|
|
- Prologue validation before detour splicing (optional Iced backend)
|
|
|
|
## Comparison to Reference Libraries
|
|
|
|
| Library | Platform | Execution | Hooking | Assembler |
|
|
|---------|----------|-----------|---------|-----------|
|
|
| **WhiteMagic** | .NET 8, x86+x64 | 3-tier | ✅ | IAssembler (Iced opt.) |
|
|
| BlackMagic | .NET 8, x86+x64 | Remote thread | ❌ | Hand stubs |
|
|
| MemorySharp | .NET FW, x86 | Remote thread | ❌ | FASM (required) |
|
|
| GreyMagic | .NET FW, x86 | In-process | ✅ | FASM |
|
|
|
|
WhiteMagic is **not a drop-in replacement** for these libraries—it's a modern synthesis with a different API design and a crash-safe execution model.
|
|
|
|
## License
|
|
|
|
[Specify your license here]
|
|
|
|
## Contributing
|
|
|
|
Contributions are welcome! Please read our contributing guidelines (coming soon).
|
|
|
|
## Acknowledgments
|
|
|
|
WhiteMagic builds upon concepts and techniques from:
|
|
- **BlackMagic** (current) — Modern .NET 8 base, x64, pattern scanning, DLL injection
|
|
- **MemorySharp** — High-level ergonomics, PEB/TEB, window/input simulation
|
|
- **GreyMagic** — Dual memory model, detours/patches, marshal cache, in-process delegates
|
|
- **Iced** — Modern x86/x64 assembler (optional backend)
|
|
|
|
See [docs/memory-library-comparison.md](./docs/memory-library-comparison.md) for a detailed analysis.
|