8.1 KiB
8.1 KiB
1. Project Setup
- 1.1 Create
WhiteMagic/WhiteMagic.csprojtargetingnet8.0-windows,AllowUnsafeBlocks=true, nullable enabled,TreatWarningsAsErrors,Platforms=x86;x64;AnyCPU - 1.2 Create
WhiteMagicTest/WhiteMagicTest.csproj(xUnit,net8.0-windows) referencingWhiteMagic - 1.3 Create
WhiteMagic.slnx(SDK 10 default solution format) and add both projects. (Built on SDK 10;net8.0-windowstargeting pack auto-restored.) - 1.4 Add
WhiteMagic/Native/P/Invoke surface (LibraryImport): OpenProcess, Read/WriteProcessMemory, VirtualAllocEx/FreeEx/ProtectEx, CreateRemoteThread, Wow64Get/SetThreadContext, Get/SetThreadContext, LoadLibrary, GetProcAddress; addSafeMemoryHandle - 1.5 Verify empty projects build:
dotnet build WhiteMagic.slnx— zero errors, zero warnings
2. Core Memory Access (spec: memory-access)
- 2.1 Add tests for
MarshalCache<T>: blittable size, marshal-required flag, IsIntPtr, computed-once behavior - 2.2 Implement
WhiteMagic/MarshalCache.csto pass 2.1 - 2.3 Add tests for
MemoryBaseabstract contract +ExternalReaderround-trip (Read<T>/Write<T>, arrays) using the current process as target - 2.4 Implement
WhiteMagic/MemoryBase.cs(abstract) andWhiteMagic/ExternalReader.csto pass 2.3 - 2.5 Add tests for string read/write with encoding, null-terminator stop, and max length
- 2.6 Implement
ReadString/WriteStringonMemoryBaseto pass 2.5 - 2.7 Add tests for relative/absolute addressing (
GetAbsolute/GetRelative,isRelativeflag) - 2.8 Implement addressing helpers to pass 2.7
- 2.9 Add tests + implementation for
InProcessReader(RPM/WPM on a self-handle — see D1 deviation note; direct deref rejected because .NET cannot catchAccessViolationException); verify sharedMemoryBaseAPI works for both readers - 2.10 Follow-up (found in review):
ReadStringscans for the null terminator byte-by-byte, so for UTF-16/UTF-32 it can match a misaligned multi-byte null across a char boundary (e.g."A"+U+4200 =41 00 00 42matches{00,00}at offset 1) and can miss a terminator split across the 64-byte chunk boundary. Harmless for ASCII/UTF-8 (single-byte encodings). Fix: align the scan to the encoding's code-unit width and carry the last(nullLen-1)bytes across chunks. Add a UTF-16 test.
3. Managed Assembler (spec: managed-assembler)
- 3.1 Add tests for
EmitU8/EmitU32/EmitU64little-endian primitives - 3.2 Implement
WhiteMagic/Assembly/StubAssembler.csemitters +IAssemblerinterface to pass 3.1 - 3.3 Add tests for x86 cdecl stub encoding (reverse push, call,
add esp, N*4, ret) with known byte expectations - 3.4 Implement x86 cdecl stub to pass 3.3
- 3.5 Add tests for stdcall (no caller cleanup), thiscall (ecx = this), fastcall (ecx/edx) x86 stubs
- 3.6 Implement x86 stdcall/thiscall/fastcall stubs to pass 3.5
- 3.7 Add tests for x64 stub argument-register placement and call
- 3.8 Implement x64 stub to pass 3.7
- 3.9 Confirm no FASM/
ManagedFasmreference exists inWhiteMagicoutput (assert via a test that scans loaded references)
4. Crash-Safe Execution Slice (spec: remote-execution, function-hooking)
- 4.1 Add tests for
PatchManager/Patch: apply writes bytes, remove restores original,IsAppliedreflects state - 4.2 Implement
WhiteMagic/Hooking/PatchManager.cs+Patch.csto pass 4.1 - 4.3 Add tests for
DetourManager/Detourin-process: apply redirects,CallOriginal, remove restores, named lookup - 4.4 Implement
WhiteMagic/Hooking/DetourManager.cs+Detour.cs(inline jmp, x86/x64 form) to pass 4.3 - 4.5 Add tests for instruction-boundary validation (aligned splice permitted, misaligned rejected when boundary info available)
- 4.6 Implement minimal prologue length-decoder in
Detour.Applyto pass 4.5. DefaultStubAssemblercovers ONLY the common x86/x64 prologue shapes — enumerate the covered opcodes in code + XML doc (e.g.push reg0x50-0x57,mov edi,edi8B FF,push ebp/mov ebp,esp55 8B EC,sub esp,imm83 EC / 81 EC, REX-prefixed forms). On any opcode outside the set, refuse the splice (do not guess). Full arbitrary-prologue validation is gated on the optional Iced backend (task 8.3) — document that slices 2-5 ship partial boundary safety. - 4.7 Add tests for auto-restore: disposing a
MemoryBasereverts all active patches and detours - 4.8 Wire manager registration +
MemoryBase.Disposerestore to pass 4.7 - 4.9 Add tests for
MainThreadPumpqueue semantics: item runs on hooked thread, result returned, throwing item surfaces exception and pump survives, dispose uninstalls hook (use a self-hosted frame-loop harness in-process) - 4.10 Implement
WhiteMagic/Execution/MainThreadPump.cs(frame-function detour + thread-safe work queue + completion handles) to pass 4.9 - 4.11 Add tests for
RemoteThreadExecutor.Execute<T>(convention stub + wait + typed exit; no-process failure is deterministic) - 4.12 Implement
WhiteMagic/Execution/RemoteThreadExecutor.csand parameter marshalling (string/struct → remote alloc → free) to pass 4.11
5. Injection & Discovery (spec: dll-injection, memory-discovery)
- 5.1 Add tests for pattern scanning: found (range/module/all-modules), wildcard mask, not-found returns Zero
- 5.2 Implement
WhiteMagic/Discovery/PatternScanner.csto pass 5.1 - 5.3 Add tests + implement scan result cache (repeat served from cache, clear rescans)
- 5.4 Add tests + implement
WhiteMagic/Discovery/PeHeaderParser.cs(sections, entry point) - 5.5 Add tests + implement
WhiteMagic/Memory/AllocatedMemory.cs(named regions, typed read/write by name, address by name, free on dispose) - 5.6 Add tests + implement raw code injection (
InjectCodeat address and into fresh allocation) - 5.7 Add tests + implement DLL injection via remote thread (LoadLibrary), including bitness-mismatch and missing-file failures
- 5.8 Add tests + implement DLL injection via thread-hijack (save/redirect/restore context) with x86 and x64 stubs
6. In-Process Tier (spec: remote-execution)
- 6.1 Add tests for
InProcessInvoker.CreateFunction<TDelegate>calling a known in-process function directly - 6.2 Implement
WhiteMagic/Execution/InProcessInvoker.cs(Marshal.GetDelegateForFunctionPointer) + vtable-entry helper to pass 6.1 - 6.3 Document that the CLR-host managed loader (injecting
InProcessReaderinto a foreign process) is a separate follow-up change
7. High-Level Ergonomics (spec: high-level-api)
- 7.1 Add tests + implement
RemotePointerindexer (sharp[addr].Read/Write/Executerelative to base) - 7.2 Add tests + implement
RemoteModule/RemoteFunction(sharp["mod"]["fn"]) resolving export addresses and executing via a chosen strategy - 7.3 Add tests + implement
ManagedPeb/ManagedTebfield reads - 7.4 Add tests + implement
WindowFactory/RemoteWindow(enumerate, move/resize/title/activate/flash, query by class) - 7.5 Add tests + implement keyboard/mouse simulation (PostMessage + SendInput) to a target window
- 7.6 Add tests + implement
Task-based async execution wrappers over the executors and pump - 7.7 Add minimal facade (
WhiteMagicentry type) exposingOpen, readers, executors, managers, and the indexer
8. Optional Iced Backend (spec: managed-assembler)
- 8.1 Add
Icedpackage reference behind anIcedAssembler : IAssemblerin a way that keeps the defaultStubAssemblerdependency-free - 8.2 Add tests + implement
IcedAssembler.Assemble(text, origin)for arbitrary mnemonics and origin-relative encoding - 8.3 Add tests + wire full prologue instruction-boundary validation (D5) using the Iced disassembler when present
9. Verification
- 9.1 Run full test suite:
dotnet test WhiteMagicTest/WhiteMagicTest.csproj— all pass - 9.2 Run full build (
dotnet build WhiteMagic.slnx) — zero errors, zero new warnings inWhiteMagic - 9.3 Confirm existing BlackMagic/its tests are unchanged and still green
- 9.4 Update
docs/memory-library-comparison.md"WhiteMagic — synthesis" section with any deviations discovered during implementation