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.

338 lines
9.3 KiB

  1. /*++
  2. Copyright (c) 1999-2002 Microsoft Corporation
  3. Module Name:
  4. imagedir.c
  5. Abstract:
  6. For backwards compatability on Win9x platforms, the imagehlp ImageNtHeader
  7. etc. functions have been physically compiled into minidump.dll.
  8. Author:
  9. Matthew D Hendel (math) 28-April-1999
  10. Revision History:
  11. --*/
  12. #include "pch.cpp"
  13. void
  14. GenImageNtHdr32To64(PIMAGE_NT_HEADERS32 Hdr32,
  15. PIMAGE_NT_HEADERS64 Hdr64)
  16. {
  17. #define CP(x) Hdr64->x = Hdr32->x
  18. #define SE64(x) Hdr64->x = (ULONG64) (LONG64) (LONG) Hdr32->x
  19. ULONG i;
  20. CP(Signature);
  21. CP(FileHeader);
  22. CP(OptionalHeader.Magic);
  23. CP(OptionalHeader.MajorLinkerVersion);
  24. CP(OptionalHeader.MinorLinkerVersion);
  25. CP(OptionalHeader.SizeOfCode);
  26. CP(OptionalHeader.SizeOfInitializedData);
  27. CP(OptionalHeader.SizeOfUninitializedData);
  28. CP(OptionalHeader.AddressOfEntryPoint);
  29. CP(OptionalHeader.BaseOfCode);
  30. SE64(OptionalHeader.ImageBase);
  31. CP(OptionalHeader.SectionAlignment);
  32. CP(OptionalHeader.FileAlignment);
  33. CP(OptionalHeader.MajorOperatingSystemVersion);
  34. CP(OptionalHeader.MinorOperatingSystemVersion);
  35. CP(OptionalHeader.MajorImageVersion);
  36. CP(OptionalHeader.MinorImageVersion);
  37. CP(OptionalHeader.MajorSubsystemVersion);
  38. CP(OptionalHeader.MinorSubsystemVersion);
  39. CP(OptionalHeader.Win32VersionValue);
  40. CP(OptionalHeader.SizeOfImage);
  41. CP(OptionalHeader.SizeOfHeaders);
  42. CP(OptionalHeader.CheckSum);
  43. CP(OptionalHeader.Subsystem);
  44. CP(OptionalHeader.DllCharacteristics);
  45. // Sizes are not sign extended, just copied.
  46. CP(OptionalHeader.SizeOfStackReserve);
  47. CP(OptionalHeader.SizeOfStackCommit);
  48. CP(OptionalHeader.SizeOfHeapReserve);
  49. CP(OptionalHeader.SizeOfHeapCommit);
  50. CP(OptionalHeader.LoaderFlags);
  51. CP(OptionalHeader.NumberOfRvaAndSizes);
  52. for (i = 0; i < ARRAY_COUNT(Hdr32->OptionalHeader.DataDirectory); i++)
  53. {
  54. CP(OptionalHeader.DataDirectory[i]);
  55. }
  56. #undef CP
  57. #undef SE64
  58. }
  59. PIMAGE_NT_HEADERS
  60. GenImageNtHeader(
  61. IN PVOID Base,
  62. OUT OPTIONAL PIMAGE_NT_HEADERS64 Generic
  63. )
  64. /*++
  65. Routine Description:
  66. This function returns the address of the NT Header.
  67. Return Value:
  68. Returns the address of the NT Header.
  69. --*/
  70. {
  71. PIMAGE_NT_HEADERS NtHeaders = NULL;
  72. if (Base != NULL && Base != (PVOID)-1) {
  73. __try {
  74. if (((PIMAGE_DOS_HEADER)Base)->e_magic == IMAGE_DOS_SIGNATURE) {
  75. NtHeaders = (PIMAGE_NT_HEADERS)((PCHAR)Base + ((PIMAGE_DOS_HEADER)Base)->e_lfanew);
  76. if (NtHeaders->Signature != IMAGE_NT_SIGNATURE ||
  77. (NtHeaders->OptionalHeader.Magic !=
  78. IMAGE_NT_OPTIONAL_HDR32_MAGIC &&
  79. NtHeaders->OptionalHeader.Magic !=
  80. IMAGE_NT_OPTIONAL_HDR64_MAGIC)) {
  81. NtHeaders = NULL;
  82. } else if (Generic) {
  83. if (NtHeaders->OptionalHeader.Magic ==
  84. IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
  85. GenImageNtHdr32To64((PIMAGE_NT_HEADERS32)NtHeaders,
  86. Generic);
  87. } else {
  88. memcpy(Generic, NtHeaders, sizeof(*Generic));
  89. }
  90. }
  91. }
  92. } __except(EXCEPTION_EXECUTE_HANDLER) {
  93. NtHeaders = NULL;
  94. }
  95. }
  96. return NtHeaders;
  97. }
  98. PIMAGE_SECTION_HEADER
  99. GenSectionTableFromVirtualAddress (
  100. IN PIMAGE_NT_HEADERS NtHeaders,
  101. IN PVOID Base,
  102. IN ULONG Address
  103. )
  104. /*++
  105. Routine Description:
  106. This function locates a VirtualAddress within the image header
  107. of a file that is mapped as a file and returns a pointer to the
  108. section table entry for that virtual address
  109. Arguments:
  110. NtHeaders - Supplies the pointer to the image or data file.
  111. Base - Supplies the base of the image or data file.
  112. Address - Supplies the virtual address to locate.
  113. Return Value:
  114. NULL - The file does not contain data for the specified directory entry.
  115. NON-NULL - Returns the pointer of the section entry containing the data.
  116. --*/
  117. {
  118. ULONG i;
  119. PIMAGE_SECTION_HEADER NtSection;
  120. NtSection = IMAGE_FIRST_SECTION( NtHeaders );
  121. for (i=0; i<NtHeaders->FileHeader.NumberOfSections; i++) {
  122. if ((ULONG)Address >= NtSection->VirtualAddress &&
  123. (ULONG)Address < NtSection->VirtualAddress + NtSection->SizeOfRawData
  124. ) {
  125. return NtSection;
  126. }
  127. ++NtSection;
  128. }
  129. return NULL;
  130. }
  131. PVOID
  132. GenAddressInSectionTable (
  133. IN PIMAGE_NT_HEADERS NtHeaders,
  134. IN PVOID Base,
  135. IN ULONG Address
  136. )
  137. /*++
  138. Routine Description:
  139. This function locates a VirtualAddress within the image header
  140. of a file that is mapped as a file and returns the seek address
  141. of the data the Directory describes.
  142. Arguments:
  143. NtHeaders - Supplies the pointer to the image or data file.
  144. Base - Supplies the base of the image or data file.
  145. Address - Supplies the virtual address to locate.
  146. Return Value:
  147. NULL - The file does not contain data for the specified directory entry.
  148. NON-NULL - Returns the address of the raw data the directory describes.
  149. --*/
  150. {
  151. PIMAGE_SECTION_HEADER NtSection;
  152. NtSection = GenSectionTableFromVirtualAddress( NtHeaders,
  153. Base,
  154. Address
  155. );
  156. if (NtSection != NULL) {
  157. return( ((PCHAR)Base + ((ULONG_PTR)Address - NtSection->VirtualAddress) + NtSection->PointerToRawData) );
  158. }
  159. else {
  160. return( NULL );
  161. }
  162. }
  163. PVOID
  164. GenImageDirectoryEntryToData32 (
  165. IN PVOID Base,
  166. IN BOOLEAN MappedAsImage,
  167. IN USHORT DirectoryEntry,
  168. OUT PULONG Size,
  169. PIMAGE_NT_HEADERS32 NtHeaders
  170. )
  171. {
  172. ULONG DirectoryAddress;
  173. if (DirectoryEntry >= NtHeaders->OptionalHeader.NumberOfRvaAndSizes) {
  174. return( NULL );
  175. }
  176. if (!(DirectoryAddress = NtHeaders->OptionalHeader.DataDirectory[ DirectoryEntry ].VirtualAddress)) {
  177. return( NULL );
  178. }
  179. *Size = NtHeaders->OptionalHeader.DataDirectory[ DirectoryEntry ].Size;
  180. if (MappedAsImage || DirectoryAddress < NtHeaders->OptionalHeader.SizeOfHeaders) {
  181. return( (PVOID)((PCHAR)Base + DirectoryAddress) );
  182. }
  183. return( GenAddressInSectionTable((PIMAGE_NT_HEADERS)NtHeaders, Base, DirectoryAddress ));
  184. }
  185. PVOID
  186. GenImageDirectoryEntryToData64 (
  187. IN PVOID Base,
  188. IN BOOLEAN MappedAsImage,
  189. IN USHORT DirectoryEntry,
  190. OUT PULONG Size,
  191. PIMAGE_NT_HEADERS64 NtHeaders
  192. )
  193. {
  194. ULONG DirectoryAddress;
  195. if (DirectoryEntry >= NtHeaders->OptionalHeader.NumberOfRvaAndSizes) {
  196. return( NULL );
  197. }
  198. if (!(DirectoryAddress = NtHeaders->OptionalHeader.DataDirectory[ DirectoryEntry ].VirtualAddress)) {
  199. return( NULL );
  200. }
  201. *Size = NtHeaders->OptionalHeader.DataDirectory[ DirectoryEntry ].Size;
  202. if (MappedAsImage || DirectoryAddress < NtHeaders->OptionalHeader.SizeOfHeaders) {
  203. return( (PVOID)((PCHAR)Base + DirectoryAddress) );
  204. }
  205. return( GenAddressInSectionTable((PIMAGE_NT_HEADERS)NtHeaders, Base, DirectoryAddress ));
  206. }
  207. PVOID
  208. GenImageDirectoryEntryToData (
  209. IN PVOID Base,
  210. IN BOOLEAN MappedAsImage,
  211. IN USHORT DirectoryEntry,
  212. OUT PULONG Size
  213. )
  214. /*++
  215. Routine Description:
  216. This function locates a Directory Entry within the image header
  217. and returns either the virtual address or seek address of the
  218. data the Directory describes.
  219. Arguments:
  220. Base - Supplies the base of the image or data file.
  221. MappedAsImage - FALSE if the file is mapped as a data file.
  222. - TRUE if the file is mapped as an image.
  223. DirectoryEntry - Supplies the directory entry to locate.
  224. Size - Return the size of the directory.
  225. Return Value:
  226. NULL - The file does not contain data for the specified directory entry.
  227. NON-NULL - Returns the address of the raw data the directory describes.
  228. --*/
  229. {
  230. PIMAGE_NT_HEADERS NtHeaders;
  231. if ((ULONG_PTR)Base & 0x00000001) {
  232. Base = (PVOID)((ULONG_PTR)Base & ~0x00000001);
  233. MappedAsImage = FALSE;
  234. }
  235. NtHeaders = GenImageNtHeader(Base, NULL);
  236. if (!NtHeaders)
  237. return NULL;
  238. if (NtHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
  239. return (GenImageDirectoryEntryToData32(Base,
  240. MappedAsImage,
  241. DirectoryEntry,
  242. Size,
  243. (PIMAGE_NT_HEADERS32)NtHeaders));
  244. } else if (NtHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
  245. return (GenImageDirectoryEntryToData64(Base,
  246. MappedAsImage,
  247. DirectoryEntry,
  248. Size,
  249. (PIMAGE_NT_HEADERS64)NtHeaders));
  250. } else {
  251. return (NULL);
  252. }
  253. }