Running an installer for FAR file manager with turned on win32 debug channel leads to crash due to invalid address of export table. This installer can be downloaded at http://www.rarlab.com/download.htm, the executable file seems compressed with RAR archiver. Run as wine -debugmsg +win32 far1704.exe to see error. The patch is against the wine-20030219 release. Changelog: Prevent a crash when dumping invalid export table, small cleanup and reindentation --- loader/pe_image.c.0 Mon Feb 24 03:34:55 2003 +++ loader/pe_image.c Thu Feb 27 00:20:41 2003 @@ -46,6 +46,8 @@ #include "snoop.h" #include "wine/server.h" #include "wine/debug.h" +#include "excpt.h" +#include "wine/exception.h" WINE_DEFAULT_DEBUG_CHANNEL(win32); WINE_DECLARE_DEBUG_CHANNEL(module); @@ -58,46 +60,70 @@ return (void *)((char *)module + va); } -#define AdjustPtr(ptr,delta) ((char *)(ptr) + (delta)) +static WINE_EXCEPTION_FILTER(page_fault) +{ + return EXCEPTION_ACCESS_VIOLATION == GetExceptionCode() ? + EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH; +} void dump_exports( HMODULE hModule ) { - char *Module; - int i, j; - WORD *ordinal; - DWORD *function,*functions; - DWORD *name; - IMAGE_EXPORT_DIRECTORY *pe_exports; - DWORD rva_start, size; - - pe_exports = RtlImageDirectoryEntryToData( hModule, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &size ); - rva_start = (char *)pe_exports - (char *)hModule; - - Module = get_rva(hModule, pe_exports->Name); - DPRINTF("*******EXPORT DATA*******\n"); - DPRINTF("Module name is %s, %ld functions, %ld names\n", - Module, pe_exports->NumberOfFunctions, pe_exports->NumberOfNames); - - ordinal = get_rva(hModule, pe_exports->AddressOfNameOrdinals); - functions = function = get_rva(hModule, pe_exports->AddressOfFunctions); - name = get_rva(hModule, pe_exports->AddressOfNames); - - DPRINTF(" Ord RVA Addr Name\n" ); - for (i=0;i<pe_exports->NumberOfFunctions;i++, function++) - { - if (!*function) continue; /* No such function */ - DPRINTF( "%4ld %08lx %p", i + pe_exports->Base, *function, get_rva(hModule, *function) ); - /* Check if we have a name for it */ - for (j = 0; j < pe_exports->NumberOfNames; j++) - if (ordinal[j] == i) - { - DPRINTF( " %s", (char*)get_rva(hModule, name[j]) ); - break; - } - if ((*function >= rva_start) && (*function <= rva_start + size)) - DPRINTF(" (forwarded -> %s)", (char *)get_rva(hModule, *function)); - DPRINTF("\n"); - } + char *Module; + int i, j; + WORD *ordinal; + DWORD *functions; + char *function; + DWORD *name; + IMAGE_EXPORT_DIRECTORY *pe_exports; + DWORD size; + + __TRY + { + pe_exports = RtlImageDirectoryEntryToData( hModule, TRUE, + IMAGE_DIRECTORY_ENTRY_EXPORT, &size ); + + Module = get_rva(hModule, pe_exports->Name); + DPRINTF("*******EXPORT DATA*******\n"); + DPRINTF("Module name is %s, %ld functions, %ld names\n", + Module, pe_exports->NumberOfFunctions, pe_exports->NumberOfNames); + + ordinal = get_rva(hModule, pe_exports->AddressOfNameOrdinals); + functions = get_rva(hModule, pe_exports->AddressOfFunctions); + name = get_rva(hModule, pe_exports->AddressOfNames); + + DPRINTF(" Ord RVA Addr Name\n" ); + for (i=0;i<pe_exports->NumberOfFunctions;i++, functions++) + { + if (!*functions) + continue; /* No such function */ + + function = get_rva(hModule, *functions); + + DPRINTF( "%4ld %08lx %p", + i + pe_exports->Base, *functions, function ); + + /* Check if we have a name for it */ + for (j = 0; j < pe_exports->NumberOfNames; j++) + if (ordinal[j] == i) + { + DPRINTF( " %s", (char*)get_rva(hModule, name[j]) ); + break; + } + + if ((function >= (char*)pe_exports) && + (function <= (char*)pe_exports + size)) + { + DPRINTF(" (forwarded -> %s)", function); + } + + DPRINTF("\n"); + } + } + __EXCEPT( page_fault ) + { + WARN( "Invalid export directory\n"); + } + __ENDTRY } /* Look up the specified function or ordinal in the export list: -- Best regards, Pavel mailto:p_lapin@mail.ru