using System.Diagnostics; using System.Runtime.InteropServices; using WhiteMagic; using WhiteMagic.Native; namespace WhiteMagicTest; /// /// Tests for relative/absolute addressing in . /// public class AddressingTests { private static ExternalReader OpenSelf() { return new ExternalReader( Process.GetCurrentProcess(), ProcessAccess.VmRead | ProcessAccess.VmWrite | ProcessAccess.VmOperation | ProcessAccess.QueryInformation); } [Fact] public void GetAbsolute_resolves_relative_offset() { using var reader = OpenSelf(); IntPtr imageBase = reader.ImageBase; IntPtr result = reader.GetAbsolute((IntPtr)0x1000); Assert.Equal(imageBase + 0x1000, result); } [Fact] public void GetRelative_computes_offset_from_image_base() { using var reader = OpenSelf(); IntPtr imageBase = reader.ImageBase; IntPtr absolute = imageBase + 0x2000; IntPtr relative = reader.GetRelative(absolute); // GetRelative returns ImageBase - absolute (GreyMagic convention) Assert.Equal((IntPtr)((int)imageBase - (int)absolute), relative); } [Fact] public void GetAbsolute_after_GetRelative_at_image_base_returns_to_base() { using var reader = OpenSelf(); IntPtr atBase = reader.ImageBase; IntPtr relative = reader.GetRelative(atBase); IntPtr back = reader.GetAbsolute(relative); Assert.Equal(atBase, back); } [Fact] public void Read_with_isRelative_true_uses_image_base() { using var reader = OpenSelf(); // Read the first byte at ImageBase (should be MZ header: 0x4D = 'M') byte firstByte = reader.Read(IntPtr.Zero, isRelative: true); Assert.Equal(0x4D, firstByte); } [Fact] public void Write_with_isRelative_true_resolves_correctly() { using var reader = OpenSelf(); int slot = 0; GCHandle pin = GCHandle.Alloc(slot, GCHandleType.Pinned); try { IntPtr absolute = pin.AddrOfPinnedObject(); nint relative = (nint)absolute - (nint)reader.ImageBase; IntPtr relativePtr = (IntPtr)relative; Assert.True(reader.Write(relativePtr, 42, isRelative: true)); Assert.Equal(42, reader.Read(absolute)); } finally { pin.Free(); } } [Fact] public void ReadBytes_with_isRelative_true_resolves_correctly() { using var reader = OpenSelf(); // DOS header 'MZ' at the image base byte[] data = reader.ReadBytes(IntPtr.Zero, 2, isRelative: true); Assert.Equal(0x4D, data[0]); Assert.Equal(0x5A, data[1]); } }