Verify that we're unable set .text or .rdata's page protection via NtProtectVirtualMemory. e.g., changing .text from PAGE_EXECUTE_READ to PAGE_EXECUTE_READWRITE should fail after remap::RemapSelfImage returns.
| 50 | // e.g., changing .text from PAGE_EXECUTE_READ to PAGE_EXECUTE_READWRITE should |
| 51 | // fail after remap::RemapSelfImage returns. |
| 52 | static void TestVirtualProtect(const PVOID ImageBase) |
| 53 | { |
| 54 | PE_HEADER pe; |
| 55 | if (!FillPEHeader(SIZE_T(ImageBase), pe)) |
| 56 | return; |
| 57 | |
| 58 | const PIMAGE_SECTION_HEADER text = GetPeSectionByName(pe, ".text"); |
| 59 | const PIMAGE_SECTION_HEADER rdata = GetPeSectionByName(pe, ".rdata"); |
| 60 | if (!(text && text < rdata)) |
| 61 | return; |
| 62 | |
| 63 | auto testVirtualProtect = [](SIZE_T BaseAddress, SIZE_T RegionSize, DWORD NewProtection) |
| 64 | { |
| 65 | PVOID regionBase = PVOID(BaseAddress); |
| 66 | SIZE_T regionSize = RegionSize; |
| 67 | DWORD oldProtection = 0; |
| 68 | ntapi::NTSTATUS status = ntapi::NtProtectVirtualMemory(GetCurrentProcess(), |
| 69 | ®ionBase, |
| 70 | ®ionSize, |
| 71 | NewProtection, |
| 72 | &oldProtection); |
| 73 | if (status != ntapi::STATUS_INVALID_PAGE_PROTECTION && |
| 74 | NewProtection != oldProtection) |
| 75 | printf("Unexpected NtProtectVirtualMemory status for %p (%X): 0x%08X\n", |
| 76 | BaseAddress, |
| 77 | NewProtection, |
| 78 | status); |
| 79 | }; |
| 80 | |
| 81 | const std::array<DWORD, 12> protectionValues = |
| 82 | { |
| 83 | PAGE_NOACCESS, |
| 84 | PAGE_READONLY, |
| 85 | PAGE_READWRITE, |
| 86 | PAGE_WRITECOPY, |
| 87 | PAGE_EXECUTE, |
| 88 | PAGE_EXECUTE_READ, |
| 89 | PAGE_EXECUTE_READWRITE, |
| 90 | PAGE_EXECUTE_WRITECOPY, |
| 91 | PAGE_GUARD, |
| 92 | PAGE_NOCACHE, |
| 93 | PAGE_WRITECOMBINE, |
| 94 | PAGE_REVERT_TO_FILE_MAP |
| 95 | }; |
| 96 | |
| 97 | for (auto protection : protectionValues) |
| 98 | { |
| 99 | // .text |
| 100 | testVirtualProtect(pe.optionalHeader->ImageBase, |
| 101 | PE_HEADER_SIZE + text->Misc.VirtualSize, |
| 102 | protection); |
| 103 | |
| 104 | // .rdata |
| 105 | testVirtualProtect(pe.optionalHeader->ImageBase + rdata->VirtualAddress, |
| 106 | rdata->Misc.VirtualSize, |
| 107 | protection); |
| 108 | } |
| 109 | } |
no test coverage detected