using System;
using ProcessNET.Native.Types;
using ProcessNET.Utilities;
namespace ProcessNET.Memory
{
///
/// Class providing tools for manipulating memory protection.
///
public class MemoryProtection : IDisposable
{
protected readonly SafeMemoryHandle Handle;
private bool isDisposed = false;
///
/// Initializes a new instance of the class.
///
/// The reference of the object.
/// The base address of the memory to change the protection.
/// The size of the memory to change.
/// The new protection to apply.
/// The resource will be automatically disposed when the finalizer collects the object.
public MemoryProtection(SafeMemoryHandle handle, IntPtr baseAddress, int size,
MemoryProtectionFlags protection = MemoryProtectionFlags.ExecuteReadWrite,
bool mustBeDisposed = true)
{
// Save the parameters
Handle = handle;
BaseAddress = baseAddress;
NewProtection = protection;
Size = size;
MustBeDisposed = mustBeDisposed;
// Change the memory protection
OldProtection = MemoryHelper.ChangeProtection(Handle, baseAddress, size, protection);
}
///
/// The base address of the altered memory.
///
public IntPtr BaseAddress { get; }
///
/// States if the object nust be disposed when it is collected.
///
public bool MustBeDisposed { get; set; }
///
/// Defines the new protection applied to the memory.
///
public MemoryProtectionFlags NewProtection { get; }
///
/// References the inital protection of the memory.
///
public MemoryProtectionFlags OldProtection { get; }
///
/// The size of the altered memory.
///
public int Size { get; }
///
/// Restores the initial protection of the memory.
///
public virtual void Dispose()
{
if (isDisposed)
return;
isDisposed = true;
// Restore the memory protection
MemoryHelper.ChangeProtection(Handle, BaseAddress, Size, OldProtection);
// Avoid the finalizer
GC.SuppressFinalize(this);
}
///
/// Frees resources and perform other cleanup operations before it is reclaimed by garbage collection.
///
~MemoryProtection()
{
if (MustBeDisposed)
Dispose();
}
///
/// Returns a string that represents the current object.
///
public override string ToString()
{
return
$"BaseAddress = 0x{BaseAddress.ToInt64():X} NewProtection = {NewProtection} OldProtection = {OldProtection}";
}
}
}