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}