internal static Pointer Allocate(int count, bool @protected = false) { if (!@protected) { return(new Pointer((byte *)Marshal.AllocHGlobal(count), count)); } const ProtectedMemoryMode mode = ProtectedMemoryMode.Executable | ProtectedMemoryMode.Writable; // VirtualAlloc rounds allocated size to a page size automatically. var size = count.AlignTo(_pageSize); // Windows XP SP2 / Vista allow Data Excution Prevention (DEP). Win32.MemoryProtectionType protectFlags = 0; if (mode.IsSet(ProtectedMemoryMode.Executable)) { protectFlags |= mode.IsSet(ProtectedMemoryMode.Writable) ? Win32.MemoryProtectionType.ExecuteReadWrite : Win32.MemoryProtectionType.ExecuteRead; } else { protectFlags |= mode.IsSet(ProtectedMemoryMode.Writable) ? Win32.MemoryProtectionType.ReadWrite : Win32.MemoryProtectionType.ReadOnly; } var @base = Win32.NativeMethods.VirtualAlloc(IntPtr.Zero, (UIntPtr)size, Win32.VirtualAllocType.Commit | Win32.VirtualAllocType.Reserve, protectFlags); if (@base.IsInvalid) { return(Pointer.Invalid); } var handle = @base.DangerousGetHandle(); return(new Pointer(handle, count, PointerFlags.Aligned | PointerFlags.Protected)); }
internal static Pointer Allocate(int count, bool @protected = false) { if (!@protected) { // Console.WriteLine("allocated unprotected"); return(new Pointer((byte *)Marshal.AllocHGlobal(count), null, count)); } const ProtectedMemoryMode mode = ProtectedMemoryMode.Executable | ProtectedMemoryMode.Writable; // VirtualAlloc rounds allocated size to a page size automatically. var size = count.AlignTo(_pageSize); // Windows XP SP2 / Vista allow Data Excution Prevention (DEP). Win32.MemoryProtectionType protectFlags = 0; if (mode.IsSet(ProtectedMemoryMode.Executable)) { protectFlags |= mode.IsSet(ProtectedMemoryMode.Writable) ? Win32.MemoryProtectionType.ExecuteReadWrite : Win32.MemoryProtectionType.ExecuteRead; } else { protectFlags |= mode.IsSet(ProtectedMemoryMode.Writable) ? Win32.MemoryProtectionType.ReadWrite : Win32.MemoryProtectionType.ReadOnly; } var @base = Win32.NativeMethods.VirtualAlloc(IntPtr.Zero, (UIntPtr)size, Win32.VirtualAllocType.Commit | Win32.VirtualAllocType.Reserve, protectFlags); if (@base.IsInvalid) { return(Pointer.Invalid); } var handle = @base.DangerousGetHandle(); /* * Console.WriteLine($"Testing write to memory at 0x{(ulong) handle:X} up to {size}"); * Marshal.WriteInt32(handle + 0x26, 0); * for (var i = 0; i < size; i++) { * //Console.WriteLine($"Testing write to memory at 0x{(ulong)(handle + i):X}"); * Marshal.WriteByte(handle + i, 0); * } */ Win32.MemoryProtectionType oldProtectFlags; Action unprotectIt = () => Win32.NativeMethods.VirtualProtect(handle, (UIntPtr)size, protectFlags, out oldProtectFlags); return(new Pointer(handle, unprotectIt, count, PointerFlags.Aligned | PointerFlags.Protected)); }