Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

458 lines
13 KiB

  1. /*++
  2. Copyright (c) 1991-1995 Microsoft Corporation
  3. Module Name:
  4. imagedir.c
  5. Abstract:
  6. The module contains the code to translate an image directory type to
  7. the address of the data for that entry.
  8. Environment:
  9. User Mode or Kernel Mode
  10. Revision History:
  11. --*/
  12. #include <nt.h>
  13. #include <ntrtl.h>
  14. #include <nturtl.h>
  15. #include <private.h>
  16. PVOID
  17. ImageDirectoryEntryToData (
  18. IN PVOID Base,
  19. IN BOOLEAN MappedAsImage,
  20. IN USHORT DirectoryEntry,
  21. OUT PULONG Size
  22. );
  23. PIMAGE_NT_HEADERS
  24. ImageNtHeader (
  25. IN PVOID Base
  26. )
  27. /*++
  28. Routine Description:
  29. This function returns the address of the NT Header.
  30. Arguments:
  31. Base - Supplies the base of the image.
  32. Return Value:
  33. Returns the address of the NT Header.
  34. --*/
  35. {
  36. return RtlpImageNtHeader( Base );
  37. }
  38. PVOID
  39. ImageDirectoryEntryToDataRom (
  40. IN PVOID Base,
  41. IN BOOLEAN MappedAsImage,
  42. IN USHORT DirectoryEntry,
  43. OUT PULONG Size,
  44. OUT PIMAGE_SECTION_HEADER *FoundSection OPTIONAL,
  45. IN PIMAGE_FILE_HEADER FileHeader,
  46. IN PIMAGE_ROM_OPTIONAL_HEADER OptionalHeader
  47. )
  48. {
  49. ULONG i;
  50. PIMAGE_SECTION_HEADER NtSection;
  51. //
  52. // There's not much we can get from ROM images. See if the info requested
  53. // is one of the known ones (debug/exception data)
  54. //
  55. NtSection = (PIMAGE_SECTION_HEADER)((ULONG_PTR)OptionalHeader +
  56. FileHeader->SizeOfOptionalHeader);
  57. for (i = 0; i < FileHeader->NumberOfSections; i++, NtSection++) {
  58. if ( DirectoryEntry == IMAGE_DIRECTORY_ENTRY_DEBUG ) {
  59. if (!_stricmp((char *)NtSection->Name, ".rdata")) {
  60. PIMAGE_DEBUG_DIRECTORY DebugDirectory;
  61. *Size = 0;
  62. DebugDirectory = (PIMAGE_DEBUG_DIRECTORY)((ULONG_PTR)NtSection->PointerToRawData + (ULONG_PTR)Base);
  63. while (DebugDirectory->Type != 0) {
  64. *Size += sizeof(IMAGE_DEBUG_DIRECTORY);
  65. DebugDirectory++;
  66. }
  67. if (FoundSection) {
  68. *FoundSection = NtSection;
  69. }
  70. return (PVOID)((ULONG_PTR)NtSection->PointerToRawData + (ULONG_PTR)Base);
  71. }
  72. } else
  73. if ( DirectoryEntry == IMAGE_DIRECTORY_ENTRY_EXCEPTION ) {
  74. if (!_stricmp((char *)NtSection->Name, ".pdata")) {
  75. if (FoundSection) {
  76. *FoundSection = NtSection;
  77. }
  78. return (PVOID)((ULONG_PTR)NtSection->PointerToRawData + (ULONG_PTR)Base);
  79. }
  80. }
  81. }
  82. // Not one of the known sections. Return error.
  83. *Size = 0;
  84. return( NULL );
  85. }
  86. PVOID
  87. ImageDirectoryEntryToData64 (
  88. IN PVOID Base,
  89. IN BOOLEAN MappedAsImage,
  90. IN USHORT DirectoryEntry,
  91. OUT PULONG Size,
  92. OUT PIMAGE_SECTION_HEADER *FoundSection OPTIONAL,
  93. IN PIMAGE_FILE_HEADER FileHeader,
  94. IN PIMAGE_OPTIONAL_HEADER64 OptionalHeader
  95. )
  96. {
  97. ULONG i;
  98. PIMAGE_SECTION_HEADER NtSection;
  99. ULONG DirectoryAddress;
  100. if (DirectoryEntry >= OptionalHeader->NumberOfRvaAndSizes) {
  101. *Size = 0;
  102. return( NULL );
  103. }
  104. if (!(DirectoryAddress = OptionalHeader->DataDirectory[ DirectoryEntry ].VirtualAddress)) {
  105. *Size = 0;
  106. return( NULL );
  107. }
  108. *Size = OptionalHeader->DataDirectory[ DirectoryEntry ].Size;
  109. if (MappedAsImage || DirectoryAddress < OptionalHeader->SizeOfHeaders) {
  110. if (FoundSection) {
  111. *FoundSection = NULL;
  112. }
  113. return( (PVOID)((ULONG_PTR)Base + DirectoryAddress) );
  114. }
  115. NtSection = (PIMAGE_SECTION_HEADER)((ULONG_PTR)OptionalHeader +
  116. FileHeader->SizeOfOptionalHeader);
  117. for (i=0; i<FileHeader->NumberOfSections; i++) {
  118. if (DirectoryAddress >= NtSection->VirtualAddress &&
  119. DirectoryAddress < NtSection->VirtualAddress + NtSection->SizeOfRawData) {
  120. if (FoundSection) {
  121. *FoundSection = NtSection;
  122. }
  123. return( (PVOID)((ULONG_PTR)Base + (DirectoryAddress - NtSection->VirtualAddress) + NtSection->PointerToRawData) );
  124. }
  125. ++NtSection;
  126. }
  127. return( NULL );
  128. }
  129. PVOID
  130. ImageDirectoryEntryToData32 (
  131. IN PVOID Base,
  132. IN BOOLEAN MappedAsImage,
  133. IN USHORT DirectoryEntry,
  134. OUT PULONG Size,
  135. OUT PIMAGE_SECTION_HEADER *FoundSection OPTIONAL,
  136. IN PIMAGE_FILE_HEADER FileHeader,
  137. IN PIMAGE_OPTIONAL_HEADER32 OptionalHeader
  138. )
  139. {
  140. ULONG i;
  141. PIMAGE_SECTION_HEADER NtSection;
  142. ULONG DirectoryAddress;
  143. if (DirectoryEntry >= OptionalHeader->NumberOfRvaAndSizes) {
  144. *Size = 0;
  145. return( NULL );
  146. }
  147. if (!(DirectoryAddress = OptionalHeader->DataDirectory[ DirectoryEntry ].VirtualAddress)) {
  148. *Size = 0;
  149. return( NULL );
  150. }
  151. *Size = OptionalHeader->DataDirectory[ DirectoryEntry ].Size;
  152. if (MappedAsImage || DirectoryAddress < OptionalHeader->SizeOfHeaders) {
  153. if (FoundSection) {
  154. *FoundSection = NULL;
  155. }
  156. return( (PVOID)((ULONG_PTR)Base + DirectoryAddress) );
  157. }
  158. NtSection = (PIMAGE_SECTION_HEADER)((ULONG_PTR)OptionalHeader +
  159. FileHeader->SizeOfOptionalHeader);
  160. for (i=0; i<FileHeader->NumberOfSections; i++) {
  161. if (DirectoryAddress >= NtSection->VirtualAddress &&
  162. DirectoryAddress < NtSection->VirtualAddress + NtSection->SizeOfRawData) {
  163. if (FoundSection) {
  164. *FoundSection = NtSection;
  165. }
  166. return( (PVOID)((ULONG_PTR)Base + (DirectoryAddress - NtSection->VirtualAddress) + NtSection->PointerToRawData) );
  167. }
  168. ++NtSection;
  169. }
  170. return( NULL );
  171. }
  172. PVOID
  173. ImageDirectoryEntryToDataEx (
  174. IN PVOID Base,
  175. IN BOOLEAN MappedAsImage,
  176. IN USHORT DirectoryEntry,
  177. OUT PULONG Size,
  178. OUT PIMAGE_SECTION_HEADER *FoundSection OPTIONAL
  179. )
  180. /*++
  181. Routine Description:
  182. This function locates a Directory Entry within the image header
  183. and returns either the virtual address or seek address of the
  184. data the Directory describes. It may optionally return the
  185. section header, if any, for the found data.
  186. Arguments:
  187. Base - Supplies the base of the image or data file.
  188. MappedAsImage - FALSE if the file is mapped as a data file.
  189. - TRUE if the file is mapped as an image.
  190. DirectoryEntry - Supplies the directory entry to locate.
  191. Size - Return the size of the directory.
  192. FoundSection - Returns the section header, if any, for the data
  193. Return Value:
  194. NULL - The file does not contain data for the specified directory entry.
  195. NON-NULL - Returns the address of the raw data the directory describes.
  196. --*/
  197. {
  198. PIMAGE_NT_HEADERS NtHeader;
  199. PIMAGE_FILE_HEADER FileHeader;
  200. PIMAGE_OPTIONAL_HEADER OptionalHeader;
  201. if ((ULONG_PTR)Base & 0x00000001) {
  202. Base = (PVOID)((ULONG_PTR)Base & ~0x1);
  203. MappedAsImage = FALSE;
  204. }
  205. NtHeader = ImageNtHeader(Base);
  206. if (NtHeader) {
  207. FileHeader = &NtHeader->FileHeader;
  208. OptionalHeader = &NtHeader->OptionalHeader;
  209. } else {
  210. // Handle case where Image passed in doesn't have a dos stub (ROM images for instance);
  211. FileHeader = (PIMAGE_FILE_HEADER)Base;
  212. OptionalHeader = (PIMAGE_OPTIONAL_HEADER) ((ULONG_PTR)Base + IMAGE_SIZEOF_FILE_HEADER);
  213. }
  214. if (OptionalHeader->Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
  215. return (ImageDirectoryEntryToData32 ( Base,
  216. MappedAsImage,
  217. DirectoryEntry,
  218. Size,
  219. FoundSection,
  220. FileHeader,
  221. (PIMAGE_OPTIONAL_HEADER32)OptionalHeader));
  222. } else if (OptionalHeader->Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
  223. return (ImageDirectoryEntryToData64 ( Base,
  224. MappedAsImage,
  225. DirectoryEntry,
  226. Size,
  227. FoundSection,
  228. FileHeader,
  229. (PIMAGE_OPTIONAL_HEADER64)OptionalHeader));
  230. } else if (OptionalHeader->Magic == IMAGE_ROM_OPTIONAL_HDR_MAGIC) {
  231. return (ImageDirectoryEntryToDataRom ( Base,
  232. MappedAsImage,
  233. DirectoryEntry,
  234. Size,
  235. FoundSection,
  236. FileHeader,
  237. (PIMAGE_ROM_OPTIONAL_HEADER)OptionalHeader));
  238. } else {
  239. *Size = 0;
  240. return NULL;
  241. }
  242. }
  243. PVOID
  244. ImageDirectoryEntryToData (
  245. IN PVOID Base,
  246. IN BOOLEAN MappedAsImage,
  247. IN USHORT DirectoryEntry,
  248. OUT PULONG Size
  249. )
  250. /*++
  251. Routine Description:
  252. This function locates a Directory Entry within the image header
  253. and returns either the virtual address or seek address of the
  254. data the Directory describes.
  255. This just calls ImageDirectoryToDataEx without a FoundSection arg.
  256. Arguments:
  257. Base - Supplies the base of the image or data file.
  258. MappedAsImage - FALSE if the file is mapped as a data file.
  259. - TRUE if the file is mapped as an image.
  260. DirectoryEntry - Supplies the directory entry to locate.
  261. Size - Return the size of the directory.
  262. Return Value:
  263. NULL - The file does not contain data for the specified directory entry.
  264. NON-NULL - Returns the address of the raw data the directory describes.
  265. --*/
  266. {
  267. return ImageDirectoryEntryToDataEx(Base, MappedAsImage, DirectoryEntry, Size, NULL);
  268. }
  269. PIMAGE_SECTION_HEADER
  270. ImageRvaToSection(
  271. IN PIMAGE_NT_HEADERS NtHeaders,
  272. IN PVOID Base,
  273. IN ULONG Rva
  274. )
  275. /*++
  276. Routine Description:
  277. This function locates an RVA within the image header of a file
  278. that is mapped as a file and returns a pointer to the section
  279. table entry for that virtual address
  280. Arguments:
  281. NtHeaders - Supplies the pointer to the image or data file.
  282. Base - Supplies the base of the image or data file.
  283. Rva - Supplies the relative virtual address (RVA) to locate.
  284. Return Value:
  285. NULL - The file does not contain data for the specified directory entry.
  286. NON-NULL - Returns the pointer of the section entry containing the data.
  287. --*/
  288. {
  289. ULONG i;
  290. PIMAGE_SECTION_HEADER NtSection;
  291. NtSection = IMAGE_FIRST_SECTION( NtHeaders );
  292. for (i=0; i<NtHeaders->FileHeader.NumberOfSections; i++) {
  293. if (Rva >= NtSection->VirtualAddress &&
  294. Rva < NtSection->VirtualAddress + NtSection->SizeOfRawData
  295. ) {
  296. return NtSection;
  297. }
  298. ++NtSection;
  299. }
  300. return NULL;
  301. }
  302. PVOID
  303. ImageRvaToVa(
  304. IN PIMAGE_NT_HEADERS NtHeaders,
  305. IN PVOID Base,
  306. IN ULONG Rva,
  307. IN OUT PIMAGE_SECTION_HEADER *LastRvaSection OPTIONAL
  308. )
  309. /*++
  310. Routine Description:
  311. This function locates an RVA within the image header of a file that
  312. is mapped as a file and returns the virtual addrees of the
  313. corresponding byte in the file.
  314. Arguments:
  315. NtHeaders - Supplies the pointer to the image or data file.
  316. Base - Supplies the base of the image or data file.
  317. Rva - Supplies the relative virtual address (RVA) to locate.
  318. LastRvaSection - Optional parameter that if specified, points
  319. to a variable that contains the last section value used for
  320. the specified image to translate and RVA to a VA.
  321. Return Value:
  322. NULL - The file does not contain the specified RVA
  323. NON-NULL - Returns the virtual addrees in the mapped file.
  324. --*/
  325. {
  326. PIMAGE_SECTION_HEADER NtSection;
  327. if (LastRvaSection == NULL ||
  328. (NtSection = *LastRvaSection) == NULL ||
  329. NtSection == NULL ||
  330. Rva < NtSection->VirtualAddress ||
  331. Rva >= NtSection->VirtualAddress + NtSection->SizeOfRawData
  332. ) {
  333. NtSection = ImageRvaToSection( NtHeaders,
  334. Base,
  335. Rva
  336. );
  337. }
  338. if (NtSection != NULL) {
  339. if (LastRvaSection != NULL) {
  340. *LastRvaSection = NtSection;
  341. }
  342. return (PVOID)((ULONG_PTR)Base +
  343. (Rva - NtSection->VirtualAddress) +
  344. NtSection->PointerToRawData
  345. );
  346. }
  347. else {
  348. return NULL;
  349. }
  350. }