Files
2026-07-21 22:30:10 +02:00

104 lines
3.1 KiB
C#

using System.Diagnostics;
using System.Runtime.InteropServices;
using WhiteMagic;
using WhiteMagic.Native;
namespace WhiteMagicTest;
/// <summary>
/// Tests for relative/absolute addressing in <see cref="MemoryBase"/>.
/// GetAbsolute(relative) = ImageBase + relative.
/// GetRelative(absolute) = absolute - ImageBase (inverse of GetAbsolute).
/// </summary>
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_returns_absolute_minus_image_base()
{
using var reader = OpenSelf();
IntPtr imageBase = reader.ImageBase;
IntPtr absolute = imageBase + 0x2000;
IntPtr relative = reader.GetRelative(absolute);
Assert.Equal((IntPtr)((nint)absolute - (nint)imageBase), relative);
}
[Fact]
public void GetAbsolute_and_GetRelative_are_inverses()
{
using var reader = OpenSelf();
IntPtr offset = (IntPtr)0x3000;
// Round-trip: offset -> absolute -> back to offset
IntPtr absolute = reader.GetAbsolute(offset);
IntPtr back = reader.GetRelative(absolute);
Assert.Equal(offset, back);
// Reverse round-trip: absolute -> offset -> back to absolute
IntPtr relative = reader.GetRelative(absolute);
IntPtr absoluteAgain = reader.GetAbsolute(relative);
Assert.Equal(absolute, absoluteAgain);
}
[Fact]
public void GetRelative_on_ImageBase_returns_zero()
{
using var reader = OpenSelf();
IntPtr relative = reader.GetRelative(reader.ImageBase);
Assert.Equal(IntPtr.Zero, relative);
}
[Fact]
public void Read_with_isRelative_true_uses_image_base()
{
using var reader = OpenSelf();
// DOS header 'MZ' at the image base
byte firstByte = reader.Read<byte>(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();
IntPtr relative = reader.GetRelative(absolute);
Assert.True(reader.Write(relative, 42, isRelative: true));
Assert.Equal(42, reader.Read<int>(absolute));
}
finally
{
pin.Free();
}
}
[Fact]
public void ReadBytes_with_isRelative_true_resolves_correctly()
{
using var reader = OpenSelf();
byte[] data = reader.ReadBytes(IntPtr.Zero, 2, isRelative: true);
Assert.Equal(0x4D, data[0]);
Assert.Equal(0x5A, data[1]);
}
}