2.4 KiB
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)thenRead<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