Files
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

3.8 KiB

1. Memory-region query (spec: memory-region)

  • 1.1 Add VirtualQueryEx LibraryImport and MEMORY_BASIC_INFORMATION to Native/ (32/64-bit-correct layout)
  • 1.2 Add tests for MemoryRegion.Contains (in-range true, boundary [base, base+size), out-of-range false)
  • 1.3 Implement WhiteMagic/Memory/MemoryRegion.cs (immutable: BaseAddress, Size, Protection, State, Type, AllocationBase, AllocationProtect, Contains) to pass 1.2
  • 1.4 Add tests for MemoryBase.QueryRegion(address) against a known committed address in the current process
  • 1.5 Implement QueryRegion to pass 1.4
  • 1.6 Add tests for EnumerateRegions(): ascending non-overlapping bases, lazy (early stop does not walk whole space — assert via a bounded take)
  • 1.7 Implement lazy EnumerateRegions() (walk base+size until VirtualQueryEx fails) to pass 1.6
  • 1.8 Add tests for ChangeProtection/ProtectionScope: protection applied in scope, restored on dispose, restored on exception
  • 1.9 Implement MemoryBase.ChangeProtection returning ProtectionScope : IDisposable to pass 1.8

2. Thread control (spec: thread-control)

  • 2.1 Add CreateToolhelp32Snapshot/Thread32First/Thread32Next + THREADENTRY32, and GetThreadTimes, to Native/ (reuse existing OpenThread/Suspend/Resume/Get/SetThreadContext)
  • 2.2 Add tests for RemoteThread: open by id, Suspend returns prior count and stops the thread, Resume restarts it (self-process worker thread)
  • 2.3 Implement WhiteMagic/Thread/RemoteThread.cs (OpenThread → SafeMemoryHandle, Suspend/Resume, Id) to pass 2.2
  • 2.4 Add tests for GetContext/SetContext round-trip on a suspended self-thread; assert WOW64 vs native selection by target bitness
  • 2.5 Implement context read/write reusing DllInjector's bitness selection to pass 2.4
  • 2.6 Add tests + implement RemoteThread.GetTeb() (via NtQueryInformationThread/ThreadBasicInformationManagedTeb)
  • 2.7 Add tests for ThreadFactory: Enumerate() returns only target threads, MainThread = earliest-created, GetThreadById
  • 2.8 Implement WhiteMagic/Thread/ThreadFactory.cs (toolhelp walk filtered by PID; GetThreadTimes for main) to pass 2.7
  • 2.9 Add tests for FrozenThread/Freeze(): suspends selected set, dispose resumes exactly those, body-throws still resumes, external suspends untouched
  • 2.10 Implement WhiteMagic/Thread/FrozenThread.cs + ThreadFactory.Freeze(...) (reverse-order resume on dispose) to pass 2.9

3. Process discovery (spec: high-level-api)

  • 3.1 Add tests for ApplicationFinder.Enumerate() and open-by-name against the current process
  • 3.2 Implement WhiteMagic/Process/ApplicationFinder.cs (Process.GetProcessesByName; window-title/handle via existing WindowFactory + GetWindowThreadProcessId)
  • 3.3 Add tests for ambiguous-match rejection (multiple candidates → throws with candidate list) and open-by-window-handle
  • 3.4 Add Magic.Open(string processName), Magic.OpenByWindowTitle(string), Magic.OpenByWindowHandle(IntPtr) overloads delegating to ApplicationFinder; add tests
  • 3.5 Wire new surface into the Magic facade (expose Threads factory and Regions/QueryRegion accessors) and document freeze-while-executing deadlock caveat in XML docs

4. Verification

  • 4.1 Run full test suite: dotnet test WhiteMagicTest/WhiteMagicTest.csproj — all pass
  • 4.2 Run full build (dotnet build WhiteMagic.slnx) — zero errors, zero new warnings in WhiteMagic
  • 4.3 Update docs/memory-library-comparison.md — mark thread-control, memory-region, and process-discovery gaps closed; note WhiteMagic is now a superset of MemorySharp's public surface (or list any remaining minor helpers deliberately skipped)
  • 4.4 openspec validate add-thread-region-finder --strict passes