summaryrefslogtreecommitdiff
path: root/src/ildasm/ceeload.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/ildasm/ceeload.cpp')
-rw-r--r--src/ildasm/ceeload.cpp266
1 files changed, 266 insertions, 0 deletions
diff --git a/src/ildasm/ceeload.cpp b/src/ildasm/ceeload.cpp
new file mode 100644
index 0000000000..a78ff72c44
--- /dev/null
+++ b/src/ildasm/ceeload.cpp
@@ -0,0 +1,266 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+//
+// CEELOAD reads in the PE file format using LoadLibrary
+// ===========================================================================
+#include "ildasmpch.h"
+
+#include "ceeload.h"
+#include <corhdr.h>
+#include <corimage.h>
+#include "util.hpp"
+#include "pedecoder.h"
+
+/*************************************************************************************/
+// Constructor and destructor!
+/*************************************************************************************/
+PELoader::PELoader()
+{
+ m_hFile = NULL;
+ m_hMod = NULL;
+ m_hMapFile = NULL;
+ m_pNT64 = NULL;
+ m_bIsPE32 = FALSE;
+ m_FileSize = m_FileSizeAligned = 0;
+}
+
+PELoader::~PELoader()
+{
+
+ m_hMod = NULL;
+ m_pNT64 = NULL;
+ // If we have an hFile then we opened this file ourselves!
+ // If we do not then this file was loaded by the OS and the OS will
+ // close it for us.
+ if (m_hFile)
+ this->close();
+}
+
+/*************************************************************************************/
+/*************************************************************************************/
+void PELoader::close()
+{
+
+ // _ASSERTE(m_hFile != NULL);
+ if (m_hFile)
+ {
+ if (m_hMod)
+ UnmapViewOfFile((void*)m_hMod);
+ if (m_hMapFile)
+ CloseHandle(m_hMapFile);
+ CloseHandle(m_hFile);
+
+ m_hMod = NULL;
+ m_hMapFile = NULL;
+ m_hFile = NULL;
+ m_FileSize = m_FileSizeAligned = 0;
+ }
+}
+
+
+BOOL PELoader::open(LPCSTR moduleName)
+{
+ HMODULE newhMod = NULL;
+ DWORD dwFileSizeLow;
+
+ _ASSERTE(moduleName);
+ if (!moduleName)
+ return FALSE;
+
+
+ m_hFile = CreateFileA(moduleName, GENERIC_READ, FILE_SHARE_READ,
+ 0, OPEN_EXISTING, 0, 0);
+ if (m_hFile == INVALID_HANDLE_VALUE)
+ return FALSE;
+
+ dwFileSizeLow = GetFileSize( m_hFile, NULL);
+ if (dwFileSizeLow == INVALID_FILE_SIZE)
+ return FALSE;
+ m_FileSize = dwFileSizeLow;
+
+ m_hMapFile = WszCreateFileMapping(m_hFile, NULL, PAGE_READONLY, 0, 0, NULL);
+ if (m_hMapFile == NULL)
+ return FALSE;
+
+ newhMod = (HMODULE) MapViewOfFile(m_hMapFile, FILE_MAP_READ, 0, 0, 0);
+ if (newhMod == NULL)
+ return FALSE;
+ return open(newhMod);
+}
+
+BOOL PELoader::open(const WCHAR* moduleName)
+{
+ HMODULE newhMod = NULL;
+ DWORD dwFileSizeLow;
+
+ _ASSERTE(moduleName);
+ if (!moduleName)
+ return FALSE;
+
+ m_hFile = WszCreateFile(moduleName, GENERIC_READ, FILE_SHARE_READ,
+ 0, OPEN_EXISTING, 0, 0);
+ if (m_hFile == INVALID_HANDLE_VALUE)
+ return FALSE;
+
+ dwFileSizeLow = GetFileSize( m_hFile, NULL);
+ if (dwFileSizeLow == INVALID_FILE_SIZE)
+ return FALSE;
+ m_FileSize = dwFileSizeLow;
+
+ m_hMapFile = WszCreateFileMapping(m_hFile, NULL, PAGE_READONLY, 0, 0, NULL);
+ if (m_hMapFile == NULL)
+ return FALSE;
+
+ newhMod = (HMODULE) MapViewOfFile(m_hMapFile, FILE_MAP_READ, 0, 0, 0);
+ if (newhMod == NULL)
+ return FALSE;
+ return open(newhMod);
+}
+
+
+/*************************************************************************************/
+BOOL PELoader::open(HMODULE hMod)
+{
+ IMAGE_DOS_HEADER * pdosHeader;
+
+ // get the dos header...
+ m_hMod = hMod;
+ pdosHeader = (IMAGE_DOS_HEADER*) hMod;
+ // If this is not a PE32+ image
+ if (pdosHeader->e_magic == VAL16(IMAGE_DOS_SIGNATURE) &&
+ 0 < VAL32(pdosHeader->e_lfanew) && VAL32(pdosHeader->e_lfanew) < 0xFF0) // has to start on first page
+ {
+ size_t fileAlignment;
+
+ m_pNT32 = (IMAGE_NT_HEADERS32*) ((BYTE *)m_hMod + VAL32(pdosHeader->e_lfanew));
+
+ m_bIsPE32 = (m_pNT32->OptionalHeader.Magic == VAL16(IMAGE_NT_OPTIONAL_HDR32_MAGIC));
+
+ if (m_bIsPE32)
+ {
+ if ((m_pNT32->Signature != VAL32(IMAGE_NT_SIGNATURE)) ||
+ (m_pNT32->FileHeader.SizeOfOptionalHeader != VAL16(sizeof(IMAGE_OPTIONAL_HEADER32))))
+ {
+ // Make this appear uninitalized because for some reason this file is toasted.
+ m_pNT32 = NULL;
+ m_hMod = NULL;
+ return FALSE;
+ }
+ fileAlignment = VAL32(m_pNT32->OptionalHeader.FileAlignment)-1;
+ }
+ else //For now assume not i386 is IA64
+ {
+ if ((m_pNT64->Signature != VAL32(IMAGE_NT_SIGNATURE)) ||
+ (m_pNT64->FileHeader.SizeOfOptionalHeader != VAL16(sizeof(IMAGE_OPTIONAL_HEADER64))))
+ {
+ // Make this appear uninitalized because for some reason this file is toasted.
+ m_pNT64 = NULL;
+ m_hMod = NULL;
+ return FALSE;
+ }
+ fileAlignment = VAL32(m_pNT64->OptionalHeader.FileAlignment)-1;
+ }
+ m_FileSizeAligned = (m_FileSize + fileAlignment)&(~fileAlignment);
+ }
+ else
+ {
+ // Make this appear uninitalized because for some reason this file is toasted.
+ m_hMod = NULL;
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/*************************************************************************************/
+void PELoader::dump()
+{
+}
+
+/*************************************************************************************/
+BOOL PELoader::getCOMHeader(IMAGE_COR20_HEADER **ppCorHeader)
+{
+ PIMAGE_SECTION_HEADER pSectionHeader;
+
+ if (m_bIsPE32)
+ {
+ PIMAGE_NT_HEADERS32 pImageHeader;
+ // Get the image header from the image, then get the directory location
+ // of the COM+ header which may or may not be filled out.
+ pImageHeader = (PIMAGE_NT_HEADERS32)Cor_RtlImageNtHeader(m_hMod, (ULONG) m_FileSize);
+ PREFIX_ASSUME(pImageHeader != NULL);
+ pSectionHeader = (PIMAGE_SECTION_HEADER) Cor_RtlImageRvaToVa32(pImageHeader, (PBYTE)m_hMod,
+ VAL32(pImageHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COMHEADER].VirtualAddress),
+ (DWORD)m_FileSizeAligned /* FileLength */);
+ }
+ else
+ {
+ PIMAGE_NT_HEADERS64 pImageHeader;
+
+ // Get the image header from the image, then get the directory location
+ // of the COM+ header which may or may not be filled out.
+ pImageHeader = (PIMAGE_NT_HEADERS64)Cor_RtlImageNtHeader(m_hMod, (ULONG) m_FileSize);
+ PREFIX_ASSUME(pImageHeader != NULL);
+ pSectionHeader = (PIMAGE_SECTION_HEADER) Cor_RtlImageRvaToVa64(pImageHeader, (PBYTE)m_hMod,
+ VAL32(pImageHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COMHEADER].VirtualAddress),
+ (DWORD)m_FileSizeAligned /* FileLength */);
+ }
+
+ // If the section header exists, then return ok and the address.
+ if (pSectionHeader)
+ {
+ *ppCorHeader = (IMAGE_COR20_HEADER *) pSectionHeader;
+ return TRUE;
+ }
+ // If there is no COM+ Data in this image, return false.
+ else
+ return FALSE;
+}
+
+/*************************************************************************************/
+BOOL PELoader::getVAforRVA(DWORD rva,void **ppva)
+{
+ PIMAGE_SECTION_HEADER pSectionHeader;
+
+ if (m_bIsPE32)
+ {
+ // Get the image header from the image, then get the directory location
+ // of the COM+ header which may or may not be filled out.
+ PIMAGE_NT_HEADERS32 pImageHeader;
+ pImageHeader = (PIMAGE_NT_HEADERS32) Cor_RtlImageNtHeader(m_hMod, (ULONG) m_FileSize);
+ PREFIX_ASSUME(pImageHeader != NULL);
+ pSectionHeader = (PIMAGE_SECTION_HEADER) Cor_RtlImageRvaToVa32(pImageHeader, (PBYTE)m_hMod,
+ rva, (DWORD)m_FileSizeAligned /* FileLength */);
+ }
+ else
+ {
+ PIMAGE_NT_HEADERS64 pImageHeader;
+ pImageHeader = (PIMAGE_NT_HEADERS64) Cor_RtlImageNtHeader(m_hMod, (ULONG) m_FileSize);
+ PREFIX_ASSUME(pImageHeader != NULL);
+ pSectionHeader = (PIMAGE_SECTION_HEADER) Cor_RtlImageRvaToVa64(pImageHeader, (PBYTE)m_hMod,
+ rva, (DWORD)m_FileSizeAligned /* FileLength */);
+ }
+
+ // If the section header exists, then return ok and the address.
+ if (pSectionHeader)
+ {
+ *ppva = pSectionHeader;
+ return TRUE;
+ }
+ // If there is no COM+ Data in this image, return false.
+ else
+ return FALSE;
+}
+
+void SectionInfo::Init(PELoader *pPELoader, IMAGE_DATA_DIRECTORY *dir)
+{
+ _ASSERTE(dir);
+ m_dwSectionOffset = VAL32(dir->VirtualAddress);
+ if (m_dwSectionOffset != 0)
+ m_pSection = pPELoader->base() + m_dwSectionOffset;
+ else
+ m_pSection = 0;
+ m_dwSectionSize = VAL32(dir->Size);
+}
+