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;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* 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
|
||||
@ stub RtlGetUserInfoHeap
|
||||
@ stdcall RtlIdentifierAuthoritySid(ptr) RtlIdentifierAuthoritySid
|
||||
@ stub RtlImageDirectoryEntryToData
|
||||
@ stdcall RtlImageDirectoryEntryToData(long long long ptr) RtlImageDirectoryEntryToData
|
||||
@ stdcall RtlImageNtHeader(long) RtlImageNtHeader
|
||||
@ stdcall RtlImageRvaToSection(ptr long long) RtlImageRvaToSection
|
||||
@ stdcall RtlImageRvaToVa(ptr long long ptr) RtlImageRvaToVa
|
||||
@ stdcall RtlImpersonateSelf(long) RtlImpersonateSelf
|
||||
@ stdcall RtlInitAnsiString(ptr str) RtlInitAnsiString
|
||||
@ 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.@]
|
||||
*/
|
||||
|
|
|
@ -170,13 +170,6 @@ extern WINE_MODREF *MODULE_modref_list;
|
|||
#define NE_MODULE_NAME(pModule) \
|
||||
(((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
|
||||
{
|
||||
|
|
|
@ -1073,6 +1073,9 @@ LPVOID WINAPI RtlNormalizeProcessParams(LPVOID x);
|
|||
DWORD WINAPI RtlNtStatusToDosError(DWORD error);
|
||||
BOOLEAN WINAPI RtlGetNtProductType(LPDWORD type);
|
||||
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(
|
||||
IN ACCESS_MASK DesiredAccess,
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
|
||||
#include "snoop.h"
|
||||
#include "file.h"
|
||||
#include "module.h"
|
||||
#include "wine/debug.h"
|
||||
#include "winerror.h"
|
||||
|
||||
|
@ -77,7 +76,7 @@ static HMODULE ELF_CreateDummyModule( LPCSTR libname, LPCSTR modname )
|
|||
dh = (PIMAGE_DOS_HEADER)hmod;
|
||||
dh->e_magic = IMAGE_DOS_SIGNATURE;
|
||||
dh->e_lfanew = sizeof(IMAGE_DOS_HEADER);
|
||||
nth = PE_HEADER(hmod);
|
||||
nth = (IMAGE_NT_HEADERS *)(dh + 1);
|
||||
nth->Signature = IMAGE_NT_SIGNATURE;
|
||||
nth->FileHeader.Machine = IMAGE_FILE_MACHINE_I386;
|
||||
nth->FileHeader.NumberOfSections = 1;
|
||||
|
|
|
@ -121,7 +121,7 @@ WINE_MODREF *MODULE_AllocModRef( HMODULE hModule, LPCSTR filename )
|
|||
if (wm->next) wm->next->prev = 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;
|
||||
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 */
|
||||
if (module32)
|
||||
{
|
||||
pModule->expected_version =
|
||||
((PE_HEADER(module32)->OptionalHeader.MajorSubsystemVersion & 0xff) << 8 ) |
|
||||
(PE_HEADER(module32)->OptionalHeader.MinorSubsystemVersion & 0xff);
|
||||
IMAGE_NT_HEADERS *nt = RtlImageNtHeader( module32 );
|
||||
pModule->expected_version = ((nt->OptionalHeader.MajorSubsystemVersion & 0xff) << 8 ) |
|
||||
(nt->OptionalHeader.MinorSubsystemVersion & 0xff);
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -55,27 +55,6 @@ WINE_DECLARE_DEBUG_CHANNEL(relay);
|
|||
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 */
|
||||
#define RVA(x) ((void *)((char *)load_addr+(unsigned int)(x)))
|
||||
|
||||
|
@ -89,12 +68,11 @@ void dump_exports( HMODULE hModule )
|
|||
DWORD *function,*functions;
|
||||
BYTE **name;
|
||||
unsigned int load_addr = hModule;
|
||||
IMAGE_EXPORT_DIRECTORY *pe_exports;
|
||||
DWORD rva_start, size;
|
||||
|
||||
DWORD rva_start = PE_HEADER(hModule)->OptionalHeader
|
||||
.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
|
||||
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);
|
||||
pe_exports = RtlImageDirectoryEntryToData( hModule, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &size );
|
||||
rva_start = (char *)pe_exports - (char *)hModule;
|
||||
|
||||
Module = (char*)RVA(pe_exports->Name);
|
||||
DPRINTF("*******EXPORT DATA*******\n");
|
||||
|
@ -117,7 +95,7 @@ void dump_exports( HMODULE hModule )
|
|||
DPRINTF( " %s", (char*)RVA(name[j]) );
|
||||
break;
|
||||
}
|
||||
if ((*function >= rva_start) && (*function <= rva_end))
|
||||
if ((*function >= rva_start) && (*function <= rva_start + size))
|
||||
DPRINTF(" (forwarded -> %s)", (char *)RVA(*function));
|
||||
DPRINTF("\n");
|
||||
}
|
||||
|
@ -142,30 +120,24 @@ static FARPROC PE_FindExportedFunction(
|
|||
BYTE ** name, *ename = NULL;
|
||||
int i, ordinal;
|
||||
unsigned int load_addr = wm->module;
|
||||
DWORD rva_start, rva_end, addr;
|
||||
DWORD rva_start, addr;
|
||||
char * forward;
|
||||
IMAGE_EXPORT_DIRECTORY *exports = get_exports(wm->module);
|
||||
FARPROC proc;
|
||||
IMAGE_EXPORT_DIRECTORY *exports;
|
||||
DWORD exp_size;
|
||||
|
||||
if (HIWORD(funcName))
|
||||
TRACE("(%s)\n",funcName);
|
||||
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);
|
||||
if (!(exports = RtlImageDirectoryEntryToData( wm->module, TRUE,
|
||||
IMAGE_DIRECTORY_ENTRY_EXPORT, &exp_size )))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (HIWORD(funcName)) TRACE("(%s)\n",funcName);
|
||||
else TRACE("(%d)\n",LOWORD(funcName));
|
||||
|
||||
ordinals= RVA(exports->AddressOfNameOrdinals);
|
||||
function= RVA(exports->AddressOfFunctions);
|
||||
name = RVA(exports->AddressOfNames);
|
||||
forward = NULL;
|
||||
rva_start = PE_HEADER(wm->module)->OptionalHeader
|
||||
.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
|
||||
rva_end = rva_start + PE_HEADER(wm->module)->OptionalHeader
|
||||
.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
|
||||
rva_start = (char *)exports - (char *)wm->module;
|
||||
|
||||
if (HIWORD(funcName))
|
||||
{
|
||||
|
@ -219,9 +191,10 @@ static FARPROC PE_FindExportedFunction(
|
|||
}
|
||||
addr = function[ordinal];
|
||||
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 (!ename) ename = "@";
|
||||
|
@ -232,8 +205,7 @@ static FARPROC PE_FindExportedFunction(
|
|||
else /* forward entry point */
|
||||
{
|
||||
WINE_MODREF *wm_fw;
|
||||
FARPROC proc;
|
||||
char *forward = RVA(addr);
|
||||
char *forward = (char *)proc;
|
||||
char module[256];
|
||||
char *end = strchr(forward, '.');
|
||||
|
||||
|
@ -257,10 +229,12 @@ static FARPROC PE_FindExportedFunction(
|
|||
*/
|
||||
DWORD PE_fixup_imports( WINE_MODREF *wm )
|
||||
{
|
||||
IMAGE_IMPORT_DESCRIPTOR *pe_imp;
|
||||
unsigned int load_addr = wm->module;
|
||||
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 */
|
||||
pe_imp = imports;
|
||||
|
@ -406,21 +380,11 @@ HMODULE PE_LoadImage( HANDLE hFile, LPCSTR filename, DWORD flags )
|
|||
/* virus check */
|
||||
|
||||
hModule = (HMODULE)base;
|
||||
nt = PE_HEADER( hModule );
|
||||
nt = RtlImageNtHeader( hModule );
|
||||
|
||||
if (nt->OptionalHeader.AddressOfEntryPoint)
|
||||
{
|
||||
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 (nt->OptionalHeader.AddressOfEntryPoint < sec->VirtualAddress)
|
||||
continue;
|
||||
if (nt->OptionalHeader.AddressOfEntryPoint < sec->VirtualAddress+sec->SizeOfRawData)
|
||||
break;
|
||||
}
|
||||
if (i == nt->FileHeader.NumberOfSections)
|
||||
if (!RtlImageRvaToSection( nt, hModule, nt->OptionalHeader.AddressOfEntryPoint ))
|
||||
MESSAGE("VIRUS WARNING: PE module has an invalid entrypoint (0x%08lx) "
|
||||
"outside all sections (possibly infected by Tchernobyl/SpaceFiller virus)!\n",
|
||||
nt->OptionalHeader.AddressOfEntryPoint );
|
||||
|
@ -448,7 +412,7 @@ WINE_MODREF *PE_CreateModule( HMODULE hModule, LPCSTR filename, DWORD flags,
|
|||
HANDLE hFile, BOOL builtin )
|
||||
{
|
||||
DWORD load_addr = (DWORD)hModule; /* for RVA */
|
||||
IMAGE_NT_HEADERS *nt = PE_HEADER(hModule);
|
||||
IMAGE_NT_HEADERS *nt;
|
||||
IMAGE_DATA_DIRECTORY *dir;
|
||||
IMAGE_EXPORT_DIRECTORY *pe_export = NULL;
|
||||
WINE_MODREF *wm;
|
||||
|
@ -456,6 +420,7 @@ WINE_MODREF *PE_CreateModule( HMODULE hModule, LPCSTR filename, DWORD flags,
|
|||
|
||||
/* Retrieve DataDirectory entries */
|
||||
|
||||
nt = RtlImageNtHeader(hModule);
|
||||
dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_EXPORT;
|
||||
if (dir->Size)
|
||||
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 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? */
|
||||
if ((nt->FileHeader.Characteristics & IMAGE_FILE_DLL) &&
|
||||
if (nt && (nt->FileHeader.Characteristics & IMAGE_FILE_DLL) &&
|
||||
(nt->OptionalHeader.AddressOfEntryPoint))
|
||||
{
|
||||
DLLENTRYPROC entry = (void*)((char*)module + nt->OptionalHeader.AddressOfEntryPoint);
|
||||
|
@ -692,19 +657,17 @@ void PE_InitTls( void )
|
|||
{
|
||||
WINE_MODREF *wm;
|
||||
IMAGE_NT_HEADERS *peh;
|
||||
DWORD size,datasize;
|
||||
DWORD size,datasize,dirsize;
|
||||
LPVOID mem;
|
||||
PIMAGE_TLS_DIRECTORY pdir;
|
||||
int delta;
|
||||
|
||||
for (wm = MODULE_modref_list;wm;wm=wm->next) {
|
||||
peh = PE_HEADER(wm->module);
|
||||
delta = wm->module - peh->OptionalHeader.ImageBase;
|
||||
if (!peh->OptionalHeader.DataDirectory[IMAGE_FILE_THREAD_LOCAL_STORAGE].VirtualAddress)
|
||||
continue;
|
||||
pdir = (LPVOID)(wm->module + peh->OptionalHeader.
|
||||
DataDirectory[IMAGE_FILE_THREAD_LOCAL_STORAGE].VirtualAddress);
|
||||
|
||||
peh = RtlImageNtHeader(wm->module);
|
||||
pdir = RtlImageDirectoryEntryToData( wm->module, TRUE,
|
||||
IMAGE_DIRECTORY_ENTRY_TLS, &dirsize );
|
||||
if (!pdir) continue;
|
||||
delta = (char *)wm->module - (char *)peh->OptionalHeader.ImageBase;
|
||||
|
||||
if ( wm->tlsindex == -1 ) {
|
||||
LPDWORD xaddr;
|
||||
|
|
|
@ -32,34 +32,13 @@
|
|||
#include "wine/unicode.h"
|
||||
#include "windef.h"
|
||||
#include "winnls.h"
|
||||
#include "ntddk.h"
|
||||
#include "winerror.h"
|
||||
#include "module.h"
|
||||
#include "stackframe.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
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
|
||||
*
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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 )
|
||||
{
|
||||
const IMAGE_DATA_DIRECTORY *dir;
|
||||
const IMAGE_RESOURCE_DIRECTORY *ret = NULL;
|
||||
const void *base = get_module_base( hmod );
|
||||
DWORD size;
|
||||
|
||||
if (base)
|
||||
if (!hmod) hmod = GetModuleHandleA( NULL );
|
||||
else if (!HIWORD(hmod))
|
||||
{
|
||||
dir = &PE_HEADER(base)->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE];
|
||||
if (dir->Size && dir->VirtualAddress)
|
||||
{
|
||||
if (is_data_file_module(hmod)) ret = get_data_file_ptr( base, dir->VirtualAddress );
|
||||
else ret = (IMAGE_RESOURCE_DIRECTORY *)((char *)base + dir->VirtualAddress);
|
||||
FIXME("Enumeration of 16-bit resources is not supported\n");
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
return RtlImageDirectoryEntryToData( hmod, TRUE, IMAGE_DIRECTORY_ENTRY_RESOURCE, &size );
|
||||
}
|
||||
|
||||
|
||||
|
@ -325,16 +278,19 @@ HRSRC PE_FindResourceW( HMODULE hmod, LPCWSTR name, LPCWSTR type )
|
|||
HGLOBAL PE_LoadResource( HMODULE hmod, HRSRC hRsrc )
|
||||
{
|
||||
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;
|
||||
|
||||
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
|
||||
return (HANDLE)((char *)base + offset);
|
||||
return (HGLOBAL)((char *)hmod + offset);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "winreg.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
#include "ntddk.h"
|
||||
#include "wine/winbase16.h"
|
||||
#include "module.h"
|
||||
#include "wine/debug.h"
|
||||
|
@ -352,11 +353,11 @@ static void VERSION_Init(void)
|
|||
*/
|
||||
static DWORD VERSION_GetSystemDLLVersion( HMODULE hmod )
|
||||
{
|
||||
IMAGE_DATA_DIRECTORY *dir = PE_HEADER(hmod)->OptionalHeader.DataDirectory
|
||||
+ IMAGE_DIRECTORY_ENTRY_IMPORT;
|
||||
if (dir->Size && dir->VirtualAddress)
|
||||
DWORD size;
|
||||
IMAGE_IMPORT_DESCRIPTOR *pe_imp;
|
||||
|
||||
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++)
|
||||
{
|
||||
char * name = (char *)hmod + (unsigned int)pe_imp->Name;
|
||||
|
@ -364,7 +365,7 @@ static DWORD VERSION_GetSystemDLLVersion( HMODULE hmod )
|
|||
|
||||
if (!strncasecmp(name, "ntdll", 5))
|
||||
{
|
||||
switch(PE_HEADER(hmod)->OptionalHeader.MajorOperatingSystemVersion) {
|
||||
switch(RtlImageNtHeader(hmod)->OptionalHeader.MajorOperatingSystemVersion) {
|
||||
case 3:
|
||||
MESSAGE("WARNING: very old native DLL (NT 3.x) used, might cause instability.\n");
|
||||
return NT351;
|
||||
|
@ -405,12 +406,14 @@ DWORD VERSION_GetLinkedDllVersion(void)
|
|||
WINE_MODREF *wm;
|
||||
DWORD WinVersion = NB_WINDOWS_VERSIONS;
|
||||
PIMAGE_OPTIONAL_HEADER ophd;
|
||||
IMAGE_NT_HEADERS *nt;
|
||||
|
||||
/* First check the native dlls provided. These have to be
|
||||
from one windows version */
|
||||
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",
|
||||
wm->modname,
|
||||
|
@ -449,7 +452,8 @@ DWORD VERSION_GetLinkedDllVersion(void)
|
|||
if(WinVersion != NB_WINDOWS_VERSIONS) return WinVersion;
|
||||
|
||||
/* 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",
|
||||
ophd->MajorLinkerVersion, ophd->MinorLinkerVersion,
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <unistd.h>
|
||||
#include "winbase.h"
|
||||
#include "windef.h"
|
||||
#include "ntddk.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
#include "wine/winbase16.h"
|
||||
|
@ -758,8 +759,10 @@ void WINAPI VXD_Win32s( CONTEXT86 *context )
|
|||
(struct Win32sModule *)W32S_APP2WINE(context->Edx);
|
||||
struct Win32sModule *module = moduleTable + context->Ecx;
|
||||
|
||||
IMAGE_NT_HEADERS *nt_header = PE_HEADER(module->baseAddr);
|
||||
IMAGE_SECTION_HEADER *pe_seg = PE_SECTIONS(module->baseAddr);
|
||||
IMAGE_NT_HEADERS *nt_header = RtlImageNtHeader( (HMODULE)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);
|
||||
BOOL error = (image == HFILE_ERROR);
|
||||
|
|
|
@ -86,6 +86,7 @@ int BUILTIN32_dlclose( void *handle )
|
|||
static void load_library( void *base, const char *filename )
|
||||
{
|
||||
HMODULE module = (HMODULE)base;
|
||||
IMAGE_NT_HEADERS *nt;
|
||||
WINE_MODREF *wm;
|
||||
char *fullname;
|
||||
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" );
|
||||
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 (!main_module) main_module = module;
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "winnt.h"
|
||||
#include "ntddk.h"
|
||||
#include "winreg.h"
|
||||
#include "stackframe.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 )
|
||||
{
|
||||
IMAGE_DATA_DIRECTORY *dir;
|
||||
IMAGE_EXPORT_DIRECTORY *exp = NULL;
|
||||
DEBUG_ENTRY_POINT *debug;
|
||||
char *p, *base = NULL;
|
||||
const char *name;
|
||||
int ordinal = 0;
|
||||
WINE_MODREF *wm;
|
||||
DWORD size;
|
||||
|
||||
/* First find the module */
|
||||
|
||||
for (wm = MODULE_modref_list; wm; wm = wm->next)
|
||||
{
|
||||
if (!(wm->flags & WINE_MODREF_INTERNAL)) continue;
|
||||
base = (char *)wm->module;
|
||||
dir = &PE_HEADER(base)->OptionalHeader.DataDirectory[IMAGE_FILE_EXPORT_DIRECTORY];
|
||||
if (!dir->Size) continue;
|
||||
exp = (IMAGE_EXPORT_DIRECTORY *)(base + dir->VirtualAddress);
|
||||
debug = (DEBUG_ENTRY_POINT *)((char *)exp + dir->Size);
|
||||
exp = RtlImageDirectoryEntryToData( wm->module, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &size );
|
||||
if (!exp) continue;
|
||||
debug = (DEBUG_ENTRY_POINT *)((char *)exp + size);
|
||||
if (debug <= relay && relay < debug + exp->NumberOfFunctions)
|
||||
{
|
||||
ordinal = relay - debug;
|
||||
|
@ -226,6 +225,7 @@ static void get_entry_point( char *buffer, DEBUG_ENTRY_POINT *relay )
|
|||
|
||||
/* Now find the function */
|
||||
|
||||
base = (char *)wm->module;
|
||||
strcpy( buffer, base + exp->Name );
|
||||
p = buffer + strlen(buffer);
|
||||
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 )
|
||||
{
|
||||
IMAGE_DATA_DIRECTORY *dir;
|
||||
IMAGE_EXPORT_DIRECTORY *exports;
|
||||
DEBUG_ENTRY_POINT *debug;
|
||||
DWORD *funcs;
|
||||
int i;
|
||||
const char *name;
|
||||
char *p, dllname[80];
|
||||
DWORD size;
|
||||
|
||||
dir = &PE_HEADER(module)->OptionalHeader.DataDirectory[IMAGE_FILE_EXPORT_DIRECTORY];
|
||||
if (!dir->Size) return;
|
||||
exports = (IMAGE_EXPORT_DIRECTORY *)(module + dir->VirtualAddress);
|
||||
debug = (DEBUG_ENTRY_POINT *)((char *)exports + dir->Size);
|
||||
exports = RtlImageDirectoryEntryToData( (HMODULE)module, TRUE,
|
||||
IMAGE_DIRECTORY_ENTRY_EXPORT, &size );
|
||||
if (!exports) return;
|
||||
debug = (DEBUG_ENTRY_POINT *)((char *)exports + size);
|
||||
funcs = (DWORD *)(module + exports->AddressOfFunctions);
|
||||
strcpy( dllname, module + exports->Name );
|
||||
p = dllname + strlen(dllname) - 4;
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <string.h>
|
||||
#include "winbase.h"
|
||||
#include "winnt.h"
|
||||
#include "ntddk.h"
|
||||
#include "snoop.h"
|
||||
#include "stackframe.h"
|
||||
#include "wine/debug.h"
|
||||
|
@ -175,30 +176,16 @@ FARPROC
|
|||
SNOOP_GetProcAddress(HMODULE hmod,LPCSTR name,DWORD ordinal,FARPROC origfun) {
|
||||
SNOOP_DLL *dll = firstdll;
|
||||
SNOOP_FUN *fun;
|
||||
int j;
|
||||
IMAGE_SECTION_HEADER *pe_seg = PE_SECTIONS(hmod);
|
||||
IMAGE_SECTION_HEADER *sec;
|
||||
|
||||
if (!TRACE_ON(snoop)) return origfun;
|
||||
if (!*(LPBYTE)origfun) /* 0x00 is an imposs. opcode, poss. dataref. */
|
||||
return origfun;
|
||||
for (j=0;j<PE_HEADER(hmod)->FileHeader.NumberOfSections;j++)
|
||||
/* 0x42 is special ELF loader tag */
|
||||
if ((pe_seg[j].VirtualAddress==0x42) ||
|
||||
(((char *)origfun - (char *)hmod>=pe_seg[j].VirtualAddress)&&
|
||||
((char *)origfun - (char *)hmod <pe_seg[j].VirtualAddress+
|
||||
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;
|
||||
|
||||
sec = RtlImageRvaToSection( RtlImageNtHeader(hmod), hmod, (char *)origfun - (char *)hmod );
|
||||
|
||||
if (!sec || !(sec->Characteristics & IMAGE_SCN_CNT_CODE))
|
||||
return origfun; /* most likely a data reference */
|
||||
|
||||
while (dll) {
|
||||
if (hmod == dll->hmod)
|
||||
|
|
|
@ -450,6 +450,7 @@ static void start_process(void)
|
|||
LPTHREAD_START_ROUTINE entry;
|
||||
WINE_MODREF *wm;
|
||||
HANDLE main_file = main_exe_file;
|
||||
IMAGE_NT_HEADERS *nt;
|
||||
|
||||
/* use original argv[0] as name for the main module */
|
||||
if (!main_exe_name[0])
|
||||
|
@ -466,16 +467,17 @@ static void start_process(void)
|
|||
}
|
||||
|
||||
/* Retrieve entry point address */
|
||||
nt = RtlImageNtHeader( current_process.module );
|
||||
entry = (LPTHREAD_START_ROUTINE)((char*)current_process.module +
|
||||
PE_HEADER(current_process.module)->OptionalHeader.AddressOfEntryPoint);
|
||||
console_app = (PE_HEADER(current_process.module)->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI);
|
||||
nt->OptionalHeader.AddressOfEntryPoint);
|
||||
console_app = (nt->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI);
|
||||
if (console_app) current_process.flags |= PDB32_CONSOLE_PROC;
|
||||
|
||||
/* Signal the parent process to continue */
|
||||
SERVER_START_REQ( init_process_done )
|
||||
{
|
||||
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;
|
||||
/* API requires a double indirection */
|
||||
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 */
|
||||
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 */
|
||||
if (!THREAD_InitStack( NtCurrentTeb(), stack_size )) goto error;
|
||||
|
|
Loading…
Reference in New Issue