| author | |
| committer | |
| log | d3599ec73cc07692c2579a8cf7151c918eea525f |
| tree | 1977456fd9b813cb60e7b3ea12842435f725144d |
| parent | a9eb463202f46f6190f57c3b9a5c4913d6c5d6c5 |
4 files changed, 60 insertions(+), 6 deletions(-)
lib/std/c/windows.zig+12| ... | ... | @@ -94,6 +94,18 @@ pub const SEEK = struct { |
| 94 | 94 | pub const END = 2; |
| 95 | 95 | }; |
| 96 | 96 | |
| 97 | /// Basic memory protection flags | |
| 98 | pub const PROT = struct { | |
| 99 | /// page can not be accessed | |
| 100 | pub const NONE = 0x0; | |
| 101 | /// page can be read | |
| 102 | pub const READ = 0x1; | |
| 103 | /// page can be written | |
| 104 | pub const WRITE = 0x2; | |
| 105 | /// page can be executed | |
| 106 | pub const EXEC = 0x4; | |
| 107 | }; | |
| 108 | ||
| 97 | 109 | pub const E = enum(u16) { |
| 98 | 110 | /// No error occurred. |
| 99 | 111 | SUCCESS = 0, |
lib/std/os.zig+24-6| ... | ... | @@ -4226,12 +4226,30 @@ pub const MProtectError = error{ |
| 4226 | 4226 | /// `memory.len` must be page-aligned. |
| 4227 | 4227 | pub fn mprotect(memory: []align(mem.page_size) u8, protection: u32) MProtectError!void { |
| 4228 | 4228 | assert(mem.isAligned(memory.len, mem.page_size)); |
| 4229 | switch (errno(system.mprotect(memory.ptr, memory.len, protection))) { | |
| 4230 | .SUCCESS => return, | |
| 4231 | .INVAL => unreachable, | |
| 4232 | .ACCES => return error.AccessDenied, | |
| 4233 | .NOMEM => return error.OutOfMemory, | |
| 4234 | else => |err| return unexpectedErrno(err), | |
| 4229 | if (builtin.os.tag == .windows) { | |
| 4230 | const win_prot: windows.DWORD = switch (@truncate(u3, protection)) { | |
| 4231 | 0b000 => windows.PAGE_NOACCESS, | |
| 4232 | 0b001 => windows.PAGE_READONLY, | |
| 4233 | 0b010 => unreachable, // +w -r not allowed | |
| 4234 | 0b011 => windows.PAGE_READWRITE, | |
| 4235 | 0b100 => windows.PAGE_EXECUTE, | |
| 4236 | 0b101 => windows.PAGE_EXECUTE_READ, | |
| 4237 | 0b110 => unreachable, // +w -r not allowed | |
| 4238 | 0b111 => windows.PAGE_EXECUTE_READWRITE, | |
| 4239 | }; | |
| 4240 | var old: windows.DWORD = undefined; | |
| 4241 | windows.VirtualProtect(memory.ptr, memory.len, win_prot, &old) catch |err| switch (err) { | |
| 4242 | error.InvalidAddress => return error.AccessDenied, | |
| 4243 | error.Unexpected => return error.Unexpected, | |
| 4244 | }; | |
| 4245 | } else { | |
| 4246 | switch (errno(system.mprotect(memory.ptr, memory.len, protection))) { | |
| 4247 | .SUCCESS => return, | |
| 4248 | .INVAL => unreachable, | |
| 4249 | .ACCES => return error.AccessDenied, | |
| 4250 | .NOMEM => return error.OutOfMemory, | |
| 4251 | else => |err| return unexpectedErrno(err), | |
| 4252 | } | |
| 4235 | 4253 | } |
| 4236 | 4254 | } |
| 4237 | 4255 |
lib/std/os/windows.zig+16| ... | ... | @@ -1499,6 +1499,22 @@ pub fn VirtualFree(lpAddress: ?LPVOID, dwSize: usize, dwFreeType: DWORD) void { |
| 1499 | 1499 | assert(kernel32.VirtualFree(lpAddress, dwSize, dwFreeType) != 0); |
| 1500 | 1500 | } |
| 1501 | 1501 | |
| 1502 | pub const VirtualProtectError = error{ | |
| 1503 | InvalidAddress, | |
| 1504 | Unexpected, | |
| 1505 | }; | |
| 1506 | ||
| 1507 | pub fn VirtualProtect(lpAddress: ?LPVOID, dwSize: SIZE_T, flNewProtect: DWORD, lpflOldProtect: *DWORD) VirtualProtectError!void { | |
| 1508 | // ntdll takes an extra level of indirection here | |
| 1509 | var addr = lpAddress; | |
| 1510 | var size = dwSize; | |
| 1511 | switch (ntdll.NtProtectVirtualMemory(self_process_handle, &addr, &size, flNewProtect, lpflOldProtect)) { | |
| 1512 | .SUCCESS => {}, | |
| 1513 | .INVALID_ADDRESS => return error.InvalidAddress, | |
| 1514 | else => |st| return unexpectedStatus(st), | |
| 1515 | } | |
| 1516 | } | |
| 1517 | ||
| 1502 | 1518 | pub const VirtualQueryError = error{Unexpected}; |
| 1503 | 1519 | |
| 1504 | 1520 | pub fn VirtualQuery(lpAddress: ?LPVOID, lpBuffer: PMEMORY_BASIC_INFORMATION, dwLength: SIZE_T) VirtualQueryError!SIZE_T { |
lib/std/os/windows/ntdll.zig+8| ... | ... | @@ -291,3 +291,11 @@ pub extern "ntdll" fn RtlQueryRegistryValues( |
| 291 | 291 | Context: ?*anyopaque, |
| 292 | 292 | Environment: ?*anyopaque, |
| 293 | 293 | ) callconv(WINAPI) NTSTATUS; |
| 294 | ||
| 295 | pub extern "ntdll" fn NtProtectVirtualMemory( | |
| 296 | ProcessHandle: HANDLE, | |
| 297 | BaseAddress: *PVOID, | |
| 298 | NumberOfBytesToProtect: *ULONG, | |
| 299 | NewAccessProtection: ULONG, | |
| 300 | OldAccessProtection: *ULONG, | |
| 301 | ) callconv(WINAPI) NTSTATUS; |