Initial commit
This commit is contained in:
@@ -0,0 +1,103 @@
|
||||
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]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user