blob: 60bbbc4c0d0643ac18ee01035c65475f90fa4f7b [file] [log] [blame]
Kai Tietzfb59d4e2009-01-27 10:33:31 +00001/**
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.
Kai Tietzfa0cfe32010-01-15 20:02:21 +00004 * No warranty is given; refer to the file DISCLAIMER.PD within this package.
Kai Tietzfb59d4e2009-01-27 10:33:31 +00005 */
6
Kai Tietz518dd332007-08-10 09:54:15 +00007#include <windows.h>
Kai Tietzd7a421a2009-09-04 20:05:52 +00008#include <string.h>
Kai Tietz518dd332007-08-10 09:54:15 +00009
10#if defined (_WIN64) && defined (__ia64__)
Kai Tietz6316d1a2007-11-03 09:31:00 +000011#error FIXME: Unsupported __ImageBase implementation.
Kai Tietz518dd332007-08-10 09:54:15 +000012#else
Kai Tietz50c6c302007-11-03 09:33:37 +000013/* Hack, for bug in ld. Will be removed soon. */
Kai Tietz4ebdc9d2009-10-19 12:58:40 +000014#define __ImageBase __MINGW_LSYMBOL(_image_base__)
Kai Tietz518dd332007-08-10 09:54:15 +000015/* This symbol is defined by the linker. */
Kai Tietz6316d1a2007-11-03 09:31:00 +000016extern IMAGE_DOS_HEADER __ImageBase;
Kai Tietz518dd332007-08-10 09:54:15 +000017#endif
18
Kai Tietzabfff812009-12-04 19:30:35 +000019WINBOOL _ValidateImageBase (PBYTE);
Kai Tietz699a2e72009-08-23 07:19:19 +000020
Kai Tietzabfff812009-12-04 19:30:35 +000021WINBOOL
Kai Tietz518dd332007-08-10 09:54:15 +000022_ValidateImageBase (PBYTE pImageBase)
23{
24 PIMAGE_DOS_HEADER pDOSHeader;
25 PIMAGE_NT_HEADERS pNTHeader;
26 PIMAGE_OPTIONAL_HEADER pOptHeader;
27
28 pDOSHeader = (PIMAGE_DOS_HEADER) pImageBase;
29 if (pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE)
30 return FALSE;
31 pNTHeader = (PIMAGE_NT_HEADERS) ((PBYTE) pDOSHeader + pDOSHeader->e_lfanew);
32 if (pNTHeader->Signature != IMAGE_NT_SIGNATURE)
33 return FALSE;
34 pOptHeader = (PIMAGE_OPTIONAL_HEADER) &pNTHeader->OptionalHeader;
35 if (pOptHeader->Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC)
36 return FALSE;
37 return TRUE;
38}
39
Kai Tietz699a2e72009-08-23 07:19:19 +000040PIMAGE_SECTION_HEADER _FindPESection (PBYTE, DWORD_PTR);
41
Kai Tietz518dd332007-08-10 09:54:15 +000042PIMAGE_SECTION_HEADER
43_FindPESection (PBYTE pImageBase, DWORD_PTR rva)
44{
45 PIMAGE_NT_HEADERS pNTHeader;
46 PIMAGE_SECTION_HEADER pSection;
47 unsigned int iSection;
48
49 pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew);
50
51 for (iSection = 0, pSection = IMAGE_FIRST_SECTION (pNTHeader);
52 iSection < pNTHeader->FileHeader.NumberOfSections;
53 ++iSection,++pSection)
54 {
55 if (rva >= pSection->VirtualAddress
56 && rva < pSection->VirtualAddress + pSection->Misc.VirtualSize)
57 return pSection;
58 }
59 return NULL;
60}
61
Kai Tietzd7a421a2009-09-04 20:05:52 +000062PIMAGE_SECTION_HEADER _FindPESectionByName (const char *);
63
64PIMAGE_SECTION_HEADER
65_FindPESectionByName (const char *pName)
66{
67 PBYTE pImageBase;
68 PIMAGE_NT_HEADERS pNTHeader;
69 PIMAGE_SECTION_HEADER pSection;
70 unsigned int iSection;
71
72 /* Long names aren't supported. */
73 if (strlen (pName) > IMAGE_SIZEOF_SHORT_NAME)
74 return NULL;
75
76 pImageBase = (PBYTE) &__ImageBase;
77 if (! _ValidateImageBase (pImageBase))
78 return NULL;
79
80 pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew);
81
82 for (iSection = 0, pSection = IMAGE_FIRST_SECTION (pNTHeader);
83 iSection < pNTHeader->FileHeader.NumberOfSections;
84 ++iSection,++pSection)
85 {
86 if (!strncmp ((char *) &pSection->Name[0], pName, IMAGE_SIZEOF_SHORT_NAME))
87 return pSection;
88 }
89 return NULL;
90}
91
92PIMAGE_SECTION_HEADER _FindPESectionExec (size_t);
93
94PIMAGE_SECTION_HEADER
95_FindPESectionExec (size_t eNo)
96{
97 PBYTE pImageBase;
98 PIMAGE_NT_HEADERS pNTHeader;
99 PIMAGE_SECTION_HEADER pSection;
100 unsigned int iSection;
101
102 pImageBase = (PBYTE) &__ImageBase;
103 if (! _ValidateImageBase (pImageBase))
104 return NULL;
105
106 pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew);
107
108 for (iSection = 0, pSection = IMAGE_FIRST_SECTION (pNTHeader);
109 iSection < pNTHeader->FileHeader.NumberOfSections;
110 ++iSection,++pSection)
111 {
112 if ((pSection->Characteristics & IMAGE_SCN_MEM_EXECUTE) != 0)
113 {
114 if (!eNo)
115 return pSection;
116 --eNo;
117 }
118 }
119 return NULL;
120}
121
122PBYTE _GetPEImageBase (void);
123
124PBYTE
125_GetPEImageBase (void)
126{
127 PBYTE pImageBase;
128 pImageBase = (PBYTE) &__ImageBase;
129 if (! _ValidateImageBase (pImageBase))
130 return NULL;
131 return pImageBase;
132}
133
Kai Tietzabfff812009-12-04 19:30:35 +0000134WINBOOL _IsNonwritableInCurrentImage (PBYTE);
Kai Tietz699a2e72009-08-23 07:19:19 +0000135
Kai Tietzabfff812009-12-04 19:30:35 +0000136WINBOOL
Kai Tietz518dd332007-08-10 09:54:15 +0000137_IsNonwritableInCurrentImage (PBYTE pTarget)
138{
139 PBYTE pImageBase;
140 DWORD_PTR rvaTarget;
141 PIMAGE_SECTION_HEADER pSection;
142
Kai Tietz6316d1a2007-11-03 09:31:00 +0000143 pImageBase = (PBYTE) &__ImageBase;
Kai Tietz518dd332007-08-10 09:54:15 +0000144 if (! _ValidateImageBase (pImageBase))
145 return FALSE;
146 rvaTarget = pTarget - pImageBase;
147 pSection = _FindPESection (pImageBase, rvaTarget);
148 if (pSection == NULL)
149 return FALSE;
150 return (pSection->Characteristics & IMAGE_SCN_MEM_WRITE) == 0;
151}