Add runtime x64 stack-alignment regression test
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>
This commit is contained in:
@@ -56,6 +56,15 @@ public sealed class RemoteThreadExecutorTests
|
||||
// ret
|
||||
private static readonly byte[] PointSumPayload = [0x8B, 0x01, 0x03, 0x41, 0x04, 0xC3];
|
||||
|
||||
// Measures the callee's entry stack alignment without faulting.
|
||||
// mov eax, esp
|
||||
// add eax, 8
|
||||
// and eax, 0x0F
|
||||
// ret
|
||||
// Returns (rsp + 8) & 15, which is 0 iff callee entry rsp ≡ 8 (mod 16) — the
|
||||
// Microsoft x64 ABI guarantee the stub must deliver.
|
||||
private static readonly byte[] AlignProbePayload = [0x89, 0xE0, 0x83, 0xC0, 0x08, 0x83, 0xE0, 0x0F, 0xC3];
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
private struct Point
|
||||
{
|
||||
@@ -87,6 +96,20 @@ public sealed class RemoteThreadExecutorTests
|
||||
Assert.Equal(15, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Execute_delivers_16byte_aligned_stack_to_callee()
|
||||
{
|
||||
if (!Environment.Is64BitProcess)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Stub entry rsp ≡ 8 → sub rsp, K (K ≡ 8) → rsp ≡ 0 → call → callee entry rsp ≡ 8.
|
||||
// So (rsp + 8) & 15 == 0 when the frame math is right; a bad K (e.g. 0x20) yields 8.
|
||||
int misalign = RunPayload(AlignProbePayload, CallConvention.Cdecl);
|
||||
Assert.Equal(0, misalign);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Execute_marshals_string_as_utf8_pointer()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user