1 /** 2 * This file has no copyright assigned and is placed in the Public Domain. 3 * This file is part of the w64 mingw-runtime package. 4 * No warranty is given; refer to the file DISCLAIMER.PD within this package. 5 */ 6 7 //#include <windows.h> 8 #include <stdarg.h> 9 #include <windef.h> 10 #include <winbase.h> 11 #include <string.h> 12 13 #if defined (_WIN64) && defined (__ia64__) 14 #error FIXME: Unsupported __ImageBase implementation. 15 #else 16 #ifdef __GNUC__ 17 /* Hack, for bug in ld. Will be removed soon. */ 18 #define __ImageBase __MINGW_LSYMBOL(_image_base__) 19 #endif 20 /* This symbol is defined by the linker. */ 21 extern IMAGE_DOS_HEADER __ImageBase; 22 #endif 23 24 WINBOOL _ValidateImageBase (PBYTE); 25 26 WINBOOL 27 _ValidateImageBase (PBYTE pImageBase) 28 { 29 PIMAGE_DOS_HEADER pDOSHeader; 30 PIMAGE_NT_HEADERS pNTHeader; 31 PIMAGE_OPTIONAL_HEADER pOptHeader; 32 33 pDOSHeader = (PIMAGE_DOS_HEADER) pImageBase; 34 if (pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE) 35 return FALSE; 36 pNTHeader = (PIMAGE_NT_HEADERS) ((PBYTE) pDOSHeader + pDOSHeader->e_lfanew); 37 if (pNTHeader->Signature != IMAGE_NT_SIGNATURE) 38 return FALSE; 39 pOptHeader = (PIMAGE_OPTIONAL_HEADER) &pNTHeader->OptionalHeader; 40 if (pOptHeader->Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC) 41 return FALSE; 42 return TRUE; 43 } 44 45 PIMAGE_SECTION_HEADER _FindPESection (PBYTE, DWORD_PTR); 46 47 PIMAGE_SECTION_HEADER 48 _FindPESection (PBYTE pImageBase, DWORD_PTR rva) 49 { 50 PIMAGE_NT_HEADERS pNTHeader; 51 PIMAGE_SECTION_HEADER pSection; 52 unsigned int iSection; 53 54 pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew); 55 56 for (iSection = 0, pSection = IMAGE_FIRST_SECTION (pNTHeader); 57 iSection < pNTHeader->FileHeader.NumberOfSections; 58 ++iSection,++pSection) 59 { 60 if (rva >= pSection->VirtualAddress 61 && rva < pSection->VirtualAddress + pSection->Misc.VirtualSize) 62 return pSection; 63 } 64 return NULL; 65 } 66 67 PIMAGE_SECTION_HEADER _FindPESectionByName (const char *); 68 69 PIMAGE_SECTION_HEADER 70 _FindPESectionByName (const char *pName) 71 { 72 PBYTE pImageBase; 73 PIMAGE_NT_HEADERS pNTHeader; 74 PIMAGE_SECTION_HEADER pSection; 75 unsigned int iSection; 76 77 /* Long names aren't supported. */ 78 if (strlen (pName) > IMAGE_SIZEOF_SHORT_NAME) 79 return NULL; 80 81 pImageBase = (PBYTE) &__ImageBase; 82 if (! _ValidateImageBase (pImageBase)) 83 return NULL; 84 85 pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew); 86 87 for (iSection = 0, pSection = IMAGE_FIRST_SECTION (pNTHeader); 88 iSection < pNTHeader->FileHeader.NumberOfSections; 89 ++iSection,++pSection) 90 { 91 if (!strncmp ((char *) &pSection->Name[0], pName, IMAGE_SIZEOF_SHORT_NAME)) 92 return pSection; 93 } 94 return NULL; 95 } 96 97 int __mingw_GetSectionCount (void); 98 PIMAGE_SECTION_HEADER __mingw_GetSectionForAddress (LPVOID p); 99 100 PIMAGE_SECTION_HEADER 101 __mingw_GetSectionForAddress (LPVOID p) 102 { 103 PBYTE pImageBase; 104 DWORD_PTR rva; 105 106 pImageBase = (PBYTE) &__ImageBase; 107 if (! _ValidateImageBase (pImageBase)) 108 return NULL; 109 110 rva = (DWORD_PTR) (((PBYTE) p) - pImageBase); 111 return _FindPESection (pImageBase, rva); 112 } 113 114 int 115 __mingw_GetSectionCount (void) 116 { 117 PBYTE pImageBase; 118 PIMAGE_NT_HEADERS pNTHeader; 119 120 pImageBase = (PBYTE) &__ImageBase; 121 if (! _ValidateImageBase (pImageBase)) 122 return 0; 123 124 pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew); 125 126 return (int) pNTHeader->FileHeader.NumberOfSections; 127 } 128 129 130 PIMAGE_SECTION_HEADER _FindPESectionExec (size_t); 131 132 PIMAGE_SECTION_HEADER 133 _FindPESectionExec (size_t eNo) 134 { 135 PBYTE pImageBase; 136 PIMAGE_NT_HEADERS pNTHeader; 137 PIMAGE_SECTION_HEADER pSection; 138 unsigned int iSection; 139 140 pImageBase = (PBYTE) &__ImageBase; 141 if (! _ValidateImageBase (pImageBase)) 142 return NULL; 143 144 pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew); 145 146 for (iSection = 0, pSection = IMAGE_FIRST_SECTION (pNTHeader); 147 iSection < pNTHeader->FileHeader.NumberOfSections; 148 ++iSection,++pSection) 149 { 150 if ((pSection->Characteristics & IMAGE_SCN_MEM_EXECUTE) != 0) 151 { 152 if (!eNo) 153 return pSection; 154 --eNo; 155 } 156 } 157 return NULL; 158 } 159 160 PBYTE _GetPEImageBase (void); 161 162 PBYTE 163 _GetPEImageBase (void) 164 { 165 PBYTE pImageBase; 166 pImageBase = (PBYTE) &__ImageBase; 167 if (! _ValidateImageBase (pImageBase)) 168 return NULL; 169 return pImageBase; 170 } 171 172 WINBOOL _IsNonwritableInCurrentImage (PBYTE); 173 174 WINBOOL 175 _IsNonwritableInCurrentImage (PBYTE pTarget) 176 { 177 PBYTE pImageBase; 178 DWORD_PTR rvaTarget; 179 PIMAGE_SECTION_HEADER pSection; 180 181 pImageBase = (PBYTE) &__ImageBase; 182 if (! _ValidateImageBase (pImageBase)) 183 return FALSE; 184 rvaTarget = pTarget - pImageBase; 185 pSection = _FindPESection (pImageBase, rvaTarget); 186 if (pSection == NULL) 187 return FALSE; 188 return (pSection->Characteristics & IMAGE_SCN_MEM_WRITE) == 0; 189 } 190 191 const char * 192 __mingw_enum_import_library_names (int); 193 194 const char * 195 __mingw_enum_import_library_names (int i) 196 { 197 PBYTE pImageBase; 198 PIMAGE_NT_HEADERS pNTHeader; 199 PIMAGE_IMPORT_DESCRIPTOR importDesc; 200 PIMAGE_SECTION_HEADER pSection; 201 DWORD importsStartRVA; 202 203 pImageBase = (PBYTE) &__ImageBase; 204 if (! _ValidateImageBase (pImageBase)) 205 return NULL; 206 207 pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew); 208 209 importsStartRVA = pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress; 210 if (!importsStartRVA) 211 return NULL; 212 213 pSection = _FindPESection (pImageBase, importsStartRVA); 214 if (!pSection) 215 return NULL; 216 217 importDesc = (PIMAGE_IMPORT_DESCRIPTOR) (pImageBase + importsStartRVA); 218 if (!importDesc) 219 return NULL; 220 221 for (;;) 222 { 223 if (importDesc->TimeDateStamp == 0 && importDesc->Name == 0) 224 break; 225 226 if (i <= 0) 227 return (char *) (pImageBase + importDesc->Name); 228 --i; 229 importDesc++; 230 } 231 232 return NULL; 233 } 234 235 HMODULE __mingw_get_msvcrt_handle(void); 236 HMODULE __mingw_get_msvcrt_handle(void) 237 { 238 static HANDLE msvcrt_handle; 239 240 if(!msvcrt_handle) { 241 const char *lib_name; 242 int i = 0; 243 244 while ((lib_name = __mingw_enum_import_library_names (i++))) { 245 if((lib_name[0] == 'm' || lib_name[0] == 'M') 246 && (lib_name[1] == 's' || lib_name[1] == 'S') 247 && (lib_name[2] == 'v' || lib_name[2] == 'V') 248 && (lib_name[3] == 'c' || lib_name[3] == 'C') 249 && (lib_name[4] == 'r' || lib_name[4] == 'R') 250 && (lib_name[5] == 't' || lib_name[5] == 'T' || ('0' <= lib_name[5] && lib_name[5] <= '9'))) 251 break; 252 } 253 254 if(lib_name) 255 msvcrt_handle = GetModuleHandleA(lib_name); 256 if(!msvcrt_handle) 257 msvcrt_handle = LoadLibraryW(L"msvcrt.dll"); 258 } 259 260 return msvcrt_handle; 261 } 262