master
1/**
2 * This file has no copyright assigned and is placed in the Public Domain.
3 * This file is part of the mingw-w64 runtime package.
4 * No warranty is given; refer to the file DISCLAIMER.PD within this package.
5 */
6
7#include <windows.h>
8#include <string.h>
9
10extern IMAGE_DOS_HEADER __ImageBase;
11
12WINBOOL _ValidateImageBase (PBYTE);
13
14WINBOOL
15_ValidateImageBase (PBYTE pImageBase)
16{
17 PIMAGE_DOS_HEADER pDOSHeader;
18 PIMAGE_NT_HEADERS pNTHeader;
19 PIMAGE_OPTIONAL_HEADER pOptHeader;
20
21 pDOSHeader = (PIMAGE_DOS_HEADER) pImageBase;
22 if (pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE)
23 return FALSE;
24 pNTHeader = (PIMAGE_NT_HEADERS) ((PBYTE) pDOSHeader + pDOSHeader->e_lfanew);
25 if (pNTHeader->Signature != IMAGE_NT_SIGNATURE)
26 return FALSE;
27 pOptHeader = (PIMAGE_OPTIONAL_HEADER) &pNTHeader->OptionalHeader;
28 if (pOptHeader->Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC)
29 return FALSE;
30 return TRUE;
31}
32
33PIMAGE_SECTION_HEADER _FindPESection (PBYTE, DWORD_PTR);
34
35PIMAGE_SECTION_HEADER
36_FindPESection (PBYTE pImageBase, DWORD_PTR rva)
37{
38 PIMAGE_NT_HEADERS pNTHeader;
39 PIMAGE_SECTION_HEADER pSection;
40 unsigned int iSection;
41
42 pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew);
43
44 for (iSection = 0, pSection = IMAGE_FIRST_SECTION (pNTHeader);
45 iSection < pNTHeader->FileHeader.NumberOfSections;
46 ++iSection,++pSection)
47 {
48 if (rva >= pSection->VirtualAddress
49 && rva < pSection->VirtualAddress + pSection->Misc.VirtualSize)
50 return pSection;
51 }
52 return NULL;
53}
54
55PIMAGE_SECTION_HEADER _FindPESectionByName (const char *);
56
57PIMAGE_SECTION_HEADER
58_FindPESectionByName (const char *pName)
59{
60 PBYTE pImageBase;
61 PIMAGE_NT_HEADERS pNTHeader;
62 PIMAGE_SECTION_HEADER pSection;
63 unsigned int iSection;
64
65 /* Long names aren't supported. */
66 if (strlen (pName) > IMAGE_SIZEOF_SHORT_NAME)
67 return NULL;
68
69 pImageBase = (PBYTE) &__ImageBase;
70 if (! _ValidateImageBase (pImageBase))
71 return NULL;
72
73 pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew);
74
75 for (iSection = 0, pSection = IMAGE_FIRST_SECTION (pNTHeader);
76 iSection < pNTHeader->FileHeader.NumberOfSections;
77 ++iSection,++pSection)
78 {
79 if (!strncmp ((char *) &pSection->Name[0], pName, IMAGE_SIZEOF_SHORT_NAME))
80 return pSection;
81 }
82 return NULL;
83}
84
85int __mingw_GetSectionCount (void);
86PIMAGE_SECTION_HEADER __mingw_GetSectionForAddress (LPVOID p);
87
88PIMAGE_SECTION_HEADER
89__mingw_GetSectionForAddress (LPVOID p)
90{
91 PBYTE pImageBase;
92 DWORD_PTR rva;
93
94 pImageBase = (PBYTE) &__ImageBase;
95 if (! _ValidateImageBase (pImageBase))
96 return NULL;
97
98 rva = (DWORD_PTR) (((PBYTE) p) - pImageBase);
99 return _FindPESection (pImageBase, rva);
100}
101
102int
103__mingw_GetSectionCount (void)
104{
105 PBYTE pImageBase;
106 PIMAGE_NT_HEADERS pNTHeader;
107
108 pImageBase = (PBYTE) &__ImageBase;
109 if (! _ValidateImageBase (pImageBase))
110 return 0;
111
112 pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew);
113
114 return (int) pNTHeader->FileHeader.NumberOfSections;
115}
116
117
118PIMAGE_SECTION_HEADER _FindPESectionExec (size_t);
119
120PIMAGE_SECTION_HEADER
121_FindPESectionExec (size_t eNo)
122{
123 PBYTE pImageBase;
124 PIMAGE_NT_HEADERS pNTHeader;
125 PIMAGE_SECTION_HEADER pSection;
126 unsigned int iSection;
127
128 pImageBase = (PBYTE) &__ImageBase;
129 if (! _ValidateImageBase (pImageBase))
130 return NULL;
131
132 pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew);
133
134 for (iSection = 0, pSection = IMAGE_FIRST_SECTION (pNTHeader);
135 iSection < pNTHeader->FileHeader.NumberOfSections;
136 ++iSection,++pSection)
137 {
138 if ((pSection->Characteristics & IMAGE_SCN_MEM_EXECUTE) != 0)
139 {
140 if (!eNo)
141 return pSection;
142 --eNo;
143 }
144 }
145 return NULL;
146}
147
148PBYTE _GetPEImageBase (void);
149
150PBYTE
151_GetPEImageBase (void)
152{
153 PBYTE pImageBase;
154 pImageBase = (PBYTE) &__ImageBase;
155 if (! _ValidateImageBase (pImageBase))
156 return NULL;
157 return pImageBase;
158}
159
160WINBOOL _IsNonwritableInCurrentImage (PBYTE);
161
162WINBOOL
163_IsNonwritableInCurrentImage (PBYTE pTarget)
164{
165 PBYTE pImageBase;
166 DWORD_PTR rvaTarget;
167 PIMAGE_SECTION_HEADER pSection;
168
169 pImageBase = (PBYTE) &__ImageBase;
170 if (! _ValidateImageBase (pImageBase))
171 return FALSE;
172 rvaTarget = pTarget - pImageBase;
173 pSection = _FindPESection (pImageBase, rvaTarget);
174 if (pSection == NULL)
175 return FALSE;
176 return (pSection->Characteristics & IMAGE_SCN_MEM_WRITE) == 0;
177}
178
179const char *
180__mingw_enum_import_library_names (int);
181
182const char *
183__mingw_enum_import_library_names (int i)
184{
185 PBYTE pImageBase;
186 PIMAGE_NT_HEADERS pNTHeader;
187 PIMAGE_IMPORT_DESCRIPTOR importDesc;
188 PIMAGE_SECTION_HEADER pSection;
189 DWORD importsStartRVA;
190
191 pImageBase = (PBYTE) &__ImageBase;
192 if (! _ValidateImageBase (pImageBase))
193 return NULL;
194
195 pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew);
196
197 importsStartRVA = pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
198 if (!importsStartRVA)
199 return NULL;
200
201 pSection = _FindPESection (pImageBase, importsStartRVA);
202 if (!pSection)
203 return NULL;
204
205 importDesc = (PIMAGE_IMPORT_DESCRIPTOR) (pImageBase + importsStartRVA);
206 if (!importDesc)
207 return NULL;
208
209 for (;;)
210 {
211 if (importDesc->TimeDateStamp == 0 && importDesc->Name == 0)
212 break;
213
214 if (i <= 0)
215 return (char *) (pImageBase + importDesc->Name);
216 --i;
217 importDesc++;
218 }
219
220 return NULL;
221}