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