Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

imagedir.c

Go to the documentation of this file.
00001 /*++ 00002 00003 Copyright (c) 1991 Microsoft Corporation 00004 00005 Module Name: 00006 00007 imagedir.c 00008 00009 Abstract: 00010 00011 The module contains the code to translate an image directory type to 00012 the address of the data for that entry. 00013 00014 Author: 00015 00016 Steve Wood (stevewo) 18-Aug-1989 00017 00018 Environment: 00019 00020 User Mode or Kernel Mode 00021 00022 Revision History: 00023 00024 --*/ 00025 00026 #include "ntrtlp.h" 00027 00028 PIMAGE_NT_HEADERS 00029 RtlImageNtHeader ( 00030 IN PVOID Base 00031 ) 00032 00033 /*++ 00034 00035 Routine Description: 00036 00037 This function returns the address of the NT Header. 00038 00039 Arguments: 00040 00041 Base - Supplies the base of the image. 00042 00043 Return Value: 00044 00045 Returns the address of the NT Header. 00046 00047 --*/ 00048 00049 { 00050 #if defined (BLDR_KERNEL_RUNTIME) || defined(NTOS_KERNEL_RUNTIME) 00051 PIMAGE_NT_HEADERS NtHeaders = NULL; 00052 00053 if (Base != NULL && Base != (PVOID)-1) { 00054 if (((PIMAGE_DOS_HEADER)Base)->e_magic == IMAGE_DOS_SIGNATURE) { 00055 NtHeaders = (PIMAGE_NT_HEADERS)((PCHAR)Base + ((PIMAGE_DOS_HEADER)Base)->e_lfanew); 00056 00057 #if defined(NTOS_KERNEL_RUNTIME) 00058 if (Base < MM_HIGHEST_USER_ADDRESS) { 00059 if ((PVOID)NtHeaders >= MM_HIGHEST_USER_ADDRESS) { 00060 return NULL; 00061 } 00062 if ((PVOID)((PCHAR)NtHeaders + sizeof (IMAGE_NT_HEADERS)) >= MM_HIGHEST_USER_ADDRESS) { 00063 return NULL; 00064 } 00065 } 00066 #endif 00067 00068 if (NtHeaders->Signature != IMAGE_NT_SIGNATURE) { 00069 NtHeaders = NULL; 00070 } 00071 } 00072 } 00073 00074 return NtHeaders; 00075 #else 00076 return RtlpImageNtHeader( Base ); 00077 #endif 00078 } 00079 00080 00081 PIMAGE_SECTION_HEADER 00082 RtlSectionTableFromVirtualAddress ( 00083 IN PIMAGE_NT_HEADERS NtHeaders, 00084 IN PVOID Base, 00085 IN ULONG Address 00086 ) 00087 00088 /*++ 00089 00090 Routine Description: 00091 00092 This function locates a VirtualAddress within the image header 00093 of a file that is mapped as a file and returns a pointer to the 00094 section table entry for that virtual address 00095 00096 Arguments: 00097 00098 NtHeaders - Supplies the pointer to the image or data file. 00099 00100 Base - Supplies the base of the image or data file. 00101 00102 Address - Supplies the virtual address to locate. 00103 00104 Return Value: 00105 00106 NULL - The file does not contain data for the specified directory entry. 00107 00108 NON-NULL - Returns the pointer of the section entry containing the data. 00109 00110 --*/ 00111 00112 { 00113 ULONG i; 00114 PIMAGE_SECTION_HEADER NtSection; 00115 00116 NtSection = IMAGE_FIRST_SECTION( NtHeaders ); 00117 for (i=0; i<NtHeaders->FileHeader.NumberOfSections; i++) { 00118 if ((ULONG)Address >= NtSection->VirtualAddress && 00119 (ULONG)Address < NtSection->VirtualAddress + NtSection->SizeOfRawData 00120 ) { 00121 return NtSection; 00122 } 00123 ++NtSection; 00124 } 00125 00126 return NULL; 00127 } 00128 00129 00130 PVOID 00131 RtlAddressInSectionTable ( 00132 IN PIMAGE_NT_HEADERS NtHeaders, 00133 IN PVOID Base, 00134 IN ULONG Address 00135 ) 00136 00137 /*++ 00138 00139 Routine Description: 00140 00141 This function locates a VirtualAddress within the image header 00142 of a file that is mapped as a file and returns the seek address 00143 of the data the Directory describes. 00144 00145 Arguments: 00146 00147 NtHeaders - Supplies the pointer to the image or data file. 00148 00149 Base - Supplies the base of the image or data file. 00150 00151 Address - Supplies the virtual address to locate. 00152 00153 Return Value: 00154 00155 NULL - The file does not contain data for the specified directory entry. 00156 00157 NON-NULL - Returns the address of the raw data the directory describes. 00158 00159 --*/ 00160 00161 { 00162 PIMAGE_SECTION_HEADER NtSection; 00163 00164 NtSection = RtlSectionTableFromVirtualAddress( NtHeaders, 00165 Base, 00166 Address 00167 ); 00168 if (NtSection != NULL) { 00169 return( ((PCHAR)Base + ((ULONG_PTR)Address - NtSection->VirtualAddress) + NtSection->PointerToRawData) ); 00170 } 00171 else { 00172 return( NULL ); 00173 } 00174 } 00175 00176 00177 PVOID 00178 RtlpImageDirectoryEntryToData32 ( 00179 IN PVOID Base, 00180 IN BOOLEAN MappedAsImage, 00181 IN USHORT DirectoryEntry, 00182 OUT PULONG Size, 00183 PIMAGE_NT_HEADERS32 NtHeaders 00184 ) 00185 { 00186 ULONG DirectoryAddress; 00187 00188 if (DirectoryEntry >= NtHeaders->OptionalHeader.NumberOfRvaAndSizes) { 00189 return( NULL ); 00190 } 00191 00192 if (!(DirectoryAddress = NtHeaders->OptionalHeader.DataDirectory[ DirectoryEntry ].VirtualAddress)) { 00193 return( NULL ); 00194 } 00195 00196 #if defined(NTOS_KERNEL_RUNTIME) 00197 if (Base < MM_HIGHEST_USER_ADDRESS) { 00198 if ((PVOID)((PCHAR)Base + DirectoryAddress) >= MM_HIGHEST_USER_ADDRESS) { 00199 return( NULL ); 00200 } 00201 } 00202 #endif 00203 00204 *Size = NtHeaders->OptionalHeader.DataDirectory[ DirectoryEntry ].Size; 00205 if (MappedAsImage || DirectoryAddress < NtHeaders->OptionalHeader.SizeOfHeaders) { 00206 return( (PVOID)((PCHAR)Base + DirectoryAddress) ); 00207 } 00208 00209 return( RtlAddressInSectionTable((PIMAGE_NT_HEADERS)NtHeaders, Base, DirectoryAddress )); 00210 } 00211 00212 00213 PVOID 00214 RtlpImageDirectoryEntryToData64 ( 00215 IN PVOID Base, 00216 IN BOOLEAN MappedAsImage, 00217 IN USHORT DirectoryEntry, 00218 OUT PULONG Size, 00219 PIMAGE_NT_HEADERS64 NtHeaders 00220 ) 00221 { 00222 ULONG DirectoryAddress; 00223 00224 if (DirectoryEntry >= NtHeaders->OptionalHeader.NumberOfRvaAndSizes) { 00225 return( NULL ); 00226 } 00227 00228 if (!(DirectoryAddress = NtHeaders->OptionalHeader.DataDirectory[ DirectoryEntry ].VirtualAddress)) { 00229 return( NULL ); 00230 } 00231 00232 #if defined(NTOS_KERNEL_RUNTIME) 00233 if (Base < MM_HIGHEST_USER_ADDRESS) { 00234 if ((PVOID)((PCHAR)Base + DirectoryAddress) >= MM_HIGHEST_USER_ADDRESS) { 00235 return( NULL ); 00236 } 00237 } 00238 #endif 00239 00240 *Size = NtHeaders->OptionalHeader.DataDirectory[ DirectoryEntry ].Size; 00241 if (MappedAsImage || DirectoryAddress < NtHeaders->OptionalHeader.SizeOfHeaders) { 00242 return( (PVOID)((PCHAR)Base + DirectoryAddress) ); 00243 } 00244 00245 return( RtlAddressInSectionTable((PIMAGE_NT_HEADERS)NtHeaders, Base, DirectoryAddress )); 00246 } 00247 00248 00249 PVOID 00250 RtlImageDirectoryEntryToData ( 00251 IN PVOID Base, 00252 IN BOOLEAN MappedAsImage, 00253 IN USHORT DirectoryEntry, 00254 OUT PULONG Size 00255 ) 00256 00257 /*++ 00258 00259 Routine Description: 00260 00261 This function locates a Directory Entry within the image header 00262 and returns either the virtual address or seek address of the 00263 data the Directory describes. 00264 00265 Arguments: 00266 00267 Base - Supplies the base of the image or data file. 00268 00269 MappedAsImage - FALSE if the file is mapped as a data file. 00270 - TRUE if the file is mapped as an image. 00271 00272 DirectoryEntry - Supplies the directory entry to locate. 00273 00274 Size - Return the size of the directory. 00275 00276 Return Value: 00277 00278 NULL - The file does not contain data for the specified directory entry. 00279 00280 NON-NULL - Returns the address of the raw data the directory describes. 00281 00282 --*/ 00283 00284 { 00285 PIMAGE_NT_HEADERS NtHeaders; 00286 00287 if ((ULONG_PTR)Base & 0x00000001) { 00288 Base = (PVOID)((ULONG_PTR)Base & ~0x00000001); 00289 MappedAsImage = FALSE; 00290 } 00291 00292 NtHeaders = RtlImageNtHeader(Base); 00293 00294 if (!NtHeaders) 00295 return NULL; 00296 00297 if (NtHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) { 00298 return (RtlpImageDirectoryEntryToData32(Base, 00299 MappedAsImage, 00300 DirectoryEntry, 00301 Size, 00302 (PIMAGE_NT_HEADERS32)NtHeaders)); 00303 } else if (NtHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) { 00304 return (RtlpImageDirectoryEntryToData64(Base, 00305 MappedAsImage, 00306 DirectoryEntry, 00307 Size, 00308 (PIMAGE_NT_HEADERS64)NtHeaders)); 00309 } else { 00310 return (NULL); 00311 } 00312 } 00313 00314 00315 #if !defined(NTOS_KERNEL_RUNTIME) && !defined(BLDR_KERNEL_RUNTIME) 00316 00317 PIMAGE_SECTION_HEADER 00318 RtlImageRvaToSection( 00319 IN PIMAGE_NT_HEADERS NtHeaders, 00320 IN PVOID Base, 00321 IN ULONG Rva 00322 ) 00323 00324 /*++ 00325 00326 Routine Description: 00327 00328 This function locates an RVA within the image header of a file 00329 that is mapped as a file and returns a pointer to the section 00330 table entry for that virtual address 00331 00332 Arguments: 00333 00334 NtHeaders - Supplies the pointer to the image or data file. 00335 00336 Base - Supplies the base of the image or data file. The image 00337 was mapped as a data file. 00338 00339 Rva - Supplies the relative virtual address (RVA) to locate. 00340 00341 Return Value: 00342 00343 NULL - The RVA was not found within any of the sections of the image. 00344 00345 NON-NULL - Returns the pointer to the image section that contains 00346 the RVA 00347 00348 --*/ 00349 00350 { 00351 ULONG i; 00352 PIMAGE_SECTION_HEADER NtSection; 00353 00354 NtSection = IMAGE_FIRST_SECTION( NtHeaders ); 00355 for (i=0; i<NtHeaders->FileHeader.NumberOfSections; i++) { 00356 if (Rva >= NtSection->VirtualAddress && 00357 Rva < NtSection->VirtualAddress + NtSection->SizeOfRawData 00358 ) { 00359 return NtSection; 00360 } 00361 ++NtSection; 00362 } 00363 00364 return NULL; 00365 } 00366 00367 00368 00369 PVOID 00370 RtlImageRvaToVa( 00371 IN PIMAGE_NT_HEADERS NtHeaders, 00372 IN PVOID Base, 00373 IN ULONG Rva, 00374 IN OUT PIMAGE_SECTION_HEADER *LastRvaSection OPTIONAL 00375 ) 00376 00377 /*++ 00378 00379 Routine Description: 00380 00381 This function locates an RVA within the image header of a file that 00382 is mapped as a file and returns the virtual addrees of the 00383 corresponding byte in the file. 00384 00385 00386 Arguments: 00387 00388 NtHeaders - Supplies the pointer to the image or data file. 00389 00390 Base - Supplies the base of the image or data file. The image 00391 was mapped as a data file. 00392 00393 Rva - Supplies the relative virtual address (RVA) to locate. 00394 00395 LastRvaSection - Optional parameter that if specified, points 00396 to a variable that contains the last section value used for 00397 the specified image to translate and RVA to a VA. 00398 00399 Return Value: 00400 00401 NULL - The file does not contain the specified RVA 00402 00403 NON-NULL - Returns the virtual addrees in the mapped file. 00404 00405 --*/ 00406 00407 { 00408 PIMAGE_SECTION_HEADER NtSection; 00409 00410 if (!ARGUMENT_PRESENT( LastRvaSection ) || 00411 (NtSection = *LastRvaSection) == NULL || 00412 Rva < NtSection->VirtualAddress || 00413 Rva >= NtSection->VirtualAddress + NtSection->SizeOfRawData 00414 ) { 00415 NtSection = RtlImageRvaToSection( NtHeaders, 00416 Base, 00417 Rva 00418 ); 00419 } 00420 00421 if (NtSection != NULL) { 00422 if (LastRvaSection != NULL) { 00423 *LastRvaSection = NtSection; 00424 } 00425 00426 return (PVOID)((PCHAR)Base + 00427 (Rva - NtSection->VirtualAddress) + 00428 NtSection->PointerToRawData 00429 ); 00430 } 00431 else { 00432 return NULL; 00433 } 00434 } 00435 00436 #endif

Generated on Sat May 15 19:40:20 2004 for test by doxygen 1.3.7