mirror of
https://github.com/reactos/reactos.git
synced 2024-08-30 23:28:58 +00:00
262 lines
6.6 KiB
C
262 lines
6.6 KiB
C
/**
|
|
* This file has no copyright assigned and is placed in the Public Domain.
|
|
* This file is part of the w64 mingw-runtime package.
|
|
* No warranty is given; refer to the file DISCLAIMER.PD within this package.
|
|
*/
|
|
|
|
//#include <windows.h>
|
|
#include <stdarg.h>
|
|
#include <windef.h>
|
|
#include <winbase.h>
|
|
#include <string.h>
|
|
|
|
#if defined (_WIN64) && defined (__ia64__)
|
|
#error FIXME: Unsupported __ImageBase implementation.
|
|
#else
|
|
#ifdef __GNUC__
|
|
/* Hack, for bug in ld. Will be removed soon. */
|
|
#define __ImageBase __MINGW_LSYMBOL(_image_base__)
|
|
#endif
|
|
/* This symbol is defined by the linker. */
|
|
extern IMAGE_DOS_HEADER __ImageBase;
|
|
#endif
|
|
|
|
WINBOOL _ValidateImageBase (PBYTE);
|
|
|
|
WINBOOL
|
|
_ValidateImageBase (PBYTE pImageBase)
|
|
{
|
|
PIMAGE_DOS_HEADER pDOSHeader;
|
|
PIMAGE_NT_HEADERS pNTHeader;
|
|
PIMAGE_OPTIONAL_HEADER pOptHeader;
|
|
|
|
pDOSHeader = (PIMAGE_DOS_HEADER) pImageBase;
|
|
if (pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE)
|
|
return FALSE;
|
|
pNTHeader = (PIMAGE_NT_HEADERS) ((PBYTE) pDOSHeader + pDOSHeader->e_lfanew);
|
|
if (pNTHeader->Signature != IMAGE_NT_SIGNATURE)
|
|
return FALSE;
|
|
pOptHeader = (PIMAGE_OPTIONAL_HEADER) &pNTHeader->OptionalHeader;
|
|
if (pOptHeader->Magic != IMAGE_NT_OPTIONAL_HDR_MAGIC)
|
|
return FALSE;
|
|
return TRUE;
|
|
}
|
|
|
|
PIMAGE_SECTION_HEADER _FindPESection (PBYTE, DWORD_PTR);
|
|
|
|
PIMAGE_SECTION_HEADER
|
|
_FindPESection (PBYTE pImageBase, DWORD_PTR rva)
|
|
{
|
|
PIMAGE_NT_HEADERS pNTHeader;
|
|
PIMAGE_SECTION_HEADER pSection;
|
|
unsigned int iSection;
|
|
|
|
pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew);
|
|
|
|
for (iSection = 0, pSection = IMAGE_FIRST_SECTION (pNTHeader);
|
|
iSection < pNTHeader->FileHeader.NumberOfSections;
|
|
++iSection,++pSection)
|
|
{
|
|
if (rva >= pSection->VirtualAddress
|
|
&& rva < pSection->VirtualAddress + pSection->Misc.VirtualSize)
|
|
return pSection;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
PIMAGE_SECTION_HEADER _FindPESectionByName (const char *);
|
|
|
|
PIMAGE_SECTION_HEADER
|
|
_FindPESectionByName (const char *pName)
|
|
{
|
|
PBYTE pImageBase;
|
|
PIMAGE_NT_HEADERS pNTHeader;
|
|
PIMAGE_SECTION_HEADER pSection;
|
|
unsigned int iSection;
|
|
|
|
/* Long names aren't supported. */
|
|
if (strlen (pName) > IMAGE_SIZEOF_SHORT_NAME)
|
|
return NULL;
|
|
|
|
pImageBase = (PBYTE) &__ImageBase;
|
|
if (! _ValidateImageBase (pImageBase))
|
|
return NULL;
|
|
|
|
pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew);
|
|
|
|
for (iSection = 0, pSection = IMAGE_FIRST_SECTION (pNTHeader);
|
|
iSection < pNTHeader->FileHeader.NumberOfSections;
|
|
++iSection,++pSection)
|
|
{
|
|
if (!strncmp ((char *) &pSection->Name[0], pName, IMAGE_SIZEOF_SHORT_NAME))
|
|
return pSection;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
int __mingw_GetSectionCount (void);
|
|
PIMAGE_SECTION_HEADER __mingw_GetSectionForAddress (LPVOID p);
|
|
|
|
PIMAGE_SECTION_HEADER
|
|
__mingw_GetSectionForAddress (LPVOID p)
|
|
{
|
|
PBYTE pImageBase;
|
|
DWORD_PTR rva;
|
|
|
|
pImageBase = (PBYTE) &__ImageBase;
|
|
if (! _ValidateImageBase (pImageBase))
|
|
return NULL;
|
|
|
|
rva = (DWORD_PTR) (((PBYTE) p) - pImageBase);
|
|
return _FindPESection (pImageBase, rva);
|
|
}
|
|
|
|
int
|
|
__mingw_GetSectionCount (void)
|
|
{
|
|
PBYTE pImageBase;
|
|
PIMAGE_NT_HEADERS pNTHeader;
|
|
|
|
pImageBase = (PBYTE) &__ImageBase;
|
|
if (! _ValidateImageBase (pImageBase))
|
|
return 0;
|
|
|
|
pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew);
|
|
|
|
return (int) pNTHeader->FileHeader.NumberOfSections;
|
|
}
|
|
|
|
|
|
PIMAGE_SECTION_HEADER _FindPESectionExec (size_t);
|
|
|
|
PIMAGE_SECTION_HEADER
|
|
_FindPESectionExec (size_t eNo)
|
|
{
|
|
PBYTE pImageBase;
|
|
PIMAGE_NT_HEADERS pNTHeader;
|
|
PIMAGE_SECTION_HEADER pSection;
|
|
unsigned int iSection;
|
|
|
|
pImageBase = (PBYTE) &__ImageBase;
|
|
if (! _ValidateImageBase (pImageBase))
|
|
return NULL;
|
|
|
|
pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew);
|
|
|
|
for (iSection = 0, pSection = IMAGE_FIRST_SECTION (pNTHeader);
|
|
iSection < pNTHeader->FileHeader.NumberOfSections;
|
|
++iSection,++pSection)
|
|
{
|
|
if ((pSection->Characteristics & IMAGE_SCN_MEM_EXECUTE) != 0)
|
|
{
|
|
if (!eNo)
|
|
return pSection;
|
|
--eNo;
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
PBYTE _GetPEImageBase (void);
|
|
|
|
PBYTE
|
|
_GetPEImageBase (void)
|
|
{
|
|
PBYTE pImageBase;
|
|
pImageBase = (PBYTE) &__ImageBase;
|
|
if (! _ValidateImageBase (pImageBase))
|
|
return NULL;
|
|
return pImageBase;
|
|
}
|
|
|
|
WINBOOL _IsNonwritableInCurrentImage (PBYTE);
|
|
|
|
WINBOOL
|
|
_IsNonwritableInCurrentImage (PBYTE pTarget)
|
|
{
|
|
PBYTE pImageBase;
|
|
DWORD_PTR rvaTarget;
|
|
PIMAGE_SECTION_HEADER pSection;
|
|
|
|
pImageBase = (PBYTE) &__ImageBase;
|
|
if (! _ValidateImageBase (pImageBase))
|
|
return FALSE;
|
|
rvaTarget = pTarget - pImageBase;
|
|
pSection = _FindPESection (pImageBase, rvaTarget);
|
|
if (pSection == NULL)
|
|
return FALSE;
|
|
return (pSection->Characteristics & IMAGE_SCN_MEM_WRITE) == 0;
|
|
}
|
|
|
|
const char *
|
|
__mingw_enum_import_library_names (int);
|
|
|
|
const char *
|
|
__mingw_enum_import_library_names (int i)
|
|
{
|
|
PBYTE pImageBase;
|
|
PIMAGE_NT_HEADERS pNTHeader;
|
|
PIMAGE_IMPORT_DESCRIPTOR importDesc;
|
|
PIMAGE_SECTION_HEADER pSection;
|
|
DWORD importsStartRVA;
|
|
|
|
pImageBase = (PBYTE) &__ImageBase;
|
|
if (! _ValidateImageBase (pImageBase))
|
|
return NULL;
|
|
|
|
pNTHeader = (PIMAGE_NT_HEADERS) (pImageBase + ((PIMAGE_DOS_HEADER) pImageBase)->e_lfanew);
|
|
|
|
importsStartRVA = pNTHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
|
|
if (!importsStartRVA)
|
|
return NULL;
|
|
|
|
pSection = _FindPESection (pImageBase, importsStartRVA);
|
|
if (!pSection)
|
|
return NULL;
|
|
|
|
importDesc = (PIMAGE_IMPORT_DESCRIPTOR) (pImageBase + importsStartRVA);
|
|
if (!importDesc)
|
|
return NULL;
|
|
|
|
for (;;)
|
|
{
|
|
if (importDesc->TimeDateStamp == 0 && importDesc->Name == 0)
|
|
break;
|
|
|
|
if (i <= 0)
|
|
return (char *) (pImageBase + importDesc->Name);
|
|
--i;
|
|
importDesc++;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
HMODULE __mingw_get_msvcrt_handle(void);
|
|
HMODULE __mingw_get_msvcrt_handle(void)
|
|
{
|
|
static HANDLE msvcrt_handle;
|
|
|
|
if(!msvcrt_handle) {
|
|
const char *lib_name;
|
|
int i = 0;
|
|
|
|
while ((lib_name = __mingw_enum_import_library_names (i++))) {
|
|
if((lib_name[0] == 'm' || lib_name[0] == 'M')
|
|
&& (lib_name[1] == 's' || lib_name[1] == 'S')
|
|
&& (lib_name[2] == 'v' || lib_name[2] == 'V')
|
|
&& (lib_name[3] == 'c' || lib_name[3] == 'C')
|
|
&& (lib_name[4] == 'r' || lib_name[4] == 'R')
|
|
&& (lib_name[5] == 't' || lib_name[5] == 'T' || ('0' <= lib_name[5] && lib_name[5] <= '9')))
|
|
break;
|
|
}
|
|
|
|
if(lib_name)
|
|
msvcrt_handle = GetModuleHandleA(lib_name);
|
|
if(!msvcrt_handle)
|
|
msvcrt_handle = LoadLibraryW(L"msvcrt.dll");
|
|
}
|
|
|
|
return msvcrt_handle;
|
|
}
|