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

58 lines
2.4 KiB
Markdown

## 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