MemoryManagementWindows.cs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. using System;
  2. using System.Runtime.CompilerServices;
  3. using System.Runtime.InteropServices;
  4. namespace ARMeilleure.Memory
  5. {
  6. static class MemoryManagementWindows
  7. {
  8. [Flags]
  9. private enum AllocationType : uint
  10. {
  11. Commit = 0x1000,
  12. Reserve = 0x2000,
  13. Decommit = 0x4000,
  14. Release = 0x8000,
  15. Reset = 0x80000,
  16. Physical = 0x400000,
  17. TopDown = 0x100000,
  18. WriteWatch = 0x200000,
  19. LargePages = 0x20000000
  20. }
  21. [Flags]
  22. private enum MemoryProtection : uint
  23. {
  24. NoAccess = 0x01,
  25. ReadOnly = 0x02,
  26. ReadWrite = 0x04,
  27. WriteCopy = 0x08,
  28. Execute = 0x10,
  29. ExecuteRead = 0x20,
  30. ExecuteReadWrite = 0x40,
  31. ExecuteWriteCopy = 0x80,
  32. GuardModifierflag = 0x100,
  33. NoCacheModifierflag = 0x200,
  34. WriteCombineModifierflag = 0x400
  35. }
  36. [DllImport("kernel32.dll")]
  37. private static extern IntPtr VirtualAlloc(
  38. IntPtr lpAddress,
  39. IntPtr dwSize,
  40. AllocationType flAllocationType,
  41. MemoryProtection flProtect);
  42. [DllImport("kernel32.dll")]
  43. private static extern bool VirtualProtect(
  44. IntPtr lpAddress,
  45. IntPtr dwSize,
  46. MemoryProtection flNewProtect,
  47. out MemoryProtection lpflOldProtect);
  48. [DllImport("kernel32.dll")]
  49. private static extern bool VirtualFree(
  50. IntPtr lpAddress,
  51. IntPtr dwSize,
  52. AllocationType dwFreeType);
  53. public static IntPtr Allocate(IntPtr size)
  54. {
  55. const AllocationType flags =
  56. AllocationType.Reserve |
  57. AllocationType.Commit;
  58. IntPtr ptr = VirtualAlloc(IntPtr.Zero, size, flags, MemoryProtection.ReadWrite);
  59. if (ptr == IntPtr.Zero)
  60. {
  61. throw new OutOfMemoryException();
  62. }
  63. return ptr;
  64. }
  65. public static IntPtr AllocateWriteTracked(IntPtr size)
  66. {
  67. const AllocationType flags =
  68. AllocationType.Reserve |
  69. AllocationType.Commit |
  70. AllocationType.WriteWatch;
  71. IntPtr ptr = VirtualAlloc(IntPtr.Zero, size, flags, MemoryProtection.ReadWrite);
  72. if (ptr == IntPtr.Zero)
  73. {
  74. throw new OutOfMemoryException();
  75. }
  76. return ptr;
  77. }
  78. public static bool Reprotect(IntPtr address, IntPtr size, Memory.MemoryProtection protection)
  79. {
  80. MemoryProtection prot = GetProtection(protection);
  81. return VirtualProtect(address, size, prot, out _);
  82. }
  83. private static MemoryProtection GetProtection(Memory.MemoryProtection protection)
  84. {
  85. switch (protection)
  86. {
  87. case Memory.MemoryProtection.None: return MemoryProtection.NoAccess;
  88. case Memory.MemoryProtection.Read: return MemoryProtection.ReadOnly;
  89. case Memory.MemoryProtection.ReadAndWrite: return MemoryProtection.ReadWrite;
  90. case Memory.MemoryProtection.ReadAndExecute: return MemoryProtection.ExecuteRead;
  91. case Memory.MemoryProtection.ReadWriteExecute: return MemoryProtection.ExecuteReadWrite;
  92. case Memory.MemoryProtection.Execute: return MemoryProtection.Execute;
  93. default: throw new ArgumentException($"Invalid permission \"{protection}\".");
  94. }
  95. }
  96. public static bool Free(IntPtr address)
  97. {
  98. return VirtualFree(address, IntPtr.Zero, AllocationType.Release);
  99. }
  100. }
  101. }