1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
6 // CEELOAD reads in the PE file format using LoadLibrary
7 // ===========================================================================
14 #include "pedecoder.h"
16 /*************************************************************************************/
17 // Constructor and destructor!
18 /*************************************************************************************/
26 m_FileSize = m_FileSizeAligned = 0;
34 // If we have an hFile then we opened this file ourselves!
35 // If we do not then this file was loaded by the OS and the OS will
41 /*************************************************************************************/
42 /*************************************************************************************/
43 void PELoader::close()
46 // _ASSERTE(m_hFile != NULL);
50 UnmapViewOfFile((void*)m_hMod);
52 CloseHandle(m_hMapFile);
58 m_FileSize = m_FileSizeAligned = 0;
63 BOOL PELoader::open(LPCSTR moduleName)
65 HMODULE newhMod = NULL;
73 m_hFile = CreateFileA(moduleName, GENERIC_READ, FILE_SHARE_READ,
74 0, OPEN_EXISTING, 0, 0);
75 if (m_hFile == INVALID_HANDLE_VALUE)
78 dwFileSizeLow = GetFileSize( m_hFile, NULL);
79 if (dwFileSizeLow == INVALID_FILE_SIZE)
81 m_FileSize = dwFileSizeLow;
83 m_hMapFile = WszCreateFileMapping(m_hFile, NULL, PAGE_READONLY, 0, 0, NULL);
84 if (m_hMapFile == NULL)
87 newhMod = (HMODULE) MapViewOfFile(m_hMapFile, FILE_MAP_READ, 0, 0, 0);
93 BOOL PELoader::open(const WCHAR* moduleName)
95 HMODULE newhMod = NULL;
102 m_hFile = WszCreateFile(moduleName, GENERIC_READ, FILE_SHARE_READ,
103 0, OPEN_EXISTING, 0, 0);
104 if (m_hFile == INVALID_HANDLE_VALUE)
107 dwFileSizeLow = GetFileSize( m_hFile, NULL);
108 if (dwFileSizeLow == INVALID_FILE_SIZE)
110 m_FileSize = dwFileSizeLow;
112 m_hMapFile = WszCreateFileMapping(m_hFile, NULL, PAGE_READONLY, 0, 0, NULL);
113 if (m_hMapFile == NULL)
116 newhMod = (HMODULE) MapViewOfFile(m_hMapFile, FILE_MAP_READ, 0, 0, 0);
119 return open(newhMod);
123 /*************************************************************************************/
124 BOOL PELoader::open(HMODULE hMod)
126 IMAGE_DOS_HEADER * pdosHeader;
128 // get the dos header...
130 pdosHeader = (IMAGE_DOS_HEADER*) hMod;
131 // If this is not a PE32+ image
132 if (pdosHeader->e_magic == VAL16(IMAGE_DOS_SIGNATURE) &&
133 0 < VAL32(pdosHeader->e_lfanew) && VAL32(pdosHeader->e_lfanew) < 0xFF0) // has to start on first page
135 size_t fileAlignment;
137 m_pNT32 = (IMAGE_NT_HEADERS32*) ((BYTE *)m_hMod + VAL32(pdosHeader->e_lfanew));
139 m_bIsPE32 = (m_pNT32->OptionalHeader.Magic == VAL16(IMAGE_NT_OPTIONAL_HDR32_MAGIC));
143 if ((m_pNT32->Signature != VAL32(IMAGE_NT_SIGNATURE)) ||
144 (m_pNT32->FileHeader.SizeOfOptionalHeader != VAL16(sizeof(IMAGE_OPTIONAL_HEADER32))))
146 // Make this appear uninitalized because for some reason this file is toasted.
151 fileAlignment = VAL32(m_pNT32->OptionalHeader.FileAlignment)-1;
153 else //For now assume not i386 is IA64
155 if ((m_pNT64->Signature != VAL32(IMAGE_NT_SIGNATURE)) ||
156 (m_pNT64->FileHeader.SizeOfOptionalHeader != VAL16(sizeof(IMAGE_OPTIONAL_HEADER64))))
158 // Make this appear uninitalized because for some reason this file is toasted.
163 fileAlignment = VAL32(m_pNT64->OptionalHeader.FileAlignment)-1;
165 m_FileSizeAligned = (m_FileSize + fileAlignment)&(~fileAlignment);
169 // Make this appear uninitalized because for some reason this file is toasted.
176 /*************************************************************************************/
177 void PELoader::dump()
181 /*************************************************************************************/
182 BOOL PELoader::getCOMHeader(IMAGE_COR20_HEADER **ppCorHeader)
184 PIMAGE_SECTION_HEADER pSectionHeader;
188 PIMAGE_NT_HEADERS32 pImageHeader;
189 // Get the image header from the image, then get the directory location
190 // of the COM+ header which may or may not be filled out.
191 pImageHeader = (PIMAGE_NT_HEADERS32)Cor_RtlImageNtHeader(m_hMod, (ULONG) m_FileSize);
192 PREFIX_ASSUME(pImageHeader != NULL);
193 pSectionHeader = (PIMAGE_SECTION_HEADER) Cor_RtlImageRvaToVa32(pImageHeader, (PBYTE)m_hMod,
194 VAL32(pImageHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COMHEADER].VirtualAddress),
195 (DWORD)m_FileSizeAligned /* FileLength */);
199 PIMAGE_NT_HEADERS64 pImageHeader;
201 // Get the image header from the image, then get the directory location
202 // of the COM+ header which may or may not be filled out.
203 pImageHeader = (PIMAGE_NT_HEADERS64)Cor_RtlImageNtHeader(m_hMod, (ULONG) m_FileSize);
204 PREFIX_ASSUME(pImageHeader != NULL);
205 pSectionHeader = (PIMAGE_SECTION_HEADER) Cor_RtlImageRvaToVa64(pImageHeader, (PBYTE)m_hMod,
206 VAL32(pImageHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COMHEADER].VirtualAddress),
207 (DWORD)m_FileSizeAligned /* FileLength */);
210 // If the section header exists, then return ok and the address.
213 *ppCorHeader = (IMAGE_COR20_HEADER *) pSectionHeader;
216 // If there is no COM+ Data in this image, return false.
221 /*************************************************************************************/
222 BOOL PELoader::getVAforRVA(DWORD rva,void **ppva)
224 PIMAGE_SECTION_HEADER pSectionHeader;
228 // Get the image header from the image, then get the directory location
229 // of the COM+ header which may or may not be filled out.
230 PIMAGE_NT_HEADERS32 pImageHeader;
231 pImageHeader = (PIMAGE_NT_HEADERS32) Cor_RtlImageNtHeader(m_hMod, (ULONG) m_FileSize);
232 PREFIX_ASSUME(pImageHeader != NULL);
233 pSectionHeader = (PIMAGE_SECTION_HEADER) Cor_RtlImageRvaToVa32(pImageHeader, (PBYTE)m_hMod,
234 rva, (DWORD)m_FileSizeAligned /* FileLength */);
238 PIMAGE_NT_HEADERS64 pImageHeader;
239 pImageHeader = (PIMAGE_NT_HEADERS64) Cor_RtlImageNtHeader(m_hMod, (ULONG) m_FileSize);
240 PREFIX_ASSUME(pImageHeader != NULL);
241 pSectionHeader = (PIMAGE_SECTION_HEADER) Cor_RtlImageRvaToVa64(pImageHeader, (PBYTE)m_hMod,
242 rva, (DWORD)m_FileSizeAligned /* FileLength */);
245 // If the section header exists, then return ok and the address.
248 *ppva = pSectionHeader;
251 // If there is no COM+ Data in this image, return false.
256 void SectionInfo::Init(PELoader *pPELoader, IMAGE_DATA_DIRECTORY *dir)
259 m_dwSectionOffset = VAL32(dir->VirtualAddress);
260 if (m_dwSectionOffset != 0)
261 m_pSection = pPELoader->base() + m_dwSectionOffset;
264 m_dwSectionSize = VAL32(dir->Size);