- PeHeaderParser: split export forwarders on the FIRST dot (IndexOf), not the
last. A forwarder is "Module.Function" and the module name has no extension, so
the last-dot split misparsed export names that themselves contain a dot.
- PeHeaderParser: document that API-set (api-ms-win-*/ext-ms-*) and ordinal
forwarders are unsupported and should be resolved via the OS loader.
- RemoteFunction.CreateDelegate now throws InvalidOperationException unless the
session is in-process; an external target's address is not host-mapped and a
delegate to it would access-violate on invocation. Tests cover both paths.
- Reword the SSE-payload comment: the 16-byte scratch sits below the saved
return address, which the aligned store leaves intact (it never overwrote it).
Tests: 223 passing, 4 skipped.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Task 7.2: export resolution + module/function facade.
- PeHeaderParser.GetExportAddress walks the PE32/PE32+ export directory and
follows export forwarders (e.g. kernel32!HeapAlloc -> NTDLL.RtlAllocateHeap)
into other loaded modules; ordinal and unresolvable API-set forwarders throw
NotSupportedException.
- RemoteModule resolves a module base via Process.Modules (name match tolerant
of .dll/case); RemoteFunction executes via RemoteThreadExecutor by default,
exposes Address for pump routing and CreateDelegate<T> for in-process.
- Magic gains a string indexer: magic["user32"]["MessageBoxA"].
Task 3.8: add the missing live-execution ABI test - an SSE callee whose aligned
movaps #GPs unless the stub delivers a 16-byte-aligned stack, combined with a
5th stack argument. Runtime-proves shadow space, alignment, and arg placement.
Tests: 214 passing, 4 skipped.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A non-faulting probe payload returns (rsp+8)&15 from the callee, which is 0
only when the stub delivers callee entry rsp ≡ 8 (mod 16) per the Microsoft
x64 ABI. Proves the stub frame alignment end-to-end through CreateRemoteThread
without risking a #GP that would crash the in-process test host. Verified to
fail against the old fixed-0x20 frame.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Add RemoteAllocator / RemoteReleaser internal test seams for string/struct scratch memory.
- Route all scratch allocation/freeing through the seams so tests can observe leaks.
- Fix inverted StubAllocator ownership: a caller-provided stub is now never freed by the executor.
- Rewrite Execute_releases_allocated_remote_memory_on_write_failure to fail pre-fix by tracking fake allocations through the seams.
- Update WriteFailingMemoryBase to carry a valid self-handle so the executor reaches the marshal/write path.
Tests: 198 passing, 4 integration/interactive 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.