- AllocatedMemory.Read<T>/Write<T>/ReadBytes/WriteBytes now validate that
the requested byte range stays within the allocated block before calling
into the memory accessor.
- Patch.Apply/Remove temporarily changes the target page to read-write and
restores the original protection, mirroring the Detour behavior.
- MainThreadPump.WorkItem uses TrySetResult/TrySetException and swallows the
InvalidOperationException raised when a completion source is already
completed, preventing Dispose from failing during concurrent pump drainage.
Regression tests added for all three fixes.
Tests: 206 passing, 4 skipped.
- MainThreadDispatcher: guard DispatchHook with try/catch so exceptions never escape to native caller; drain and fault pending work on Dispose; synchronize Execute/ExecuteAsync/Dispose against race/dispose.
- InstructionAnalyzer: require ModRM 0xEC for 0x83/0x81 sub-esp/rsp forms, rejecting unsafe RIP-relative or memory forms.
- PatternScannerCache: implement value equality on CacheKey so repeated scans actually hit cache.
- BackgroundTaskExecutor: add remote allocations to the free list immediately after VirtualAllocEx, before any write that could fail and leak.
- redirect: capture and restore original page protection in Apply/Remove instead of leaving target RWX.
- Regression tests for all six fixes.
Tests: 198 passing, 4 integration/interactive skipped.