Address review: forwarder split, CreateDelegate guard, API-set docs

- 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>
This commit is contained in:
kbe
2026-07-22 09:22:29 +02:00
co-authored by Claude Opus 4.8
parent 30d5a9a5ec
commit 0ddd812829
4 changed files with 54 additions and 4 deletions
+12 -1
View File
@@ -53,10 +53,21 @@ public sealed class RemoteFunction
/// <summary>
/// Creates a managed delegate bound to this function for the in-process scenario.
/// Only valid when the session was opened in-process.
/// </summary>
/// <exception cref="InvalidOperationException">The session is not in-process. The
/// resolved <see cref="Address"/> lives in the target process; a delegate to it would
/// access-violate when invoked from the host, so this is rejected for external sessions.
/// Use <see cref="Execute{T}"/> (remote thread) for external targets.</exception>
public TDelegate CreateDelegate<TDelegate>() where TDelegate : Delegate
{
if (_magic.Memory is not InProcessReader)
{
throw new InvalidOperationException(
"CreateDelegate is only valid for an in-process session (Magic.OpenInProcess). " +
"The function address is not mapped into the host process for an external target; " +
"use Execute<T> to call it via a remote thread.");
}
return new InProcessInvoker(_magic.Memory).CreateFunction<TDelegate>(Address);
}
}