Implemented the RtlImage* functions, and use them to replace the

PE_HEADER macro.
This commit is contained in:
Alexandre Julliard 2002-08-09 19:57:38 +00:00
parent 3d8b123e5a
commit a5dea216cc
15 changed files with 191 additions and 210 deletions

View File

@ -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);
}

View File

@ -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

View File

@ -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.@]
*/ */

View File

@ -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
{ {

View File

@ -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,

View File

@ -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;

View File

@ -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;
} }

View File

@ -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;

View File

@ -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);
} }

View File

@ -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,

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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)

View File

@ -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;