Files
whitemagic/WhiteMagic.Examples/README.md
T
kbe 6300bebe33 Fix API documentation and examples; add comprehensive documentation suite
- 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.
2026-07-22 22:26:07 +02:00

7.7 KiB

WhiteMagic Examples

This directory contains comprehensive examples demonstrating all major features of the WhiteMagic library.

Prerequisites

  • Target Process: Most examples use Notepad as the target. Launch Notepad before running the examples.
  • Administrator Privileges: Some operations require elevated privileges. Run Visual Studio or terminal as Administrator.
  • .NET 8.0 SDK: Ensure you have .NET 8.0 installed.

Running the Examples

From Visual Studio

  1. Open WhiteMagic.slnx in Visual Studio
  2. Set WhiteMagic.Examples as the startup project
  3. Press F5 to run

From Command Line

# Navigate to the examples directory
cd WhiteMagic.Examples

# Run the examples
dotnet run

Example Categories

1. Basic Memory Operations (Example1_BasicMemoryOperations.cs)

Demonstrates:

  • Reading and writing primitive types (int, float, double, bool)
  • Reading and writing arrays
  • Reading and writing strings (ANSI and Unicode)
  • Reading and writing raw bytes
  • Using RemotePointer for fluent pointer arithmetic
  • Relative addressing (module-relative offsets)
  • Error handling for memory operations
  • Working with custom structs

Key Takeaways:

  • All memory operations go through the Magic.Memory API
  • Use RemotePointer for clean, fluent pointer arithmetic
  • Reads throw exceptions on failure; writes return false
  • Prefer blittable types for best performance

2. Pattern Scanning (Example2_PatternScanning.cs)

Demonstrates:

  • Simple pattern scans with wildcards
  • Multiple pattern scans in one operation
  • Region-specific scanning (e.g., .text section only)
  • Finding function signatures
  • Cached pattern scanning for performance
  • Flexible wildcard patterns
  • Signature-based scanning (code caves, NOPs, INT3s)
  • Pattern validation

Key Takeaways:

  • Use IDA-style patterns: "48 8B ? ? ? ? ?" where ? is a wildcard
  • Cache results for repeated scans
  • Narrow search region when possible for better performance

3. Execution Models (Example3_ExecutionModels.cs)

Demonstrates:

  • RemoteThreadExecutor: CreateRemoteThread for thread-agnostic calls
  • MainThreadPump: Crash-safe execution for state-sensitive calls
  • InProcessInvoker: Direct delegates for in-process calls
  • Choosing the right execution model
  • Combining execution models (inject then switch)
  • Error handling for each model

Key Takeaways:

  • CRITICAL: Use the right model for the payload:
    • RemoteThreadExecutor: Only for thread-agnostic functions (WinAPI, DLL injection)
    • MainThreadPump: For state-sensitive calls (game state, scripting, UI)
    • InProcessInvoker: Only after DLL injection
  • Using the wrong model crashes the target application

4. Function Hooking (Example4_FunctionHooking.cs)

Demonstrates:

  • Inline Detours: Function hooking with trampolines
  • Detours with parameter modification
  • Detours with return value modification
  • Multiple detours (chain hooking)
  • Byte Patching: Named byte patches
  • NOP patching (removing instructions)
  • Conditional patching (toggle on/off)
  • Prologue validation and safety
  • Automatic restoration on disposal

Key Takeaways:

  • Detours ONLY work in-process (requires DLL injection)
  • Patches work externally (no injection required)
  • DetourManager/PatchManager are NOT thread-safe
  • All hooks and patches auto-restore on disposal

5. High-Level API (Example5_HighLevelAPI.cs)

Demonstrates:

  • RemotePointer: Fluent pointer arithmetic with [] indexing
  • RemoteModule: Module enumeration and export resolution
  • RemoteFunction: Function resolution and execution
  • ManagedPeb/ManagedTeb: Typed PEB/TEB access
  • RemoteWindow: Window manipulation (move, resize, flash, activate)
  • Memory allocation and freeing
  • Module pattern scanning
  • Export function iteration
  • Chaining high-level operations

Key Takeaways:

  • Use high-level APIs for cleaner, more readable code
  • magic["ModuleName"] returns a RemoteModule
  • module["FunctionName"] returns a RemoteFunction
  • All high-level operations are built on top of the core memory API

Common Patterns

Reading a Nested Structure

// GameManager -> PlayerList -> Player[i] -> Health
IntPtr gameManagerPtr = magic.Memory.ImageBase + 0x1000;
IntPtr playerListPtr = magic.Memory.Read<IntPtr>(gameManagerPtr + 0x20);
IntPtr playerPtr = magic.Memory.Read<IntPtr>(playerListPtr + (playerIndex * 8));
int health = magic.Memory.Read<int>(playerPtr + 0x4);

Using RemotePointer for Cleaner Code

int health = magic[gameManagerPtr]
    .Read<IntPtr>(0x20)        // PlayerList
    .Let(ptr => magic[ptr]
        .Read<IntPtr>(playerIndex * 8))  // Player
    .Let(ptr => magic[ptr]
        .Read<int>(0x4));      // Health

Safe Retry Loop for Writes

for (int i = 0; i < 5; i++)
{
    if (magic.Memory.Write(address, value))
        break;
    Thread.Sleep(100 * (1 << i)); // Exponential backoff
}

Crash-Safe State Access

// WRONG (crashes in most games)
int health = magic.RemoteThread.Execute<int>(fn, CallConvention.Cdecl);

// RIGHT (crash-safe)
var pump = magic.CreateMainThreadPump(frameAddress);
int health = await pump.Enqueue(() => magic.Memory.Read<int>(healthAddress));

Troubleshooting

"Process is not open for read/write"

Cause: Process has exited or handle is invalid

Solution: Ensure process is still running and handle is valid

"Read returns default value"

Cause: Address is invalid or memory is protected

Solution: Verify address with debugger; check memory protection

"Write returns false"

Cause: Memory is read-only or process has exited

Solution: Retry with delay; use PatchManager for code patches

"CreateRemoteThread failed"

Cause: Insufficient permissions or target is protected

Solution: Run as Administrator; check target process protection

"Crash when calling target function"

Cause: Calling single-threaded function from remote thread

Solution: Use MainThreadPump instead of RemoteThreadExecutor

"Detour failed: prologue too short"

Cause: Function prologue is shorter than minimum (5 bytes)

Solution: Hook different function; patch deeper into function

Further Reading

Safety Reminders

⚠️ CRITICAL WARNINGS:

  1. Execution Model Choice:

    • RemoteThreadExecutor: ONLY for thread-agnostic functions
    • MainThreadPump: For state-sensitive calls (crash-safe)
    • InProcessInvoker: Only after DLL injection
    • Using the wrong model crashes the target application!
  2. Detours vs Patches:

    • Detours ONLY work in-process (requires injection)
    • Patches work externally (no injection required)
  3. Thread Safety:

    • DetourManager/PatchManager are NOT thread-safe
    • Synchronize concurrent modifications
  4. Handle Management:

    • Always use using statements or dispose Magic properly
    • Leaked handles can cause resource exhaustion
  5. Anti-Cheat Detection:

    • Some operations (e.g., CreateRemoteThread) are easily detected
    • Use MainThreadPump for stealthier operation

Contributing

Found a bug or have a suggestion? Please open an issue on GitHub.

License

These examples are part of the WhiteMagic project. See the main LICENSE file for details.