private nint AllocateSinglePageNearAddress(nint targetAddr) { var sysInfo = new NativeImport.NativeStructs.SYSTEM_INFO(); NativeImport.GetSystemInfo(ref sysInfo); nuint pageSize = sysInfo.dwPageSize; nuint startAddr = ((nuint)targetAddr & ~(pageSize - 1)); nuint minAddr = (nuint)Math.Min((long)(startAddr - 0x7FFFFF00), sysInfo.lpMinimumApplicationAddress.ToInt64()); nuint maxAddr = (nuint)Math.Min((long)(startAddr - 0x7FFFFF00), sysInfo.lpMaximumApplicationAddress.ToInt64()); nuint startPage = (startAddr - (startAddr % pageSize)); nuint pageOffset = 1; while (true) { nuint byteOffset = pageOffset * pageSize; nuint highAddr = startPage + byteOffset; nuint lowAddr = (startPage > byteOffset) ? startPage - byteOffset : 0; bool needsExit = highAddr > maxAddr && lowAddr < minAddr; if (highAddr < maxAddr) { IntPtr outAddr = NativeImport.VirtualAlloc((nint)highAddr, pageSize, NativeImport.NativeStructs.AllocationType.Commit | NativeImport.NativeStructs.AllocationType.Reserve, NativeImport.NativeStructs.MemoryProtection.ExecuteReadWrite); if (outAddr != IntPtr.Zero) { return(outAddr); } } if (lowAddr > minAddr) { IntPtr outAddr = NativeImport.VirtualAlloc((nint)lowAddr, pageSize, NativeImport.NativeStructs.AllocationType.Commit | NativeImport.NativeStructs.AllocationType.Reserve, NativeImport.NativeStructs.MemoryProtection.ExecuteReadWrite); if (outAddr != IntPtr.Zero) { return(outAddr); } } pageOffset++; if (needsExit) { break; } } return(0); }