Added ptrguard to be used whenever ptrs are being used.

This commit is contained in:
cake
2026-01-20 00:24:42 +01:00
parent 367af2c3d0
commit cff866dcc2
4 changed files with 183 additions and 106 deletions

View File

@@ -0,0 +1,55 @@
using System.Runtime.InteropServices;
using static LightlessSync.Utils.PtrGuardMemory;
namespace LightlessSync.Utils
{
public static partial class PtrGuard
{
private const ulong _minLikelyPtr = 0x0000_0001_0000_0000UL;
private const ulong _maxUserPtr = 0x0000_7FFF_FFFF_FFFFUL;
private const ulong _aligmentPtr = 0x7UL;
public static bool LooksLikePtr(nint p)
{
if (p == 0) return false;
var u = (ulong)p;
if (u < _minLikelyPtr) return false;
if (u > _maxUserPtr) return false;
if ((u & _aligmentPtr) != 0) return false;
return true;
}
public static bool TryReadIntPtr(nint addr, out nint value)
{
value = 0;
if (!LooksLikePtr(addr))
return false;
return ReadProcessMemory(GetCurrentProcess(), addr, out value, (nuint)IntPtr.Size, out nuint bytesRead)
&& bytesRead == (nuint)IntPtr.Size;
}
public static bool IsReadable(nint addr, nuint size)
{
if (addr == 0 || size == 0) return false;
if (VirtualQuery(addr, out var mbi, (nuint)Marshal.SizeOf<MEMORY_BASIC_INFORMATION>()) == 0)
return false;
const uint Commit = 0x1000;
const uint NoAccess = 0x01;
const uint PageGuard = 0x100;
if (mbi.State != Commit) return false;
if ((mbi.Protect & PageGuard) != 0) return false;
if (mbi.Protect == NoAccess) return false;
ulong start = (ulong)addr;
ulong end = start + size - 1;
ulong r0 = (ulong)mbi.BaseAddress;
ulong r1 = r0 + mbi.RegionSize - 1;
return start >= r0 && end <= r1;
}
}
}

View File

@@ -0,0 +1,36 @@
using System.Runtime.InteropServices;
namespace LightlessSync.Utils
{
internal static class PtrGuardMemory
{
[StructLayout(LayoutKind.Sequential)]
internal struct MEMORY_BASIC_INFORMATION
{
public nint BaseAddress;
public nint AllocationBase;
public uint AllocationProtect;
public nuint RegionSize;
public uint State;
public uint Protect;
public uint Type;
}
[DllImport("kernel32.dll", SetLastError = true)]
internal static extern nuint VirtualQuery(
nint lpAddress,
out MEMORY_BASIC_INFORMATION lpBuffer,
nuint dwLength);
[DllImport("kernel32.dll", SetLastError = true)]
internal static extern bool ReadProcessMemory(
nint hProcess,
nint lpBaseAddress,
out nint lpBuffer,
nuint nSize,
out nuint lpNumberOfBytesRead);
[DllImport("kernel32.dll")]
internal static extern nint GetCurrentProcess();
}
}