| /** |
| * This file has no copyright assigned and is placed in the Public Domain. |
| * This file is part of the w64 mingw-runtime package. |
| * No warranty is given; refer to the file DISCLAIMER.PD within this package. |
| */ |
| |
| #include <windows.h> |
| #include <string.h> |
| |
| #if defined (_WIN64) && defined (__ia64__) |
| #error FIXME: Unsupported __ImageBase implementation. |
| #else |
| /* Hack, for bug in ld. Will be removed soon. */ |
| #define __ImageBase __MINGW_LSYMBOL(_image_base__) |
| /* This symbol is defined by the linker. */ |
| extern IMAGE_DOS_HEADER __ImageBase; |
| #endif |
| |
| WINBOOL _ValidateImageBase (PBYTE); |
| |
| WINBOOL |
| _ValidateImageBase (PBYTE pImageBase) |
| { |
| PIMAGE_DOS_HEADER pDOSHeader; |
| PIMAGE_NT_HEADERS pNTHeader; |
| PIMAGE_OPTIONAL_HEADER pOptHeader; |
| |
| pDOSHeader = (PIMAGE_DOS_HEADER) pImageBase; |
| if (pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE) |
| return FALSE; |
| pNTHeader = (PIMAGE_NT_HEADERS) ((PBYTE) pDOSHeader + pDOSHeader->e_lfanew); |
| if (pNTHeader->Signature != IMAGE_NT_SIGNATURE) |
| return FALSE; |
| pOptHeader = (PIMAGE_OPTIONAL_HEADER) &pNTHeader->OptionalHeader; |
| if (pOptHeader->Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC) |
| return FALSE; |
| return TRUE; |
| } |
| |
| PIMAGE_SECTION_HEADER _FindPESection (PBYTE, DWORD_PTR); |
| |
| PIMAGE_SECTION_HEADER |
| _FindPESection (PBYTE pImageBase, DWORD_PTR rva) |
| { |
| PIMAGE_NT_HEADERS pNTHeader; |
| PIMAGE_SECTION_HEADER pSection; |
| unsigned int iSection; |
| |
| pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew); |
| |
| for (iSection = 0, pSection = IMAGE_FIRST_SECTION (pNTHeader); |
| iSection < pNTHeader->FileHeader.NumberOfSections; |
| ++iSection,++pSection) |
| { |
| if (rva >= pSection->VirtualAddress |
| && rva < pSection->VirtualAddress + pSection->Misc.VirtualSize) |
| return pSection; |
| } |
| return NULL; |
| } |
| |
| PIMAGE_SECTION_HEADER _FindPESectionByName (const char *); |
| |
| PIMAGE_SECTION_HEADER |
| _FindPESectionByName (const char *pName) |
| { |
| PBYTE pImageBase; |
| PIMAGE_NT_HEADERS pNTHeader; |
| PIMAGE_SECTION_HEADER pSection; |
| unsigned int iSection; |
| |
| /* Long names aren't supported. */ |
| if (strlen (pName) > IMAGE_SIZEOF_SHORT_NAME) |
| return NULL; |
| |
| pImageBase = (PBYTE) &__ImageBase; |
| if (! _ValidateImageBase (pImageBase)) |
| return NULL; |
| |
| pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew); |
| |
| for (iSection = 0, pSection = IMAGE_FIRST_SECTION (pNTHeader); |
| iSection < pNTHeader->FileHeader.NumberOfSections; |
| ++iSection,++pSection) |
| { |
| if (!strncmp ((char *) &pSection->Name[0], pName, IMAGE_SIZEOF_SHORT_NAME)) |
| return pSection; |
| } |
| return NULL; |
| } |
| |
| int __mingw_GetSectionCount (void); |
| PIMAGE_SECTION_HEADER __mingw_GetSectionForAddress (LPVOID p); |
| |
| PIMAGE_SECTION_HEADER |
| __mingw_GetSectionForAddress (LPVOID p) |
| { |
| PBYTE pImageBase; |
| DWORD_PTR rva; |
| |
| pImageBase = (PBYTE) &__ImageBase; |
| if (! _ValidateImageBase (pImageBase)) |
| return NULL; |
| |
| rva = (DWORD_PTR) (((PBYTE) p) - pImageBase); |
| return _FindPESection (pImageBase, rva); |
| } |
| |
| int |
| __mingw_GetSectionCount (void) |
| { |
| PBYTE pImageBase; |
| PIMAGE_NT_HEADERS pNTHeader; |
| |
| pImageBase = (PBYTE) &__ImageBase; |
| if (! _ValidateImageBase (pImageBase)) |
| return 0; |
| |
| pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew); |
| |
| return (int) pNTHeader->FileHeader.NumberOfSections; |
| } |
| |
| |
| PIMAGE_SECTION_HEADER _FindPESectionExec (size_t); |
| |
| PIMAGE_SECTION_HEADER |
| _FindPESectionExec (size_t eNo) |
| { |
| PBYTE pImageBase; |
| PIMAGE_NT_HEADERS pNTHeader; |
| PIMAGE_SECTION_HEADER pSection; |
| unsigned int iSection; |
| |
| pImageBase = (PBYTE) &__ImageBase; |
| if (! _ValidateImageBase (pImageBase)) |
| return NULL; |
| |
| pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew); |
| |
| for (iSection = 0, pSection = IMAGE_FIRST_SECTION (pNTHeader); |
| iSection < pNTHeader->FileHeader.NumberOfSections; |
| ++iSection,++pSection) |
| { |
| if ((pSection->Characteristics & IMAGE_SCN_MEM_EXECUTE) != 0) |
| { |
| if (!eNo) |
| return pSection; |
| --eNo; |
| } |
| } |
| return NULL; |
| } |
| |
| PBYTE _GetPEImageBase (void); |
| |
| PBYTE |
| _GetPEImageBase (void) |
| { |
| PBYTE pImageBase; |
| pImageBase = (PBYTE) &__ImageBase; |
| if (! _ValidateImageBase (pImageBase)) |
| return NULL; |
| return pImageBase; |
| } |
| |
| WINBOOL _IsNonwritableInCurrentImage (PBYTE); |
| |
| WINBOOL |
| _IsNonwritableInCurrentImage (PBYTE pTarget) |
| { |
| PBYTE pImageBase; |
| DWORD_PTR rvaTarget; |
| PIMAGE_SECTION_HEADER pSection; |
| |
| pImageBase = (PBYTE) &__ImageBase; |
| if (! _ValidateImageBase (pImageBase)) |
| return FALSE; |
| rvaTarget = pTarget - pImageBase; |
| pSection = _FindPESection (pImageBase, rvaTarget); |
| if (pSection == NULL) |
| return FALSE; |
| return (pSection->Characteristics & IMAGE_SCN_MEM_WRITE) == 0; |
| } |
| |
| const char * |
| __mingw_enum_import_library_names (int); |
| |
| const char * |
| __mingw_enum_import_library_names (int i) |
| { |
| PBYTE pImageBase; |
| PIMAGE_NT_HEADERS pNTHeader; |
| PIMAGE_IMPORT_DESCRIPTOR importDesc; |
| PIMAGE_SECTION_HEADER pSection; |
| DWORD importsStartRVA; |
| |
| pImageBase = (PBYTE) &__ImageBase; |
| if (! _ValidateImageBase (pImageBase)) |
| return NULL; |
| |
| pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew); |
| |
| importsStartRVA = pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; |
| if (!importsStartRVA) |
| return NULL; |
| |
| pSection = _FindPESection (pImageBase, importsStartRVA); |
| if (!pSection) |
| return NULL; |
| |
| importDesc = (PIMAGE_IMPORT_DESCRIPTOR) (pImageBase + importsStartRVA); |
| if (!importDesc) |
| return NULL; |
| |
| for (;;) |
| { |
| if (importDesc->TimeDateStamp == 0 && importDesc->Name == 0) |
| break; |
| |
| if (i <= 0) |
| return (char *) (pImageBase + importDesc->Name); |
| --i; |
| importDesc++; |
| } |
| |
| return NULL; |
| } |
| |
| HMODULE __mingw_get_msvcrt_handle(void); |
| HMODULE __mingw_get_msvcrt_handle(void) |
| { |
| static HANDLE msvcrt_handle; |
| |
| if(!msvcrt_handle) { |
| const char *lib_name; |
| int i = 0; |
| |
| while ((lib_name = __mingw_enum_import_library_names (i++))) { |
| if((lib_name[0] == 'm' || lib_name[0] == 'M') |
| && (lib_name[1] == 's' || lib_name[1] == 'S') |
| && (lib_name[2] == 'v' || lib_name[2] == 'V') |
| && (lib_name[3] == 'c' || lib_name[3] == 'C') |
| && (lib_name[4] == 'r' || lib_name[4] == 'R') |
| && (lib_name[5] == 't' || lib_name[5] == 'T' || ('0' <= lib_name[5] && lib_name[5] <= '9'))) |
| break; |
| } |
| |
| if(lib_name) |
| msvcrt_handle = GetModuleHandleA(lib_name); |
| if(!msvcrt_handle) |
| msvcrt_handle = LoadLibraryW(L"msvcrt.dll"); |
| } |
| |
| return msvcrt_handle; |
| } |