Kai Tietz | fb59d4e | 2009-01-27 10:33:31 +0000 | [diff] [blame] | 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. |
Kai Tietz | fa0cfe3 | 2010-01-15 20:02:21 +0000 | [diff] [blame] | 4 | * No warranty is given; refer to the file DISCLAIMER.PD within this package. |
Kai Tietz | fb59d4e | 2009-01-27 10:33:31 +0000 | [diff] [blame] | 5 | */ |
| 6 | |
Kai Tietz | 518dd33 | 2007-08-10 09:54:15 +0000 | [diff] [blame] | 7 | #include <windows.h> |
Kai Tietz | d7a421a | 2009-09-04 20:05:52 +0000 | [diff] [blame] | 8 | #include <string.h> |
Kai Tietz | 518dd33 | 2007-08-10 09:54:15 +0000 | [diff] [blame] | 9 | |
| 10 | #if defined (_WIN64) && defined (__ia64__) |
Kai Tietz | 6316d1a | 2007-11-03 09:31:00 +0000 | [diff] [blame] | 11 | #error FIXME: Unsupported __ImageBase implementation. |
Kai Tietz | 518dd33 | 2007-08-10 09:54:15 +0000 | [diff] [blame] | 12 | #else |
Kai Tietz | 50c6c30 | 2007-11-03 09:33:37 +0000 | [diff] [blame] | 13 | /* Hack, for bug in ld. Will be removed soon. */ |
Kai Tietz | 4ebdc9d | 2009-10-19 12:58:40 +0000 | [diff] [blame] | 14 | #define __ImageBase __MINGW_LSYMBOL(_image_base__) |
Kai Tietz | 518dd33 | 2007-08-10 09:54:15 +0000 | [diff] [blame] | 15 | /* This symbol is defined by the linker. */ |
Kai Tietz | 6316d1a | 2007-11-03 09:31:00 +0000 | [diff] [blame] | 16 | extern IMAGE_DOS_HEADER __ImageBase; |
Kai Tietz | 518dd33 | 2007-08-10 09:54:15 +0000 | [diff] [blame] | 17 | #endif |
| 18 | |
Kai Tietz | abfff81 | 2009-12-04 19:30:35 +0000 | [diff] [blame] | 19 | WINBOOL _ValidateImageBase (PBYTE); |
Kai Tietz | 699a2e7 | 2009-08-23 07:19:19 +0000 | [diff] [blame] | 20 | |
Kai Tietz | abfff81 | 2009-12-04 19:30:35 +0000 | [diff] [blame] | 21 | WINBOOL |
Kai Tietz | 518dd33 | 2007-08-10 09:54:15 +0000 | [diff] [blame] | 22 | _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 Tietz | 699a2e7 | 2009-08-23 07:19:19 +0000 | [diff] [blame] | 40 | PIMAGE_SECTION_HEADER _FindPESection (PBYTE, DWORD_PTR); |
| 41 | |
Kai Tietz | 518dd33 | 2007-08-10 09:54:15 +0000 | [diff] [blame] | 42 | PIMAGE_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 Tietz | d7a421a | 2009-09-04 20:05:52 +0000 | [diff] [blame] | 62 | PIMAGE_SECTION_HEADER _FindPESectionByName (const char *); |
| 63 | |
| 64 | PIMAGE_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 | |
| 92 | PIMAGE_SECTION_HEADER _FindPESectionExec (size_t); |
| 93 | |
| 94 | PIMAGE_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 | |
| 122 | PBYTE _GetPEImageBase (void); |
| 123 | |
| 124 | PBYTE |
| 125 | _GetPEImageBase (void) |
| 126 | { |
| 127 | PBYTE pImageBase; |
| 128 | pImageBase = (PBYTE) &__ImageBase; |
| 129 | if (! _ValidateImageBase (pImageBase)) |
| 130 | return NULL; |
| 131 | return pImageBase; |
| 132 | } |
| 133 | |
Kai Tietz | abfff81 | 2009-12-04 19:30:35 +0000 | [diff] [blame] | 134 | WINBOOL _IsNonwritableInCurrentImage (PBYTE); |
Kai Tietz | 699a2e7 | 2009-08-23 07:19:19 +0000 | [diff] [blame] | 135 | |
Kai Tietz | abfff81 | 2009-12-04 19:30:35 +0000 | [diff] [blame] | 136 | WINBOOL |
Kai Tietz | 518dd33 | 2007-08-10 09:54:15 +0000 | [diff] [blame] | 137 | _IsNonwritableInCurrentImage (PBYTE pTarget) |
| 138 | { |
| 139 | PBYTE pImageBase; |
| 140 | DWORD_PTR rvaTarget; |
| 141 | PIMAGE_SECTION_HEADER pSection; |
| 142 | |
Kai Tietz | 6316d1a | 2007-11-03 09:31:00 +0000 | [diff] [blame] | 143 | pImageBase = (PBYTE) &__ImageBase; |
Kai Tietz | 518dd33 | 2007-08-10 09:54:15 +0000 | [diff] [blame] | 144 | 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 | } |