1 /* 2 * PROJECT: ReactOS API Tests 3 * LICENSE: GPLv2+ - See COPYING in the top level directory 4 * PURPOSE: Test for the NtProtectVirtualMemory API 5 * PROGRAMMERS: Jérôme Gardou <jerome.gardou@reactos.org> 6 * Thomas Faber <thomas.faber@reactos.org> 7 */ 8 9 #include "precomp.h" 10 11 static 12 void 13 TestReadWrite(void) 14 { 15 ULONG* allocationStart = NULL; 16 NTSTATUS status; 17 SIZE_T allocationSize; 18 ULONG oldProtection; 19 20 /* Reserve a page */ 21 allocationSize = PAGE_SIZE; 22 status = NtAllocateVirtualMemory(NtCurrentProcess(), 23 (void**)&allocationStart, 24 0, 25 &allocationSize, 26 MEM_RESERVE, 27 PAGE_NOACCESS); 28 ok(NT_SUCCESS(status), "Reserving memory failed\n"); 29 30 /* Commit the page (RW) */ 31 status = NtAllocateVirtualMemory(NtCurrentProcess(), 32 (void**)&allocationStart, 33 0, 34 &allocationSize, 35 MEM_COMMIT, 36 PAGE_READWRITE); 37 ok(NT_SUCCESS(status), "Commiting memory failed\n"); 38 39 /* Try writing it */ 40 StartSeh() 41 { 42 *allocationStart = 0xFF; 43 } EndSeh(STATUS_SUCCESS); 44 45 /* Try reading it */ 46 StartSeh() 47 { 48 ok(*allocationStart == 0xFF, "Memory was not written\n"); 49 } EndSeh(STATUS_SUCCESS); 50 51 /* Set it as read only */ 52 status = NtProtectVirtualMemory(NtCurrentProcess(), 53 (void**)&allocationStart, 54 &allocationSize, 55 PAGE_READONLY, 56 &oldProtection); 57 ok(NT_SUCCESS(status), "NtProtectVirtualMemory failed.\n"); 58 ok(oldProtection == PAGE_READWRITE, "Expected PAGE_READWRITE, got %08lx.\n", oldProtection); 59 60 /* Try writing it */ 61 StartSeh() 62 { 63 *allocationStart = 0xAA; 64 } EndSeh(STATUS_ACCESS_VIOLATION); 65 66 /* Try reading it */ 67 StartSeh() 68 { 69 ok(*allocationStart == 0xFF, "read-only memory were changed.\n"); 70 } EndSeh(STATUS_SUCCESS); 71 72 /* Set it as no access */ 73 status = NtProtectVirtualMemory(NtCurrentProcess(), 74 (void**)&allocationStart, 75 &allocationSize, 76 PAGE_NOACCESS, 77 &oldProtection); 78 ok(NT_SUCCESS(status), "NtProtectVirtualMemory failed.\n"); 79 ok(oldProtection == PAGE_READONLY, "Expected PAGE_READONLY, got %08lx.\n", oldProtection); 80 81 /* Try writing it */ 82 StartSeh() 83 { 84 *allocationStart = 0xAA; 85 } EndSeh(STATUS_ACCESS_VIOLATION); 86 87 /* Try reading it */ 88 StartSeh() 89 { 90 ok(*allocationStart == 0, "Test should not go as far as this.\n"); 91 } EndSeh(STATUS_ACCESS_VIOLATION); 92 93 /* Set it as readable again */ 94 status = NtProtectVirtualMemory(NtCurrentProcess(), 95 (void**)&allocationStart, 96 &allocationSize, 97 PAGE_READONLY, 98 &oldProtection); 99 ok(NT_SUCCESS(status), "NtProtectVirtualMemory failed.\n"); 100 ok(oldProtection == PAGE_NOACCESS, "Expected PAGE_READONLY, got %08lx.\n", oldProtection); 101 102 /* Try writing it */ 103 StartSeh() 104 { 105 *allocationStart = 0xAA; 106 } EndSeh(STATUS_ACCESS_VIOLATION); 107 108 /* Try reading it */ 109 StartSeh() 110 { 111 ok(*allocationStart == 0xFF, "Memory content was not preserved.\n"); 112 } EndSeh(STATUS_SUCCESS); 113 114 /* Free memory */ 115 status = NtFreeVirtualMemory(NtCurrentProcess(), 116 (void**)&allocationStart, 117 &allocationSize, 118 MEM_RELEASE); 119 ok(NT_SUCCESS(status), "Failed freeing memory.\n"); 120 } 121 122 /* Regression test for CORE-13311 */ 123 static 124 void 125 TestFreeNoAccess(void) 126 { 127 PVOID Mem; 128 SIZE_T Size; 129 NTSTATUS Status; 130 ULONG Iteration, PageNumber; 131 PUCHAR Page; 132 ULONG OldProtection; 133 134 for (Iteration = 0; Iteration < 50000; Iteration++) 135 { 136 Mem = NULL; 137 Size = 16 * PAGE_SIZE; 138 Status = NtAllocateVirtualMemory(NtCurrentProcess(), 139 &Mem, 140 0, 141 &Size, 142 MEM_COMMIT, 143 PAGE_READWRITE); 144 ok_ntstatus(Status, STATUS_SUCCESS); 145 if (!NT_SUCCESS(Status)) 146 { 147 break; 148 } 149 150 for (PageNumber = 0; PageNumber < 16; PageNumber++) 151 { 152 Page = Mem; 153 Page += PageNumber * PAGE_SIZE; 154 ok(*Page == 0, 155 "[%lu, %lu] Got non-zero memory. %x at %p\n", 156 Iteration, PageNumber, *Page, Page); 157 *Page = 123; 158 } 159 160 Status = NtProtectVirtualMemory(NtCurrentProcess(), 161 &Mem, 162 &Size, 163 PAGE_NOACCESS, 164 &OldProtection); 165 ok_ntstatus(Status, STATUS_SUCCESS); 166 ok_hex(OldProtection, PAGE_READWRITE); 167 168 Size = 0; 169 Status = NtFreeVirtualMemory(NtCurrentProcess(), 170 &Mem, 171 &Size, 172 MEM_RELEASE); 173 ok_ntstatus(Status, STATUS_SUCCESS); 174 } 175 } 176 177 START_TEST(NtProtectVirtualMemory) 178 { 179 TestReadWrite(); 180 TestFreeNoAccess(); 181 } 182