Files
whitemagic/openspec/changes/whitemagic-foundation/specs/memory-discovery/spec.md
T
2026-07-21 22:30:10 +02:00

2.4 KiB

ADDED Requirements

Requirement: Pattern scanning with mask

WhiteMagic SHALL scan process memory for a byte signature with a wildcard mask, returning the address of the first match or IntPtr.Zero when no match is found. Scans SHALL be available over an explicit range, a single module, and all modules.

Scenario: pattern found

  • WHEN a known byte sequence is scanned for with a matching mask over a range containing it
  • THEN the returned address MUST point at the first occurrence

Scenario: wildcard mask

  • WHEN the mask marks positions as wildcards (e.g. "xx?x")
  • THEN those byte positions MUST be ignored during matching

Scenario: pattern not found

  • WHEN a pattern absent from the range is scanned for
  • THEN the result MUST be IntPtr.Zero

Requirement: Pattern scan cache

The scanner SHALL cache resolved pattern results keyed by pattern and mask, returning the cached address on repeat lookups, and SHALL expose an operation to clear the cache.

Scenario: repeat lookup served from cache

  • WHEN the same pattern and mask are scanned twice without clearing the cache
  • THEN the second lookup MUST return the same address without rescanning memory

Scenario: cache cleared

  • WHEN the cache is cleared
  • THEN the next lookup MUST rescan memory

Requirement: PE header parsing

WhiteMagic SHALL parse the PE headers of a module to expose its sections and entry point without executing the module.

Scenario: sections enumerated

  • WHEN a valid PE module is parsed
  • THEN its section names, virtual addresses, and sizes MUST be enumerable

Scenario: entry point located

  • WHEN a valid PE module is parsed
  • THEN the parsed entry-point RVA MUST match the module's header

Requirement: Named remote allocation

WhiteMagic SHALL allocate a chunk of remote memory subdivided into named regions, allowing typed read/write and address lookup by name, and freeing the whole chunk on dispose.

Scenario: write and read by name

  • WHEN a named region is allocated and Write<int>("count", 5) then Read<int>("count") is called
  • THEN the result MUST equal 5

Scenario: address by name

  • WHEN a region named "buffer" is allocated
  • THEN requesting its address MUST return chunkBase + regionOffset

Scenario: freed on dispose

  • WHEN the allocation is disposed
  • THEN the underlying remote memory MUST be released