1 /* 2 * PROJECT: ReactOS api tests 3 * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory 4 * PURPOSE: Test for RtlImageRvaToVa 5 * PROGRAMMERS: Thomas Faber <thomas.faber@reactos.org> 6 */ 7 8 #include "precomp.h" 9 10 static 11 PVOID 12 AllocateGuarded( 13 _In_ SIZE_T SizeRequested) 14 { 15 NTSTATUS Status; 16 SIZE_T Size = PAGE_ROUND_UP(SizeRequested + PAGE_SIZE); 17 PVOID VirtualMemory = NULL; 18 PCHAR StartOfBuffer; 19 20 Status = NtAllocateVirtualMemory(NtCurrentProcess(), &VirtualMemory, 0, &Size, MEM_RESERVE, PAGE_NOACCESS); 21 22 if (!NT_SUCCESS(Status)) 23 return NULL; 24 25 Size -= PAGE_SIZE; 26 if (Size) 27 { 28 Status = NtAllocateVirtualMemory(NtCurrentProcess(), &VirtualMemory, 0, &Size, MEM_COMMIT, PAGE_READWRITE); 29 if (!NT_SUCCESS(Status)) 30 { 31 Size = 0; 32 Status = NtFreeVirtualMemory(NtCurrentProcess(), &VirtualMemory, &Size, MEM_RELEASE); 33 ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status); 34 return NULL; 35 } 36 } 37 38 StartOfBuffer = VirtualMemory; 39 StartOfBuffer += Size - SizeRequested; 40 41 return StartOfBuffer; 42 } 43 44 static 45 VOID 46 FreeGuarded( 47 _In_ PVOID Pointer) 48 { 49 NTSTATUS Status; 50 PVOID VirtualMemory = (PVOID)PAGE_ROUND_DOWN((SIZE_T)Pointer); 51 SIZE_T Size = 0; 52 53 Status = NtFreeVirtualMemory(NtCurrentProcess(), &VirtualMemory, &Size, MEM_RELEASE); 54 ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status); 55 } 56 57 START_TEST(RtlImageRvaToVa) 58 { 59 PIMAGE_NT_HEADERS NtHeader; 60 PIMAGE_SECTION_HEADER Section; 61 ULONG NumberOfSections; 62 ULONG ImageSize; 63 PUCHAR BaseAddress; 64 PVOID Va; 65 PIMAGE_SECTION_HEADER OutSection; 66 IMAGE_SECTION_HEADER DummySection; 67 struct 68 { 69 ULONG Rva; 70 ULONG VaOffset; 71 ULONG SectionIndex; 72 } Tests[] = 73 { 74 { 0, 0, 0 }, 75 { 0xfff, 0, 0 }, 76 { 0x1000, 0x3000, 0 }, 77 { 0x1001, 0x3001, 0 }, 78 { 0x1fff, 0x3fff, 0 }, 79 { 0x2000, 0, 0 }, 80 { 0x2fff, 0, 0 }, 81 { 0x3000, 0x4000, 3 }, 82 { 0x3fff, 0x4fff, 3 }, 83 { 0x4000, 0x5000, 3 }, 84 { 0x4fff, 0x5fff, 3 }, 85 { 0x5000, 0, 0 }, 86 { 0x5fff, 0, 0 }, 87 { 0x6000, 0, 0 }, 88 { 0x6fff, 0, 0 }, 89 { 0x7000, 0x7000, 5 }, 90 { 0x7fff, 0x7fff, 5 }, 91 { 0x8000, 0x9000, 7 }, 92 { 0x8fff, 0x9fff, 7 }, 93 { 0x9000, 0x8000, 6 }, 94 { 0x9fff, 0x8fff, 6 }, 95 }; 96 ULONG i; 97 98 NumberOfSections = 8; 99 ImageSize = FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader.DataDirectory) + 100 NumberOfSections * sizeof(IMAGE_SECTION_HEADER); 101 NtHeader = AllocateGuarded(ImageSize); 102 if (!NtHeader) 103 { 104 skip("Could not allocate %lu bytes\n", ImageSize); 105 return; 106 } 107 108 RtlFillMemory(NtHeader, ImageSize, 0xDD); 109 NtHeader->FileHeader.NumberOfSections = NumberOfSections; 110 NtHeader->FileHeader.SizeOfOptionalHeader = FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, DataDirectory); 111 Section = (PIMAGE_SECTION_HEADER)((PUCHAR)&NtHeader->OptionalHeader + 112 NtHeader->FileHeader.SizeOfOptionalHeader); 113 Section[0].VirtualAddress = 0x1000; 114 Section[0].Misc.VirtualSize = 0x1000; 115 Section[0].SizeOfRawData = 0x1000; 116 Section[0].PointerToRawData = 0x3000; 117 Section[1].VirtualAddress = 0x2000; 118 Section[1].Misc.VirtualSize = 0; 119 Section[1].SizeOfRawData = 0; 120 Section[1].PointerToRawData = 0x4000; 121 Section[2].VirtualAddress = 0x2000; 122 Section[2].Misc.VirtualSize = 0x1000; 123 Section[2].SizeOfRawData = 0; 124 Section[2].PointerToRawData = 0x4000; 125 Section[3].VirtualAddress = 0x3000; 126 Section[3].Misc.VirtualSize = 0x1000; 127 Section[3].SizeOfRawData = 0x2000; 128 Section[3].PointerToRawData = 0x4000; 129 Section[4].VirtualAddress = 0x4000; 130 Section[4].Misc.VirtualSize = 0x2000; 131 Section[4].SizeOfRawData = 0x1000; 132 Section[4].PointerToRawData = 0x6000; 133 Section[5].VirtualAddress = 0x7000; 134 Section[5].Misc.VirtualSize = 0x1000; 135 Section[5].SizeOfRawData = 0x1000; 136 Section[5].PointerToRawData = 0x7000; 137 Section[6].VirtualAddress = 0x9000; 138 Section[6].Misc.VirtualSize = 0x1000; 139 Section[6].SizeOfRawData = 0x1000; 140 Section[6].PointerToRawData = 0x8000; 141 Section[7].VirtualAddress = 0x8000; 142 Section[7].Misc.VirtualSize = 0x1000; 143 Section[7].SizeOfRawData = 0x1000; 144 Section[7].PointerToRawData = 0x9000; 145 DummySection.VirtualAddress = 0xf000; 146 DummySection.Misc.VirtualSize = 0xf000; 147 DummySection.SizeOfRawData = 0xf000; 148 DummySection.PointerToRawData = 0xf000; 149 150 BaseAddress = (PUCHAR)0x2000000; 151 152 StartSeh() 153 RtlImageRvaToVa(NULL, NULL, 0, NULL); 154 EndSeh(STATUS_ACCESS_VIOLATION); 155 156 Va = RtlImageRvaToVa(NtHeader, NULL, 0, NULL); 157 ok(Va == NULL, "Va = %p\n", Va); 158 159 Va = RtlImageRvaToVa(NtHeader, BaseAddress, 0, NULL); 160 ok(Va == NULL, "Va = %p\n", Va); 161 162 OutSection = NULL; 163 Va = RtlImageRvaToVa(NtHeader, BaseAddress, 0, &OutSection); 164 ok(Va == NULL, "Va = %p\n", Va); 165 ok(OutSection == NULL, "OutSection = %p\n", OutSection); 166 167 OutSection = (PVOID)1; 168 StartSeh() 169 RtlImageRvaToVa(NtHeader, BaseAddress, 0, &OutSection); 170 EndSeh(STATUS_ACCESS_VIOLATION); 171 172 for (i = 0; i < RTL_NUMBER_OF(Tests); i++) 173 { 174 /* Section = not specified */ 175 StartSeh() 176 Va = RtlImageRvaToVa(NtHeader, BaseAddress, Tests[i].Rva, NULL); 177 EndSeh(STATUS_SUCCESS); 178 if (Tests[i].VaOffset == 0) 179 ok(Va == NULL, "[0x%lx] Va = %p\n", Tests[i].Rva, Va); 180 else 181 ok(Va == BaseAddress + Tests[i].VaOffset, "[0x%lx] Va = %p\n", Tests[i].Rva, Va); 182 183 /* Section = NULL */ 184 OutSection = NULL; 185 StartSeh() 186 Va = RtlImageRvaToVa(NtHeader, BaseAddress, Tests[i].Rva, &OutSection); 187 EndSeh(STATUS_SUCCESS); 188 if (Tests[i].VaOffset == 0) 189 { 190 ok(Va == NULL, "[0x%lx] Va = %p\n", Tests[i].Rva, Va); 191 ok(OutSection == NULL, "[0x%lx] OutSection = %p (%Id)\n", Tests[i].Rva, OutSection, OutSection - Section); 192 } 193 else 194 { 195 ok(Va == BaseAddress + Tests[i].VaOffset, "[0x%lx] Va = %p\n", Tests[i].Rva, Va); 196 ok(OutSection == &Section[Tests[i].SectionIndex], "[0x%lx] OutSection = %p (%Id)\n", Tests[i].Rva, OutSection, OutSection - Section); 197 } 198 199 /* Section = first section */ 200 OutSection = Section; 201 StartSeh() 202 Va = RtlImageRvaToVa(NtHeader, BaseAddress, Tests[i].Rva, &OutSection); 203 EndSeh(STATUS_SUCCESS); 204 if (Tests[i].VaOffset == 0) 205 { 206 ok(Va == NULL, "[0x%lx] Va = %p\n", Tests[i].Rva, Va); 207 ok(OutSection == Section, "[0x%lx] OutSection = %p (%Id)\n", Tests[i].Rva, OutSection, OutSection - Section); 208 } 209 else 210 { 211 ok(Va == BaseAddress + Tests[i].VaOffset, "[0x%lx] Va = %p\n", Tests[i].Rva, Va); 212 ok(OutSection == &Section[Tests[i].SectionIndex], "[0x%lx] OutSection = %p (%Id)\n", Tests[i].Rva, OutSection, OutSection - Section); 213 } 214 215 /* Section = dummy section */ 216 OutSection = &DummySection; 217 StartSeh() 218 Va = RtlImageRvaToVa(NtHeader, BaseAddress, Tests[i].Rva, &OutSection); 219 EndSeh(STATUS_SUCCESS); 220 if (Tests[i].VaOffset == 0) 221 { 222 ok(Va == NULL, "[0x%lx] Va = %p\n", Tests[i].Rva, Va); 223 ok(OutSection == &DummySection, "[0x%lx] OutSection = %p (%Id)\n", Tests[i].Rva, OutSection, OutSection - Section); 224 } 225 else 226 { 227 ok(Va == BaseAddress + Tests[i].VaOffset, "[0x%lx] Va = %p\n", Tests[i].Rva, Va); 228 ok(OutSection == &Section[Tests[i].SectionIndex], "[0x%lx] OutSection = %p (%Id)\n", Tests[i].Rva, OutSection, OutSection - Section); 229 } 230 } 231 232 FreeGuarded(NtHeader); 233 } 234