Implements VirtualQueryEx + MEMORY_BASIC_INFORMATION wrappers, the immutable MemoryRegion record, the ProtectionScope disposable helper, and MemoryBase.QueryRegion/EnumerateRegions/ChangeProtection. Closes section 1 of add-thread-region-finder.
76 lines
2.4 KiB
C#
76 lines
2.4 KiB
C#
using System;
|
|
using WhiteMagic.Native;
|
|
|
|
namespace WhiteMagic.Memory;
|
|
|
|
/// <summary>
|
|
/// An immutable snapshot of a memory region as reported by <c>VirtualQueryEx</c>.
|
|
/// </summary>
|
|
public readonly record struct MemoryRegion
|
|
{
|
|
/// <summary>The base address of the region of pages.</summary>
|
|
public IntPtr BaseAddress { get; }
|
|
|
|
/// <summary>The size of the region, in bytes.</summary>
|
|
public nuint Size { get; }
|
|
|
|
/// <summary>The access protection of the pages in the region.</summary>
|
|
public MemoryProtectionType Protection { get; }
|
|
|
|
/// <summary>The state of the pages in the region.</summary>
|
|
public MemoryState State { get; }
|
|
|
|
/// <summary>The type of pages in the region.</summary>
|
|
public MemoryType Type { get; }
|
|
|
|
/// <summary>The base address of a range of pages allocated by VirtualAllocEx.</summary>
|
|
public IntPtr AllocationBase { get; }
|
|
|
|
/// <summary>The memory protection option when the region was initially allocated.</summary>
|
|
public MemoryProtectionType AllocationProtect { get; }
|
|
|
|
/// <summary>
|
|
/// Initializes a new <see cref="MemoryRegion"/> from explicit values.
|
|
/// </summary>
|
|
public MemoryRegion(
|
|
IntPtr baseAddress,
|
|
nuint size,
|
|
MemoryProtectionType protection,
|
|
MemoryState state,
|
|
MemoryType type,
|
|
IntPtr allocationBase,
|
|
MemoryProtectionType allocationProtect)
|
|
{
|
|
BaseAddress = baseAddress;
|
|
Size = size;
|
|
Protection = protection;
|
|
State = state;
|
|
Type = type;
|
|
AllocationBase = allocationBase;
|
|
AllocationProtect = allocationProtect;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes a new <see cref="MemoryRegion"/> from a raw <c>MEMORY_BASIC_INFORMATION</c>.
|
|
/// </summary>
|
|
internal MemoryRegion(MemoryBasicInformation info)
|
|
{
|
|
BaseAddress = info.BaseAddress;
|
|
Size = info.RegionSize;
|
|
AllocationBase = info.AllocationBase;
|
|
AllocationProtect = (MemoryProtectionType)info.AllocationProtect;
|
|
Protection = (MemoryProtectionType)info.Protect;
|
|
State = (MemoryState)info.State;
|
|
Type = (MemoryType)info.Type;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns <see langword="true"/> if <paramref name="address"/> is inside the region,
|
|
/// defined as <c>[BaseAddress, BaseAddress + Size)</c>.
|
|
/// </summary>
|
|
public bool Contains(IntPtr address)
|
|
{
|
|
return (nuint)(address - BaseAddress) < Size;
|
|
}
|
|
}
|