📄 pe_image.c
字号:
if ((pe_sec->SizeOfRawData < pe_sec->Misc.VirtualSize) && (pe_sec->SizeOfRawData & (page_size-1))) { DWORD end = (pe_sec->SizeOfRawData & ~(page_size-1)) + page_size; if (end > pe_sec->Misc.VirtualSize) end = pe_sec->Misc.VirtualSize; TRACE("clearing %p - %p\n", RVA(pe_sec->VirtualAddress) + pe_sec->SizeOfRawData, RVA(pe_sec->VirtualAddress) + end ); memset( (char*)RVA(pe_sec->VirtualAddress) + pe_sec->SizeOfRawData, 0, end - pe_sec->SizeOfRawData ); } } if ( reloc ) do_relocations( load_addr, (IMAGE_BASE_RELOCATION *)RVA(reloc) ); *version = ( (nt->OptionalHeader.MajorSubsystemVersion & 0xff) << 8 ) | (nt->OptionalHeader.MinorSubsystemVersion & 0xff); UnmapViewOfFile( (LPVOID)hModule ); return (HMODULE)load_addr;error: if (unix_handle != -1) close( unix_handle ); if (load_addr) VirtualFree( (LPVOID)load_addr, 0, MEM_RELEASE ); UnmapViewOfFile( (LPVOID)hModule ); return 0;}/********************************************************************** * PE_CreateModule * * Create WINE_MODREF structure for loaded HMODULE32, link it into * process modref_list, and fixup all imports. * * Note: hModule must point to a correctly allocated PE image, * with base relocations applied; the 16-bit dummy module * associated to hModule must already exist. * * Note: This routine must always be called in the context of the * process that is to own the module to be created. */WINE_MODREF *PE_CreateModule( HMODULE hModule, LPCSTR filename, DWORD flags, WIN_BOOL builtin ){ DWORD load_addr = (DWORD)hModule; IMAGE_NT_HEADERS *nt = PE_HEADER(hModule); IMAGE_DATA_DIRECTORY *dir; IMAGE_IMPORT_DESCRIPTOR *pe_import = NULL; IMAGE_EXPORT_DIRECTORY *pe_export = NULL; IMAGE_RESOURCE_DIRECTORY *pe_resource = NULL; WINE_MODREF *wm; dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_EXPORT; if (dir->Size) pe_export = (PIMAGE_EXPORT_DIRECTORY)RVA(dir->VirtualAddress); dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_IMPORT; if (dir->Size) pe_import = (PIMAGE_IMPORT_DESCRIPTOR)RVA(dir->VirtualAddress); dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_RESOURCE; if (dir->Size) pe_resource = (PIMAGE_RESOURCE_DIRECTORY)RVA(dir->VirtualAddress); dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_EXCEPTION; if (dir->Size) FIXME("Exception directory ignored\n" ); dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_SECURITY; if (dir->Size) FIXME("Security directory ignored\n" ); dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_DEBUG; if (dir->Size) TRACE("Debug directory ignored\n" ); dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_COPYRIGHT; if (dir->Size) FIXME("Copyright string ignored\n" ); dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_GLOBALPTR; if (dir->Size) FIXME("Global Pointer (MIPS) ignored\n" ); dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG; if (dir->Size) FIXME("Load Configuration directory ignored\n" ); dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT; if (dir->Size) TRACE("Bound Import directory ignored\n" ); dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_IAT; if (dir->Size) TRACE("Import Address Table directory ignored\n" ); dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT; if (dir->Size) { TRACE("Delayed import, stub calls LoadLibrary\n" ); /* * Nothing to do here. */#ifdef ImgDelayDescr /* * This code is useful to observe what the heck is going on. */ { ImgDelayDescr *pe_delay = NULL; pe_delay = (PImgDelayDescr)RVA(dir->VirtualAddress); TRACE_(delayhlp)("pe_delay->grAttrs = %08x\n", pe_delay->grAttrs); TRACE_(delayhlp)("pe_delay->szName = %s\n", pe_delay->szName); TRACE_(delayhlp)("pe_delay->phmod = %08x\n", pe_delay->phmod); TRACE_(delayhlp)("pe_delay->pIAT = %08x\n", pe_delay->pIAT); TRACE_(delayhlp)("pe_delay->pINT = %08x\n", pe_delay->pINT); TRACE_(delayhlp)("pe_delay->pBoundIAT = %08x\n", pe_delay->pBoundIAT); TRACE_(delayhlp)("pe_delay->pUnloadIAT = %08x\n", pe_delay->pUnloadIAT); TRACE_(delayhlp)("pe_delay->dwTimeStamp = %08x\n", pe_delay->dwTimeStamp); }#endif } dir = nt->OptionalHeader.DataDirectory+IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR; if (dir->Size) FIXME("Unknown directory 14 ignored\n" ); dir = nt->OptionalHeader.DataDirectory+15; if (dir->Size) FIXME("Unknown directory 15 ignored\n" ); wm = (WINE_MODREF *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wm) ); wm->module = hModule; if ( builtin ) wm->flags |= WINE_MODREF_INTERNAL; if ( flags & DONT_RESOLVE_DLL_REFERENCES ) wm->flags |= WINE_MODREF_DONT_RESOLVE_REFS; if ( flags & LOAD_LIBRARY_AS_DATAFILE ) wm->flags |= WINE_MODREF_LOAD_AS_DATAFILE; wm->type = MODULE32_PE; wm->binfmt.pe.pe_export = pe_export; wm->binfmt.pe.pe_import = pe_import; wm->binfmt.pe.pe_resource = pe_resource; wm->binfmt.pe.tlsindex = -1; wm->filename = malloc(strlen(filename)+1); strcpy(wm->filename, filename ); wm->modname = strrchr( wm->filename, '\\' ); if (!wm->modname) wm->modname = wm->filename; else wm->modname++; if ( pe_export ) dump_exports( hModule ); /* Fixup Imports */ if ( pe_import && !( wm->flags & WINE_MODREF_LOAD_AS_DATAFILE ) && !( wm->flags & WINE_MODREF_DONT_RESOLVE_REFS ) && fixup_imports( wm ) ) { /* remove entry from modref chain */ return NULL; } return wm;}/****************************************************************************** * The PE Library Loader frontend. * FIXME: handle the flags. */WINE_MODREF *PE_LoadLibraryExA (LPCSTR name, DWORD flags){ HMODULE hModule32; WINE_MODREF *wm; char filename[256]; int hFile; WORD version = 0; strncpy(filename, name, sizeof(filename)); hFile=open(filename, O_RDONLY); if(hFile==-1) return NULL; hModule32 = PE_LoadImage( hFile, filename, &version ); if (!hModule32) { SetLastError( ERROR_OUTOFMEMORY ); return NULL; } if ( !(wm = PE_CreateModule( hModule32, filename, flags, FALSE )) ) { ERR( "can't load %s\n", filename ); SetLastError( ERROR_OUTOFMEMORY ); return NULL; } close(hFile); //printf("^^^^^^^^^^^^^^^^Alloc VM1 %p\n", wm); return wm;}/***************************************************************************** * PE_UnloadLibrary * * Unload the library unmapping the image and freeing the modref structure. */void PE_UnloadLibrary(WINE_MODREF *wm){ TRACE(" unloading %s\n", wm->filename); if (wm->filename) free(wm->filename); if (wm->short_filename) free(wm->short_filename); HeapFree( GetProcessHeap(), 0, wm->deps ); VirtualFree( (LPVOID)wm->module, 0, MEM_RELEASE ); HeapFree( GetProcessHeap(), 0, wm ); //printf("^^^^^^^^^^^^^^^^Free VM1 %p\n", wm);}/***************************************************************************** * Load the PE main .EXE. All other loading is done by PE_LoadLibraryExA * FIXME: this function should use PE_LoadLibraryExA, but currently can't * due to the PROCESS_Create stuff. *//* * This is a dirty hack. * The win32 DLLs contain an alloca routine, that first probes the soon * to be allocated new memory *below* the current stack pointer in 4KByte * increments. After the mem probing below the current %esp, the stack * pointer is finally decremented to make room for the "alloca"ed memory. * Maybe the probing code is intended to extend the stack on a windows box. * Anyway, the linux kernel does *not* extend the stack by simply accessing * memory below %esp; it segfaults. * The extend_stack_for_dll_alloca() routine just preallocates a big chunk * of memory on the stack, for use by the DLLs alloca routine. * Added the noinline attribute as e.g. gcc 3.2.2 inlines this function * in a way that breaks it. */static void __attribute__((noinline)) extend_stack_for_dll_alloca(void){#if !defined(__FreeBSD__) && !defined(__DragonFly__) volatile int* mem=alloca(0x20000); *mem=0x1234;#endif}/* Called if the library is loaded or freed. * NOTE: if a thread attaches a DLL, the current thread will only do * DLL_PROCESS_ATTACH. Only new created threads do DLL_THREAD_ATTACH * (SDK) */WIN_BOOL PE_InitDLL( WINE_MODREF *wm, DWORD type, LPVOID lpReserved ){ WIN_BOOL retv = TRUE; assert( wm->type == MODULE32_PE ); if ((PE_HEADER(wm->module)->FileHeader.Characteristics & IMAGE_FILE_DLL) && (PE_HEADER(wm->module)->OptionalHeader.AddressOfEntryPoint) ) { DLLENTRYPROC entry ; entry = (void*)PE_FindExportedFunction(wm, "DllMain", 0); if(entry==NULL) entry = (void*)RVA_PTR( wm->module,OptionalHeader.AddressOfEntryPoint ); TRACE_(relay)("CallTo32(entryproc=%p,module=%08x,type=%ld,res=%p)\n", entry, wm->module, type, lpReserved ); TRACE("Entering DllMain("); switch(type) { case DLL_PROCESS_DETACH: TRACE("DLL_PROCESS_DETACH) "); break; case DLL_PROCESS_ATTACH: TRACE("DLL_PROCESS_ATTACH) "); break; case DLL_THREAD_DETACH: TRACE("DLL_THREAD_DETACH) "); break; case DLL_THREAD_ATTACH: TRACE("DLL_THREAD_ATTACH) "); break; } TRACE("for %s\n", wm->filename); extend_stack_for_dll_alloca(); retv = entry( wm->module, type, lpReserved ); } return retv;}static LPVOID_fixup_address(PIMAGE_OPTIONAL_HEADER opt,int delta,LPVOID addr) { if ( ((DWORD)addr>opt->ImageBase) && ((DWORD)addr<opt->ImageBase+opt->SizeOfImage) ) return (LPVOID)(((DWORD)addr)+delta); else return addr;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -