Implemented the RtlImage* functions, and use them to replace the
PE_HEADER macro.
This commit is contained in:
parent
3d8b123e5a
commit
a5dea216cc
|
@ -68,3 +68,83 @@ NTSTATUS WINAPI LdrGetProcedureAddress(PVOID base, PANSI_STRING name, ULONG ord,
|
||||||
|
|
||||||
return (*address) ? STATUS_SUCCESS : STATUS_DLL_NOT_FOUND;
|
return (*address) ? STATUS_SUCCESS : STATUS_DLL_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* RtlImageNtHeader (NTDLL.@)
|
||||||
|
*/
|
||||||
|
PIMAGE_NT_HEADERS WINAPI RtlImageNtHeader(HMODULE hModule)
|
||||||
|
{
|
||||||
|
IMAGE_NT_HEADERS *ret = NULL;
|
||||||
|
IMAGE_DOS_HEADER *dos = (IMAGE_DOS_HEADER *)hModule;
|
||||||
|
|
||||||
|
if (dos->e_magic == IMAGE_DOS_SIGNATURE)
|
||||||
|
{
|
||||||
|
ret = (IMAGE_NT_HEADERS *)((char *)dos + dos->e_lfanew);
|
||||||
|
if (ret->Signature != IMAGE_NT_SIGNATURE) ret = NULL;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* RtlImageDirectoryEntryToData (NTDLL.@)
|
||||||
|
*/
|
||||||
|
PVOID WINAPI RtlImageDirectoryEntryToData( HMODULE module, BOOL image, WORD dir, ULONG *size )
|
||||||
|
{
|
||||||
|
const IMAGE_NT_HEADERS *nt;
|
||||||
|
DWORD addr;
|
||||||
|
|
||||||
|
if ((ULONG_PTR)module & 1) /* mapped as data file */
|
||||||
|
{
|
||||||
|
module = (HMODULE)((ULONG_PTR)module & ~1);
|
||||||
|
image = FALSE;
|
||||||
|
}
|
||||||
|
if (!(nt = RtlImageNtHeader( module ))) return NULL;
|
||||||
|
if (dir >= nt->OptionalHeader.NumberOfRvaAndSizes) return NULL;
|
||||||
|
if (!(addr = nt->OptionalHeader.DataDirectory[dir].VirtualAddress)) return NULL;
|
||||||
|
*size = nt->OptionalHeader.DataDirectory[dir].Size;
|
||||||
|
if (image || addr < nt->OptionalHeader.SizeOfHeaders) return (char *)module + addr;
|
||||||
|
|
||||||
|
/* not mapped as image, need to find the section containing the virtual address */
|
||||||
|
return RtlImageRvaToVa( nt, module, addr, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* RtlImageRvaToSection (NTDLL.@)
|
||||||
|
*/
|
||||||
|
PIMAGE_SECTION_HEADER WINAPI RtlImageRvaToSection( const IMAGE_NT_HEADERS *nt,
|
||||||
|
HMODULE module, DWORD rva )
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
IMAGE_SECTION_HEADER *sec = (IMAGE_SECTION_HEADER*)((char*)&nt->OptionalHeader +
|
||||||
|
nt->FileHeader.SizeOfOptionalHeader);
|
||||||
|
for (i = 0; i < nt->FileHeader.NumberOfSections; i++, sec++)
|
||||||
|
{
|
||||||
|
if ((sec->VirtualAddress <= rva) && (sec->VirtualAddress + sec->SizeOfRawData > rva))
|
||||||
|
return sec;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* RtlImageRvaToVa (NTDLL.@)
|
||||||
|
*/
|
||||||
|
PVOID WINAPI RtlImageRvaToVa( const IMAGE_NT_HEADERS *nt, HMODULE module,
|
||||||
|
DWORD rva, IMAGE_SECTION_HEADER **section )
|
||||||
|
{
|
||||||
|
IMAGE_SECTION_HEADER *sec;
|
||||||
|
|
||||||
|
if (section && *section) /* try this section first */
|
||||||
|
{
|
||||||
|
sec = *section;
|
||||||
|
if ((sec->VirtualAddress <= rva) && (sec->VirtualAddress + sec->SizeOfRawData > rva))
|
||||||
|
goto found;
|
||||||
|
}
|
||||||
|
if (!(sec = RtlImageRvaToSection( nt, module, rva ))) return NULL;
|
||||||
|
found:
|
||||||
|
if (section) *section = sec;
|
||||||
|
return (char *)module + sec->PointerToRawData + (rva - sec->VirtualAddress);
|
||||||
|
}
|
||||||
|
|
|
@ -403,8 +403,10 @@
|
||||||
@ stdcall RtlGetSaclSecurityDescriptor(ptr ptr ptr ptr)RtlGetSaclSecurityDescriptor
|
@ stdcall RtlGetSaclSecurityDescriptor(ptr ptr ptr ptr)RtlGetSaclSecurityDescriptor
|
||||||
@ stub RtlGetUserInfoHeap
|
@ stub RtlGetUserInfoHeap
|
||||||
@ stdcall RtlIdentifierAuthoritySid(ptr) RtlIdentifierAuthoritySid
|
@ stdcall RtlIdentifierAuthoritySid(ptr) RtlIdentifierAuthoritySid
|
||||||
@ stub RtlImageDirectoryEntryToData
|
@ stdcall RtlImageDirectoryEntryToData(long long long ptr) RtlImageDirectoryEntryToData
|
||||||
@ stdcall RtlImageNtHeader(long) RtlImageNtHeader
|
@ stdcall RtlImageNtHeader(long) RtlImageNtHeader
|
||||||
|
@ stdcall RtlImageRvaToSection(ptr long long) RtlImageRvaToSection
|
||||||
|
@ stdcall RtlImageRvaToVa(ptr long long ptr) RtlImageRvaToVa
|
||||||
@ stdcall RtlImpersonateSelf(long) RtlImpersonateSelf
|
@ stdcall RtlImpersonateSelf(long) RtlImpersonateSelf
|
||||||
@ stdcall RtlInitAnsiString(ptr str) RtlInitAnsiString
|
@ stdcall RtlInitAnsiString(ptr str) RtlInitAnsiString
|
||||||
@ stub RtlInitCodePageTable
|
@ stub RtlInitCodePageTable
|
||||||
|
|
|
@ -346,23 +346,6 @@ BOOLEAN WINAPI RtlDosPathNameToNtPathName_U(
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
|
||||||
* RtlImageNtHeader (NTDLL.@)
|
|
||||||
*/
|
|
||||||
PIMAGE_NT_HEADERS WINAPI RtlImageNtHeader(HMODULE hModule)
|
|
||||||
{
|
|
||||||
IMAGE_NT_HEADERS *ret = NULL;
|
|
||||||
IMAGE_DOS_HEADER *dos = (IMAGE_DOS_HEADER *)hModule;
|
|
||||||
|
|
||||||
if (dos->e_magic == IMAGE_DOS_SIGNATURE)
|
|
||||||
{
|
|
||||||
ret = (IMAGE_NT_HEADERS *)((char *)dos + dos->e_lfanew);
|
|
||||||
if (ret->Signature != IMAGE_NT_SIGNATURE) ret = NULL;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* RtlCreateEnvironment [NTDLL.@]
|
* RtlCreateEnvironment [NTDLL.@]
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -170,13 +170,6 @@ extern WINE_MODREF *MODULE_modref_list;
|
||||||
#define NE_MODULE_NAME(pModule) \
|
#define NE_MODULE_NAME(pModule) \
|
||||||
(((OFSTRUCT *)((char*)(pModule) + (pModule)->fileinfo))->szPathName)
|
(((OFSTRUCT *)((char*)(pModule) + (pModule)->fileinfo))->szPathName)
|
||||||
|
|
||||||
#define PE_HEADER(module) \
|
|
||||||
((IMAGE_NT_HEADERS*)((LPBYTE)(module) + \
|
|
||||||
(((IMAGE_DOS_HEADER*)(module))->e_lfanew)))
|
|
||||||
|
|
||||||
#define PE_SECTIONS(module) \
|
|
||||||
((IMAGE_SECTION_HEADER*)((LPBYTE)&PE_HEADER(module)->OptionalHeader + \
|
|
||||||
PE_HEADER(module)->FileHeader.SizeOfOptionalHeader))
|
|
||||||
|
|
||||||
enum loadorder_type
|
enum loadorder_type
|
||||||
{
|
{
|
||||||
|
|
|
@ -1073,6 +1073,9 @@ LPVOID WINAPI RtlNormalizeProcessParams(LPVOID x);
|
||||||
DWORD WINAPI RtlNtStatusToDosError(DWORD error);
|
DWORD WINAPI RtlNtStatusToDosError(DWORD error);
|
||||||
BOOLEAN WINAPI RtlGetNtProductType(LPDWORD type);
|
BOOLEAN WINAPI RtlGetNtProductType(LPDWORD type);
|
||||||
PIMAGE_NT_HEADERS WINAPI RtlImageNtHeader(HMODULE hModule);
|
PIMAGE_NT_HEADERS WINAPI RtlImageNtHeader(HMODULE hModule);
|
||||||
|
PIMAGE_SECTION_HEADER WINAPI RtlImageRvaToSection( const IMAGE_NT_HEADERS *, HMODULE, DWORD );
|
||||||
|
PVOID WINAPI RtlImageDirectoryEntryToData( HMODULE module, BOOL image, WORD dir, ULONG *size );
|
||||||
|
PVOID WINAPI RtlImageRvaToVa( const IMAGE_NT_HEADERS *, HMODULE, DWORD, IMAGE_SECTION_HEADER **);
|
||||||
|
|
||||||
DWORD WINAPI RtlOpenCurrentUser(
|
DWORD WINAPI RtlOpenCurrentUser(
|
||||||
IN ACCESS_MASK DesiredAccess,
|
IN ACCESS_MASK DesiredAccess,
|
||||||
|
|
|
@ -33,7 +33,6 @@
|
||||||
|
|
||||||
#include "snoop.h"
|
#include "snoop.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "module.h"
|
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
#include "winerror.h"
|
#include "winerror.h"
|
||||||
|
|
||||||
|
@ -77,7 +76,7 @@ static HMODULE ELF_CreateDummyModule( LPCSTR libname, LPCSTR modname )
|
||||||
dh = (PIMAGE_DOS_HEADER)hmod;
|
dh = (PIMAGE_DOS_HEADER)hmod;
|
||||||
dh->e_magic = IMAGE_DOS_SIGNATURE;
|
dh->e_magic = IMAGE_DOS_SIGNATURE;
|
||||||
dh->e_lfanew = sizeof(IMAGE_DOS_HEADER);
|
dh->e_lfanew = sizeof(IMAGE_DOS_HEADER);
|
||||||
nth = PE_HEADER(hmod);
|
nth = (IMAGE_NT_HEADERS *)(dh + 1);
|
||||||
nth->Signature = IMAGE_NT_SIGNATURE;
|
nth->Signature = IMAGE_NT_SIGNATURE;
|
||||||
nth->FileHeader.Machine = IMAGE_FILE_MACHINE_I386;
|
nth->FileHeader.Machine = IMAGE_FILE_MACHINE_I386;
|
||||||
nth->FileHeader.NumberOfSections = 1;
|
nth->FileHeader.NumberOfSections = 1;
|
||||||
|
|
|
@ -121,7 +121,7 @@ WINE_MODREF *MODULE_AllocModRef( HMODULE hModule, LPCSTR filename )
|
||||||
if (wm->next) wm->next->prev = wm;
|
if (wm->next) wm->next->prev = wm;
|
||||||
MODULE_modref_list = wm;
|
MODULE_modref_list = wm;
|
||||||
|
|
||||||
if (!(PE_HEADER(hModule)->FileHeader.Characteristics & IMAGE_FILE_DLL))
|
if (!(RtlImageNtHeader(hModule)->FileHeader.Characteristics & IMAGE_FILE_DLL))
|
||||||
{
|
{
|
||||||
if (!exe_modref) exe_modref = wm;
|
if (!exe_modref) exe_modref = wm;
|
||||||
else FIXME( "Trying to load second .EXE file: %s\n", filename );
|
else FIXME( "Trying to load second .EXE file: %s\n", filename );
|
||||||
|
@ -434,11 +434,11 @@ HMODULE16 MODULE_CreateDummyModule( LPCSTR filename, HMODULE module32 )
|
||||||
/* Set version and flags */
|
/* Set version and flags */
|
||||||
if (module32)
|
if (module32)
|
||||||
{
|
{
|
||||||
pModule->expected_version =
|
IMAGE_NT_HEADERS *nt = RtlImageNtHeader( module32 );
|
||||||
((PE_HEADER(module32)->OptionalHeader.MajorSubsystemVersion & 0xff) << 8 ) |
|
pModule->expected_version = ((nt->OptionalHeader.MajorSubsystemVersion & 0xff) << 8 ) |
|
||||||
(PE_HEADER(module32)->OptionalHeader.MinorSubsystemVersion & 0xff);
|
(nt->OptionalHeader.MinorSubsystemVersion & 0xff);
|
||||||
pModule->flags |= NE_FFLAGS_WIN32;
|
pModule->flags |= NE_FFLAGS_WIN32;
|
||||||
if (PE_HEADER(module32)->FileHeader.Characteristics & IMAGE_FILE_DLL)
|
if (nt->FileHeader.Characteristics & IMAGE_FILE_DLL)
|
||||||
pModule->flags |= NE_FFLAGS_LIBMODULE | NE_FFLAGS_SINGLEDATA;
|
pModule->flags |= NE_FFLAGS_LIBMODULE | NE_FFLAGS_SINGLEDATA;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -55,27 +55,6 @@ WINE_DECLARE_DEBUG_CHANNEL(relay);
|
||||||
WINE_DECLARE_DEBUG_CHANNEL(segment);
|
WINE_DECLARE_DEBUG_CHANNEL(segment);
|
||||||
|
|
||||||
|
|
||||||
static IMAGE_EXPORT_DIRECTORY *get_exports( HMODULE hmod )
|
|
||||||
{
|
|
||||||
IMAGE_EXPORT_DIRECTORY *ret = NULL;
|
|
||||||
IMAGE_DATA_DIRECTORY *dir = PE_HEADER(hmod)->OptionalHeader.DataDirectory
|
|
||||||
+ IMAGE_DIRECTORY_ENTRY_EXPORT;
|
|
||||||
if (dir->Size && dir->VirtualAddress)
|
|
||||||
ret = (IMAGE_EXPORT_DIRECTORY *)((char *)hmod + dir->VirtualAddress);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static IMAGE_IMPORT_DESCRIPTOR *get_imports( HMODULE hmod )
|
|
||||||
{
|
|
||||||
IMAGE_IMPORT_DESCRIPTOR *ret = NULL;
|
|
||||||
IMAGE_DATA_DIRECTORY *dir = PE_HEADER(hmod)->OptionalHeader.DataDirectory
|
|
||||||
+ IMAGE_DIRECTORY_ENTRY_IMPORT;
|
|
||||||
if (dir->Size && dir->VirtualAddress)
|
|
||||||
ret = (IMAGE_IMPORT_DESCRIPTOR *)((char *)hmod + dir->VirtualAddress);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* convert PE image VirtualAddress to Real Address */
|
/* convert PE image VirtualAddress to Real Address */
|
||||||
#define RVA(x) ((void *)((char *)load_addr+(unsigned int)(x)))
|
#define RVA(x) ((void *)((char *)load_addr+(unsigned int)(x)))
|
||||||
|
|
||||||
|
@ -89,12 +68,11 @@ void dump_exports( HMODULE hModule )
|
||||||
DWORD *function,*functions;
|
DWORD *function,*functions;
|
||||||
BYTE **name;
|
BYTE **name;
|
||||||
unsigned int load_addr = hModule;
|
unsigned int load_addr = hModule;
|
||||||
|
IMAGE_EXPORT_DIRECTORY *pe_exports;
|
||||||
|
DWORD rva_start, size;
|
||||||
|
|
||||||
DWORD rva_start = PE_HEADER(hModule)->OptionalHeader
|
pe_exports = RtlImageDirectoryEntryToData( hModule, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &size );
|
||||||
.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
|
rva_start = (char *)pe_exports - (char *)hModule;
|
||||||
DWORD rva_end = rva_start + PE_HEADER(hModule)->OptionalHeader
|
|
||||||
.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
|
|
||||||
IMAGE_EXPORT_DIRECTORY *pe_exports = (IMAGE_EXPORT_DIRECTORY*)RVA(rva_start);
|
|
||||||
|
|
||||||
Module = (char*)RVA(pe_exports->Name);
|
Module = (char*)RVA(pe_exports->Name);
|
||||||
DPRINTF("*******EXPORT DATA*******\n");
|
DPRINTF("*******EXPORT DATA*******\n");
|
||||||
|
@ -117,7 +95,7 @@ void dump_exports( HMODULE hModule )
|
||||||
DPRINTF( " %s", (char*)RVA(name[j]) );
|
DPRINTF( " %s", (char*)RVA(name[j]) );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ((*function >= rva_start) && (*function <= rva_end))
|
if ((*function >= rva_start) && (*function <= rva_start + size))
|
||||||
DPRINTF(" (forwarded -> %s)", (char *)RVA(*function));
|
DPRINTF(" (forwarded -> %s)", (char *)RVA(*function));
|
||||||
DPRINTF("\n");
|
DPRINTF("\n");
|
||||||
}
|
}
|
||||||
|
@ -142,30 +120,24 @@ static FARPROC PE_FindExportedFunction(
|
||||||
BYTE ** name, *ename = NULL;
|
BYTE ** name, *ename = NULL;
|
||||||
int i, ordinal;
|
int i, ordinal;
|
||||||
unsigned int load_addr = wm->module;
|
unsigned int load_addr = wm->module;
|
||||||
DWORD rva_start, rva_end, addr;
|
DWORD rva_start, addr;
|
||||||
char * forward;
|
char * forward;
|
||||||
IMAGE_EXPORT_DIRECTORY *exports = get_exports(wm->module);
|
FARPROC proc;
|
||||||
|
IMAGE_EXPORT_DIRECTORY *exports;
|
||||||
|
DWORD exp_size;
|
||||||
|
|
||||||
if (HIWORD(funcName))
|
if (!(exports = RtlImageDirectoryEntryToData( wm->module, TRUE,
|
||||||
TRACE("(%s)\n",funcName);
|
IMAGE_DIRECTORY_ENTRY_EXPORT, &exp_size )))
|
||||||
else
|
|
||||||
TRACE("(%d)\n",(int)funcName);
|
|
||||||
if (!exports) {
|
|
||||||
/* Not a fatal problem, some apps do
|
|
||||||
* GetProcAddress(0,"RegisterPenApp") which triggers this
|
|
||||||
* case.
|
|
||||||
*/
|
|
||||||
WARN("Module %08x(%s)/MODREF %p doesn't have a exports table.\n",wm->module,wm->modname,wm);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
|
if (HIWORD(funcName)) TRACE("(%s)\n",funcName);
|
||||||
|
else TRACE("(%d)\n",LOWORD(funcName));
|
||||||
|
|
||||||
ordinals= RVA(exports->AddressOfNameOrdinals);
|
ordinals= RVA(exports->AddressOfNameOrdinals);
|
||||||
function= RVA(exports->AddressOfFunctions);
|
function= RVA(exports->AddressOfFunctions);
|
||||||
name = RVA(exports->AddressOfNames);
|
name = RVA(exports->AddressOfNames);
|
||||||
forward = NULL;
|
forward = NULL;
|
||||||
rva_start = PE_HEADER(wm->module)->OptionalHeader
|
rva_start = (char *)exports - (char *)wm->module;
|
||||||
.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
|
|
||||||
rva_end = rva_start + PE_HEADER(wm->module)->OptionalHeader
|
|
||||||
.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
|
|
||||||
|
|
||||||
if (HIWORD(funcName))
|
if (HIWORD(funcName))
|
||||||
{
|
{
|
||||||
|
@ -219,9 +191,10 @@ static FARPROC PE_FindExportedFunction(
|
||||||
}
|
}
|
||||||
addr = function[ordinal];
|
addr = function[ordinal];
|
||||||
if (!addr) return NULL;
|
if (!addr) return NULL;
|
||||||
if ((addr < rva_start) || (addr >= rva_end))
|
|
||||||
|
proc = RVA(addr);
|
||||||
|
if (((char *)proc < (char *)exports) || ((char *)proc >= (char *)exports + exp_size))
|
||||||
{
|
{
|
||||||
FARPROC proc = RVA(addr);
|
|
||||||
if (snoop)
|
if (snoop)
|
||||||
{
|
{
|
||||||
if (!ename) ename = "@";
|
if (!ename) ename = "@";
|
||||||
|
@ -232,8 +205,7 @@ static FARPROC PE_FindExportedFunction(
|
||||||
else /* forward entry point */
|
else /* forward entry point */
|
||||||
{
|
{
|
||||||
WINE_MODREF *wm_fw;
|
WINE_MODREF *wm_fw;
|
||||||
FARPROC proc;
|
char *forward = (char *)proc;
|
||||||
char *forward = RVA(addr);
|
|
||||||
char module[256];
|
char module[256];
|
||||||
char *end = strchr(forward, '.');
|
char *end = strchr(forward, '.');
|
||||||
|
|
||||||
|
@ -257,10 +229,12 @@ static FARPROC PE_FindExportedFunction(
|
||||||
*/
|
*/
|
||||||
DWORD PE_fixup_imports( WINE_MODREF *wm )
|
DWORD PE_fixup_imports( WINE_MODREF *wm )
|
||||||
{
|
{
|
||||||
IMAGE_IMPORT_DESCRIPTOR *pe_imp;
|
|
||||||
unsigned int load_addr = wm->module;
|
unsigned int load_addr = wm->module;
|
||||||
int i,characteristics_detection=1;
|
int i,characteristics_detection=1;
|
||||||
IMAGE_IMPORT_DESCRIPTOR *imports = get_imports(wm->module);
|
IMAGE_IMPORT_DESCRIPTOR *imports, *pe_imp;
|
||||||
|
DWORD size;
|
||||||
|
|
||||||
|
imports = RtlImageDirectoryEntryToData( wm->module, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &size );
|
||||||
|
|
||||||
/* first, count the number of imported non-internal modules */
|
/* first, count the number of imported non-internal modules */
|
||||||
pe_imp = imports;
|
pe_imp = imports;
|
||||||
|
@ -406,21 +380,11 @@ HMODULE PE_LoadImage( HANDLE hFile, LPCSTR filename, DWORD flags )
|
||||||
/* virus check */
|
/* virus check */
|
||||||
|
|
||||||
hModule = (HMODULE)base;
|
hModule = (HMODULE)base;
|
||||||
nt = PE_HEADER( hModule );
|
nt = RtlImageNtHeader( hModule );
|
||||||
|
|
||||||
if (nt->OptionalHeader.AddressOfEntryPoint)
|
if (nt->OptionalHeader.AddressOfEntryPoint)
|
||||||
{
|
{
|
||||||
int i;
|
if (!RtlImageRvaToSection( nt, hModule, nt->OptionalHeader.AddressOfEntryPoint ))
|
||||||
IMAGE_SECTION_HEADER *sec = (IMAGE_SECTION_HEADER*)((char*)&nt->OptionalHeader +
|
|
||||||
nt->FileHeader.SizeOfOptionalHeader);
|
|
||||||
for (i = 0; i < nt->FileHeader.NumberOfSections; i++, sec++)
|
|
||||||
{
|
|
||||||
if (nt->OptionalHeader.AddressOfEntryPoint < sec->VirtualAddress)
|
|
||||||
continue;
|
|
||||||
if (nt->OptionalHeader.AddressOfEntryPoint < sec->VirtualAddress+sec->SizeOfRawData)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (i == nt->FileHeader.NumberOfSections)
|
|
||||||
MESSAGE("VIRUS WARNING: PE module has an invalid entrypoint (0x%08lx) "
|
MESSAGE("VIRUS WARNING: PE module has an invalid entrypoint (0x%08lx) "
|
||||||
"outside all sections (possibly infected by Tchernobyl/SpaceFiller virus)!\n",
|
"outside all sections (possibly infected by Tchernobyl/SpaceFiller virus)!\n",
|
||||||
nt->OptionalHeader.AddressOfEntryPoint );
|
nt->OptionalHeader.AddressOfEntryPoint );
|
||||||
|
@ -448,7 +412,7 @@ WINE_MODREF *PE_CreateModule( HMODULE hModule, LPCSTR filename, DWORD flags,
|
||||||
HANDLE hFile, BOOL builtin )
|
HANDLE hFile, BOOL builtin )
|
||||||
{
|
{
|
||||||
DWORD load_addr = (DWORD)hModule; /* for RVA */
|
DWORD load_addr = (DWORD)hModule; /* for RVA */
|
||||||
IMAGE_NT_HEADERS *nt = PE_HEADER(hModule);
|
IMAGE_NT_HEADERS *nt;
|
||||||
IMAGE_DATA_DIRECTORY *dir;
|
IMAGE_DATA_DIRECTORY *dir;
|
||||||
IMAGE_EXPORT_DIRECTORY *pe_export = NULL;
|
IMAGE_EXPORT_DIRECTORY *pe_export = NULL;
|
||||||
WINE_MODREF *wm;
|
WINE_MODREF *wm;
|
||||||
|
@ -456,6 +420,7 @@ WINE_MODREF *PE_CreateModule( HMODULE hModule, LPCSTR filename, DWORD flags,
|
||||||
|
|
||||||
/* Retrieve DataDirectory entries */
|
/* Retrieve DataDirectory entries */
|
||||||
|
|
||||||
|
nt = RtlImageNtHeader(hModule);
|
||||||
dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_EXPORT;
|
dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_EXPORT;
|
||||||
if (dir->Size)
|
if (dir->Size)
|
||||||
pe_export = (PIMAGE_EXPORT_DIRECTORY)RVA(dir->VirtualAddress);
|
pe_export = (PIMAGE_EXPORT_DIRECTORY)RVA(dir->VirtualAddress);
|
||||||
|
@ -651,10 +616,10 @@ typedef DWORD (CALLBACK *DLLENTRYPROC)(HMODULE,DWORD,LPVOID);
|
||||||
BOOL PE_InitDLL( HMODULE module, DWORD type, LPVOID lpReserved )
|
BOOL PE_InitDLL( HMODULE module, DWORD type, LPVOID lpReserved )
|
||||||
{
|
{
|
||||||
BOOL retv = TRUE;
|
BOOL retv = TRUE;
|
||||||
IMAGE_NT_HEADERS *nt = PE_HEADER(module);
|
IMAGE_NT_HEADERS *nt = RtlImageNtHeader(module);
|
||||||
|
|
||||||
/* Is this a library? And has it got an entrypoint? */
|
/* Is this a library? And has it got an entrypoint? */
|
||||||
if ((nt->FileHeader.Characteristics & IMAGE_FILE_DLL) &&
|
if (nt && (nt->FileHeader.Characteristics & IMAGE_FILE_DLL) &&
|
||||||
(nt->OptionalHeader.AddressOfEntryPoint))
|
(nt->OptionalHeader.AddressOfEntryPoint))
|
||||||
{
|
{
|
||||||
DLLENTRYPROC entry = (void*)((char*)module + nt->OptionalHeader.AddressOfEntryPoint);
|
DLLENTRYPROC entry = (void*)((char*)module + nt->OptionalHeader.AddressOfEntryPoint);
|
||||||
|
@ -692,19 +657,17 @@ void PE_InitTls( void )
|
||||||
{
|
{
|
||||||
WINE_MODREF *wm;
|
WINE_MODREF *wm;
|
||||||
IMAGE_NT_HEADERS *peh;
|
IMAGE_NT_HEADERS *peh;
|
||||||
DWORD size,datasize;
|
DWORD size,datasize,dirsize;
|
||||||
LPVOID mem;
|
LPVOID mem;
|
||||||
PIMAGE_TLS_DIRECTORY pdir;
|
PIMAGE_TLS_DIRECTORY pdir;
|
||||||
int delta;
|
int delta;
|
||||||
|
|
||||||
for (wm = MODULE_modref_list;wm;wm=wm->next) {
|
for (wm = MODULE_modref_list;wm;wm=wm->next) {
|
||||||
peh = PE_HEADER(wm->module);
|
peh = RtlImageNtHeader(wm->module);
|
||||||
delta = wm->module - peh->OptionalHeader.ImageBase;
|
pdir = RtlImageDirectoryEntryToData( wm->module, TRUE,
|
||||||
if (!peh->OptionalHeader.DataDirectory[IMAGE_FILE_THREAD_LOCAL_STORAGE].VirtualAddress)
|
IMAGE_DIRECTORY_ENTRY_TLS, &dirsize );
|
||||||
continue;
|
if (!pdir) continue;
|
||||||
pdir = (LPVOID)(wm->module + peh->OptionalHeader.
|
delta = (char *)wm->module - (char *)peh->OptionalHeader.ImageBase;
|
||||||
DataDirectory[IMAGE_FILE_THREAD_LOCAL_STORAGE].VirtualAddress);
|
|
||||||
|
|
||||||
|
|
||||||
if ( wm->tlsindex == -1 ) {
|
if ( wm->tlsindex == -1 ) {
|
||||||
LPDWORD xaddr;
|
LPDWORD xaddr;
|
||||||
|
|
|
@ -32,34 +32,13 @@
|
||||||
#include "wine/unicode.h"
|
#include "wine/unicode.h"
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
#include "winnls.h"
|
#include "winnls.h"
|
||||||
|
#include "ntddk.h"
|
||||||
#include "winerror.h"
|
#include "winerror.h"
|
||||||
#include "module.h"
|
|
||||||
#include "stackframe.h"
|
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(resource);
|
WINE_DEFAULT_DEBUG_CHANNEL(resource);
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
|
||||||
* get_module_base
|
|
||||||
*
|
|
||||||
* Get the base address of a module
|
|
||||||
*/
|
|
||||||
static const void *get_module_base( HMODULE hmod )
|
|
||||||
{
|
|
||||||
if (!hmod) hmod = GetModuleHandleA( NULL );
|
|
||||||
else if (!HIWORD(hmod))
|
|
||||||
{
|
|
||||||
FIXME("Enumeration of 16-bit resources is not supported\n");
|
|
||||||
SetLastError(ERROR_INVALID_HANDLE);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* clear low order bit in case of LOAD_LIBRARY_AS_DATAFILE module */
|
|
||||||
return (void *)((ULONG_PTR)hmod & ~1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* is_data_file_module
|
* is_data_file_module
|
||||||
*
|
*
|
||||||
|
@ -71,28 +50,6 @@ inline static int is_data_file_module( HMODULE hmod )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
|
||||||
* get_data_file_ptr
|
|
||||||
*
|
|
||||||
* Get a pointer to a given offset in a file mapped as data file.
|
|
||||||
*/
|
|
||||||
static const void *get_data_file_ptr( const void *base, DWORD offset )
|
|
||||||
{
|
|
||||||
const IMAGE_NT_HEADERS *nt = PE_HEADER(base);
|
|
||||||
const IMAGE_SECTION_HEADER *sec = (IMAGE_SECTION_HEADER *)((char *)&nt->OptionalHeader +
|
|
||||||
nt->FileHeader.SizeOfOptionalHeader);
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* find the section containing the virtual address */
|
|
||||||
for (i = 0; i < nt->FileHeader.NumberOfSections; i++, sec++)
|
|
||||||
{
|
|
||||||
if ((sec->VirtualAddress <= offset) && (sec->VirtualAddress + sec->SizeOfRawData > offset))
|
|
||||||
return (char *)base + sec->PointerToRawData + (offset - sec->VirtualAddress);
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* get_resdir
|
* get_resdir
|
||||||
*
|
*
|
||||||
|
@ -100,20 +57,16 @@ static const void *get_data_file_ptr( const void *base, DWORD offset )
|
||||||
*/
|
*/
|
||||||
static const IMAGE_RESOURCE_DIRECTORY* get_resdir( HMODULE hmod )
|
static const IMAGE_RESOURCE_DIRECTORY* get_resdir( HMODULE hmod )
|
||||||
{
|
{
|
||||||
const IMAGE_DATA_DIRECTORY *dir;
|
DWORD size;
|
||||||
const IMAGE_RESOURCE_DIRECTORY *ret = NULL;
|
|
||||||
const void *base = get_module_base( hmod );
|
|
||||||
|
|
||||||
if (base)
|
if (!hmod) hmod = GetModuleHandleA( NULL );
|
||||||
|
else if (!HIWORD(hmod))
|
||||||
{
|
{
|
||||||
dir = &PE_HEADER(base)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE];
|
FIXME("Enumeration of 16-bit resources is not supported\n");
|
||||||
if (dir->Size && dir->VirtualAddress)
|
SetLastError(ERROR_INVALID_HANDLE);
|
||||||
{
|
return NULL;
|
||||||
if (is_data_file_module(hmod)) ret = get_data_file_ptr( base, dir->VirtualAddress );
|
|
||||||
else ret = (IMAGE_RESOURCE_DIRECTORY *)((char *)base + dir->VirtualAddress);
|
|
||||||
}
|
}
|
||||||
}
|
return RtlImageDirectoryEntryToData( hmod, TRUE, IMAGE_DIRECTORY_ENTRY_RESOURCE, &size );
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -325,16 +278,19 @@ HRSRC PE_FindResourceW( HMODULE hmod, LPCWSTR name, LPCWSTR type )
|
||||||
HGLOBAL PE_LoadResource( HMODULE hmod, HRSRC hRsrc )
|
HGLOBAL PE_LoadResource( HMODULE hmod, HRSRC hRsrc )
|
||||||
{
|
{
|
||||||
DWORD offset;
|
DWORD offset;
|
||||||
const void *base = get_module_base( hmod );
|
|
||||||
|
|
||||||
if (!hRsrc || !base) return 0;
|
if (!hRsrc) return 0;
|
||||||
|
if (!hmod) hmod = GetModuleHandleA( NULL );
|
||||||
|
|
||||||
offset = ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData;
|
offset = ((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData;
|
||||||
|
|
||||||
if (is_data_file_module(hmod))
|
if (is_data_file_module(hmod))
|
||||||
return (HANDLE)get_data_file_ptr( base, offset );
|
{
|
||||||
|
hmod = (HMODULE)((ULONG_PTR)hmod & ~1);
|
||||||
|
return (HGLOBAL)RtlImageRvaToVa( RtlImageNtHeader(hmod), hmod, offset, NULL );
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return (HANDLE)((char *)base + offset);
|
return (HGLOBAL)((char *)hmod + offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "winreg.h"
|
#include "winreg.h"
|
||||||
#include "wingdi.h"
|
#include "wingdi.h"
|
||||||
#include "winuser.h"
|
#include "winuser.h"
|
||||||
|
#include "ntddk.h"
|
||||||
#include "wine/winbase16.h"
|
#include "wine/winbase16.h"
|
||||||
#include "module.h"
|
#include "module.h"
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
@ -352,11 +353,11 @@ static void VERSION_Init(void)
|
||||||
*/
|
*/
|
||||||
static DWORD VERSION_GetSystemDLLVersion( HMODULE hmod )
|
static DWORD VERSION_GetSystemDLLVersion( HMODULE hmod )
|
||||||
{
|
{
|
||||||
IMAGE_DATA_DIRECTORY *dir = PE_HEADER(hmod)->OptionalHeader.DataDirectory
|
DWORD size;
|
||||||
+ IMAGE_DIRECTORY_ENTRY_IMPORT;
|
IMAGE_IMPORT_DESCRIPTOR *pe_imp;
|
||||||
if (dir->Size && dir->VirtualAddress)
|
|
||||||
|
if ((pe_imp = RtlImageDirectoryEntryToData( hmod, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &size )))
|
||||||
{
|
{
|
||||||
IMAGE_IMPORT_DESCRIPTOR *pe_imp = (IMAGE_IMPORT_DESCRIPTOR *)((char *)hmod + dir->VirtualAddress);
|
|
||||||
for ( ; pe_imp->Name; pe_imp++)
|
for ( ; pe_imp->Name; pe_imp++)
|
||||||
{
|
{
|
||||||
char * name = (char *)hmod + (unsigned int)pe_imp->Name;
|
char * name = (char *)hmod + (unsigned int)pe_imp->Name;
|
||||||
|
@ -364,7 +365,7 @@ static DWORD VERSION_GetSystemDLLVersion( HMODULE hmod )
|
||||||
|
|
||||||
if (!strncasecmp(name, "ntdll", 5))
|
if (!strncasecmp(name, "ntdll", 5))
|
||||||
{
|
{
|
||||||
switch(PE_HEADER(hmod)->OptionalHeader.MajorOperatingSystemVersion) {
|
switch(RtlImageNtHeader(hmod)->OptionalHeader.MajorOperatingSystemVersion) {
|
||||||
case 3:
|
case 3:
|
||||||
MESSAGE("WARNING: very old native DLL (NT 3.x) used, might cause instability.\n");
|
MESSAGE("WARNING: very old native DLL (NT 3.x) used, might cause instability.\n");
|
||||||
return NT351;
|
return NT351;
|
||||||
|
@ -405,12 +406,14 @@ DWORD VERSION_GetLinkedDllVersion(void)
|
||||||
WINE_MODREF *wm;
|
WINE_MODREF *wm;
|
||||||
DWORD WinVersion = NB_WINDOWS_VERSIONS;
|
DWORD WinVersion = NB_WINDOWS_VERSIONS;
|
||||||
PIMAGE_OPTIONAL_HEADER ophd;
|
PIMAGE_OPTIONAL_HEADER ophd;
|
||||||
|
IMAGE_NT_HEADERS *nt;
|
||||||
|
|
||||||
/* First check the native dlls provided. These have to be
|
/* First check the native dlls provided. These have to be
|
||||||
from one windows version */
|
from one windows version */
|
||||||
for ( wm = MODULE_modref_list; wm; wm=wm->next )
|
for ( wm = MODULE_modref_list; wm; wm=wm->next )
|
||||||
{
|
{
|
||||||
ophd = &(PE_HEADER(wm->module)->OptionalHeader);
|
nt = RtlImageNtHeader(wm->module);
|
||||||
|
ophd = &nt->OptionalHeader;
|
||||||
|
|
||||||
TRACE("%s: %02x.%02x/%02x.%02x/%02x.%02x/%02x.%02x\n",
|
TRACE("%s: %02x.%02x/%02x.%02x/%02x.%02x/%02x.%02x\n",
|
||||||
wm->modname,
|
wm->modname,
|
||||||
|
@ -449,7 +452,8 @@ DWORD VERSION_GetLinkedDllVersion(void)
|
||||||
if(WinVersion != NB_WINDOWS_VERSIONS) return WinVersion;
|
if(WinVersion != NB_WINDOWS_VERSIONS) return WinVersion;
|
||||||
|
|
||||||
/* we are using no external system dlls, look at the exe */
|
/* we are using no external system dlls, look at the exe */
|
||||||
ophd = &(PE_HEADER(GetModuleHandleA(NULL))->OptionalHeader);
|
nt = RtlImageNtHeader(GetModuleHandleA(NULL));
|
||||||
|
ophd = &nt->OptionalHeader;
|
||||||
|
|
||||||
TRACE("%02x.%02x/%02x.%02x/%02x.%02x/%02x.%02x\n",
|
TRACE("%02x.%02x/%02x.%02x/%02x.%02x/%02x.%02x\n",
|
||||||
ophd->MajorLinkerVersion, ophd->MinorLinkerVersion,
|
ophd->MajorLinkerVersion, ophd->MinorLinkerVersion,
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
#include "windef.h"
|
#include "windef.h"
|
||||||
|
#include "ntddk.h"
|
||||||
#include "wingdi.h"
|
#include "wingdi.h"
|
||||||
#include "winuser.h"
|
#include "winuser.h"
|
||||||
#include "wine/winbase16.h"
|
#include "wine/winbase16.h"
|
||||||
|
@ -758,8 +759,10 @@ void WINAPI VXD_Win32s( CONTEXT86 *context )
|
||||||
(struct Win32sModule *)W32S_APP2WINE(context->Edx);
|
(struct Win32sModule *)W32S_APP2WINE(context->Edx);
|
||||||
struct Win32sModule *module = moduleTable + context->Ecx;
|
struct Win32sModule *module = moduleTable + context->Ecx;
|
||||||
|
|
||||||
IMAGE_NT_HEADERS *nt_header = PE_HEADER(module->baseAddr);
|
IMAGE_NT_HEADERS *nt_header = RtlImageNtHeader( (HMODULE)module->baseAddr );
|
||||||
IMAGE_SECTION_HEADER *pe_seg = PE_SECTIONS(module->baseAddr);
|
IMAGE_SECTION_HEADER *pe_seg = (IMAGE_SECTION_HEADER*)((char *)&nt_header->OptionalHeader +
|
||||||
|
nt_header->FileHeader.SizeOfOptionalHeader);
|
||||||
|
|
||||||
|
|
||||||
HFILE image = _lopen(module->pathName, OF_READ);
|
HFILE image = _lopen(module->pathName, OF_READ);
|
||||||
BOOL error = (image == HFILE_ERROR);
|
BOOL error = (image == HFILE_ERROR);
|
||||||
|
|
|
@ -86,6 +86,7 @@ int BUILTIN32_dlclose( void *handle )
|
||||||
static void load_library( void *base, const char *filename )
|
static void load_library( void *base, const char *filename )
|
||||||
{
|
{
|
||||||
HMODULE module = (HMODULE)base;
|
HMODULE module = (HMODULE)base;
|
||||||
|
IMAGE_NT_HEADERS *nt;
|
||||||
WINE_MODREF *wm;
|
WINE_MODREF *wm;
|
||||||
char *fullname;
|
char *fullname;
|
||||||
DWORD len;
|
DWORD len;
|
||||||
|
@ -95,8 +96,13 @@ static void load_library( void *base, const char *filename )
|
||||||
ERR("could not map image for %s\n", filename ? filename : "main exe" );
|
ERR("could not map image for %s\n", filename ? filename : "main exe" );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!(nt = RtlImageNtHeader( module )))
|
||||||
|
{
|
||||||
|
ERR( "bad module for %s\n", filename ? filename : "main exe" );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(PE_HEADER(module)->FileHeader.Characteristics & IMAGE_FILE_DLL))
|
if (!(nt->FileHeader.Characteristics & IMAGE_FILE_DLL))
|
||||||
{
|
{
|
||||||
/* if we already have an executable, ignore this one */
|
/* if we already have an executable, ignore this one */
|
||||||
if (!main_module) main_module = module;
|
if (!main_module) main_module = module;
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "winnt.h"
|
#include "winnt.h"
|
||||||
|
#include "ntddk.h"
|
||||||
#include "winreg.h"
|
#include "winreg.h"
|
||||||
#include "stackframe.h"
|
#include "stackframe.h"
|
||||||
#include "module.h"
|
#include "module.h"
|
||||||
|
@ -199,24 +200,22 @@ static const char *find_exported_name( const char *module,
|
||||||
*/
|
*/
|
||||||
static void get_entry_point( char *buffer, DEBUG_ENTRY_POINT *relay )
|
static void get_entry_point( char *buffer, DEBUG_ENTRY_POINT *relay )
|
||||||
{
|
{
|
||||||
IMAGE_DATA_DIRECTORY *dir;
|
|
||||||
IMAGE_EXPORT_DIRECTORY *exp = NULL;
|
IMAGE_EXPORT_DIRECTORY *exp = NULL;
|
||||||
DEBUG_ENTRY_POINT *debug;
|
DEBUG_ENTRY_POINT *debug;
|
||||||
char *p, *base = NULL;
|
char *p, *base = NULL;
|
||||||
const char *name;
|
const char *name;
|
||||||
int ordinal = 0;
|
int ordinal = 0;
|
||||||
WINE_MODREF *wm;
|
WINE_MODREF *wm;
|
||||||
|
DWORD size;
|
||||||
|
|
||||||
/* First find the module */
|
/* First find the module */
|
||||||
|
|
||||||
for (wm = MODULE_modref_list; wm; wm = wm->next)
|
for (wm = MODULE_modref_list; wm; wm = wm->next)
|
||||||
{
|
{
|
||||||
if (!(wm->flags & WINE_MODREF_INTERNAL)) continue;
|
if (!(wm->flags & WINE_MODREF_INTERNAL)) continue;
|
||||||
base = (char *)wm->module;
|
exp = RtlImageDirectoryEntryToData( wm->module, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &size );
|
||||||
dir = &PE_HEADER(base)->OptionalHeader.DataDirectory[IMAGE_FILE_EXPORT_DIRECTORY];
|
if (!exp) continue;
|
||||||
if (!dir->Size) continue;
|
debug = (DEBUG_ENTRY_POINT *)((char *)exp + size);
|
||||||
exp = (IMAGE_EXPORT_DIRECTORY *)(base + dir->VirtualAddress);
|
|
||||||
debug = (DEBUG_ENTRY_POINT *)((char *)exp + dir->Size);
|
|
||||||
if (debug <= relay && relay < debug + exp->NumberOfFunctions)
|
if (debug <= relay && relay < debug + exp->NumberOfFunctions)
|
||||||
{
|
{
|
||||||
ordinal = relay - debug;
|
ordinal = relay - debug;
|
||||||
|
@ -226,6 +225,7 @@ static void get_entry_point( char *buffer, DEBUG_ENTRY_POINT *relay )
|
||||||
|
|
||||||
/* Now find the function */
|
/* Now find the function */
|
||||||
|
|
||||||
|
base = (char *)wm->module;
|
||||||
strcpy( buffer, base + exp->Name );
|
strcpy( buffer, base + exp->Name );
|
||||||
p = buffer + strlen(buffer);
|
p = buffer + strlen(buffer);
|
||||||
if (p > buffer + 4 && !strcasecmp( p - 4, ".dll" )) p -= 4;
|
if (p > buffer + 4 && !strcasecmp( p - 4, ".dll" )) p -= 4;
|
||||||
|
@ -504,18 +504,18 @@ __ASM_GLOBAL_FUNC( RELAY_CallFrom32Regs,
|
||||||
*/
|
*/
|
||||||
void RELAY_SetupDLL( const char *module )
|
void RELAY_SetupDLL( const char *module )
|
||||||
{
|
{
|
||||||
IMAGE_DATA_DIRECTORY *dir;
|
|
||||||
IMAGE_EXPORT_DIRECTORY *exports;
|
IMAGE_EXPORT_DIRECTORY *exports;
|
||||||
DEBUG_ENTRY_POINT *debug;
|
DEBUG_ENTRY_POINT *debug;
|
||||||
DWORD *funcs;
|
DWORD *funcs;
|
||||||
int i;
|
int i;
|
||||||
const char *name;
|
const char *name;
|
||||||
char *p, dllname[80];
|
char *p, dllname[80];
|
||||||
|
DWORD size;
|
||||||
|
|
||||||
dir = &PE_HEADER(module)->OptionalHeader.DataDirectory[IMAGE_FILE_EXPORT_DIRECTORY];
|
exports = RtlImageDirectoryEntryToData( (HMODULE)module, TRUE,
|
||||||
if (!dir->Size) return;
|
IMAGE_DIRECTORY_ENTRY_EXPORT, &size );
|
||||||
exports = (IMAGE_EXPORT_DIRECTORY *)(module + dir->VirtualAddress);
|
if (!exports) return;
|
||||||
debug = (DEBUG_ENTRY_POINT *)((char *)exports + dir->Size);
|
debug = (DEBUG_ENTRY_POINT *)((char *)exports + size);
|
||||||
funcs = (DWORD *)(module + exports->AddressOfFunctions);
|
funcs = (DWORD *)(module + exports->AddressOfFunctions);
|
||||||
strcpy( dllname, module + exports->Name );
|
strcpy( dllname, module + exports->Name );
|
||||||
p = dllname + strlen(dllname) - 4;
|
p = dllname + strlen(dllname) - 4;
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "winbase.h"
|
#include "winbase.h"
|
||||||
#include "winnt.h"
|
#include "winnt.h"
|
||||||
|
#include "ntddk.h"
|
||||||
#include "snoop.h"
|
#include "snoop.h"
|
||||||
#include "stackframe.h"
|
#include "stackframe.h"
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
@ -175,30 +176,16 @@ FARPROC
|
||||||
SNOOP_GetProcAddress(HMODULE hmod,LPCSTR name,DWORD ordinal,FARPROC origfun) {
|
SNOOP_GetProcAddress(HMODULE hmod,LPCSTR name,DWORD ordinal,FARPROC origfun) {
|
||||||
SNOOP_DLL *dll = firstdll;
|
SNOOP_DLL *dll = firstdll;
|
||||||
SNOOP_FUN *fun;
|
SNOOP_FUN *fun;
|
||||||
int j;
|
IMAGE_SECTION_HEADER *sec;
|
||||||
IMAGE_SECTION_HEADER *pe_seg = PE_SECTIONS(hmod);
|
|
||||||
|
|
||||||
if (!TRACE_ON(snoop)) return origfun;
|
if (!TRACE_ON(snoop)) return origfun;
|
||||||
if (!*(LPBYTE)origfun) /* 0x00 is an imposs. opcode, poss. dataref. */
|
if (!*(LPBYTE)origfun) /* 0x00 is an imposs. opcode, poss. dataref. */
|
||||||
return origfun;
|
return origfun;
|
||||||
for (j=0;j<PE_HEADER(hmod)->FileHeader.NumberOfSections;j++)
|
|
||||||
/* 0x42 is special ELF loader tag */
|
sec = RtlImageRvaToSection( RtlImageNtHeader(hmod), hmod, (char *)origfun - (char *)hmod );
|
||||||
if ((pe_seg[j].VirtualAddress==0x42) ||
|
|
||||||
(((char *)origfun - (char *)hmod>=pe_seg[j].VirtualAddress)&&
|
if (!sec || !(sec->Characteristics & IMAGE_SCN_CNT_CODE))
|
||||||
((char *)origfun - (char *)hmod <pe_seg[j].VirtualAddress+
|
return origfun; /* most likely a data reference */
|
||||||
pe_seg[j].SizeOfRawData
|
|
||||||
))
|
|
||||||
)
|
|
||||||
break;
|
|
||||||
/* If we looked through all sections (and didn't find one)
|
|
||||||
* or if the sectionname contains "data", we return the
|
|
||||||
* original function since it is most likely a datareference.
|
|
||||||
*/
|
|
||||||
if ( (j==PE_HEADER(hmod)->FileHeader.NumberOfSections) ||
|
|
||||||
(strstr(pe_seg[j].Name,"data")) ||
|
|
||||||
!(pe_seg[j].Characteristics & IMAGE_SCN_CNT_CODE)
|
|
||||||
)
|
|
||||||
return origfun;
|
|
||||||
|
|
||||||
while (dll) {
|
while (dll) {
|
||||||
if (hmod == dll->hmod)
|
if (hmod == dll->hmod)
|
||||||
|
|
|
@ -450,6 +450,7 @@ static void start_process(void)
|
||||||
LPTHREAD_START_ROUTINE entry;
|
LPTHREAD_START_ROUTINE entry;
|
||||||
WINE_MODREF *wm;
|
WINE_MODREF *wm;
|
||||||
HANDLE main_file = main_exe_file;
|
HANDLE main_file = main_exe_file;
|
||||||
|
IMAGE_NT_HEADERS *nt;
|
||||||
|
|
||||||
/* use original argv[0] as name for the main module */
|
/* use original argv[0] as name for the main module */
|
||||||
if (!main_exe_name[0])
|
if (!main_exe_name[0])
|
||||||
|
@ -466,16 +467,17 @@ static void start_process(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Retrieve entry point address */
|
/* Retrieve entry point address */
|
||||||
|
nt = RtlImageNtHeader( current_process.module );
|
||||||
entry = (LPTHREAD_START_ROUTINE)((char*)current_process.module +
|
entry = (LPTHREAD_START_ROUTINE)((char*)current_process.module +
|
||||||
PE_HEADER(current_process.module)->OptionalHeader.AddressOfEntryPoint);
|
nt->OptionalHeader.AddressOfEntryPoint);
|
||||||
console_app = (PE_HEADER(current_process.module)->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI);
|
console_app = (nt->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI);
|
||||||
if (console_app) current_process.flags |= PDB32_CONSOLE_PROC;
|
if (console_app) current_process.flags |= PDB32_CONSOLE_PROC;
|
||||||
|
|
||||||
/* Signal the parent process to continue */
|
/* Signal the parent process to continue */
|
||||||
SERVER_START_REQ( init_process_done )
|
SERVER_START_REQ( init_process_done )
|
||||||
{
|
{
|
||||||
req->module = (void *)current_process.module;
|
req->module = (void *)current_process.module;
|
||||||
req->module_size = PE_HEADER(current_process.module)->OptionalHeader.SizeOfImage;
|
req->module_size = nt->OptionalHeader.SizeOfImage;
|
||||||
req->entry = entry;
|
req->entry = entry;
|
||||||
/* API requires a double indirection */
|
/* API requires a double indirection */
|
||||||
req->name = &main_exe_name_ptr;
|
req->name = &main_exe_name_ptr;
|
||||||
|
@ -633,7 +635,7 @@ void PROCESS_InitWine( int argc, char *argv[], LPSTR win16_exe_name, HANDLE *win
|
||||||
|
|
||||||
/* create 32-bit module for main exe */
|
/* create 32-bit module for main exe */
|
||||||
if (!(current_process.module = BUILTIN32_LoadExeModule( current_process.module ))) goto error;
|
if (!(current_process.module = BUILTIN32_LoadExeModule( current_process.module ))) goto error;
|
||||||
stack_size = PE_HEADER(current_process.module)->OptionalHeader.SizeOfStackReserve;
|
stack_size = RtlImageNtHeader(current_process.module)->OptionalHeader.SizeOfStackReserve;
|
||||||
|
|
||||||
/* allocate main thread stack */
|
/* allocate main thread stack */
|
||||||
if (!THREAD_InitStack( NtCurrentTeb(), stack_size )) goto error;
|
if (!THREAD_InitStack( NtCurrentTeb(), stack_size )) goto error;
|
||||||
|
|
Loading…
Reference in New Issue