xref: /reactos/sdk/lib/crt/startup/pesect.c (revision 845faec4)
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