⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pe_image.c

📁 君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图片解码,浏览,电子书,录音,想学ucos,识货的人就下吧 russblock fmradio explore set
💻 C
📖 第 1 页 / 共 3 页
字号:
/*  *  Copyright	1994	Eric Youndale & Erik Bos *  Copyright	1995	Martin von Löwis *  Copyright   1996-98 Marcus Meissner * *	based on Eric Youndale's pe-test and: * *	ftp.microsoft.com:/pub/developer/MSDN/CD8/PEFILE.ZIP * make that: *	ftp.microsoft.com:/developr/MSDN/OctCD/PEFILE.ZIP * * Modified for use with MPlayer, detailed changelog at * http://svn.mplayerhq.hu/mplayer/trunk/ * $Id: pe_image.c,v 1.3 2008/04/12 07:14:45 dsqiu Exp $ * *//* Notes: * Before you start changing something in this file be aware of the following: * * - There are several functions called recursively. In a very subtle and  *   obscure way. DLLs can reference each other recursively etc. * - If you want to enhance, speed up or clean up something in here, think *   twice WHY it is implemented in that strange way. There is usually a reason. *   Though sometimes it might just be lazyness ;) * - In PE_MapImage, right before fixup_imports() all external and internal  *   state MUST be correct since this function can be called with the SAME image *   AGAIN. (Thats recursion for you.) That means MODREF.module and *   NE_MODULE.module32. * - Sometimes, we can't use Linux mmap() to mmap() the images directly. * *   The problem is, that there is not direct 1:1 mapping from a diskimage and *   a memoryimage. The headers at the start are mapped linear, but the sections *   are not. Older x86 pe binaries are 512 byte aligned in file and 4096 byte *   aligned in memory. Linux likes them 4096 byte aligned in memory (due to *   x86 pagesize, this cannot be fixed without a rather large kernel rewrite) *   and 'blocksize' file-aligned (offsets). Since we have 512/1024/2048 (CDROM) *   and other byte blocksizes, we can't always do this.  We *can* do this for *   newer pe binaries produced by MSVC 5 and later, since they are also aligned *   to 4096 byte boundaries on disk. */#include "config.h"#include "debug.h"#include <errno.h>#include <assert.h>#include <mplaylib.h>#include <mplaylib.h>#include <mplaylib.h>#include <mplaylib.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#ifdef HAVE_SYS_MMAN_H#include <sys/mman.h>#endif#include "wine/windef.h"#include "wine/winbase.h"#include "wine/winerror.h"#include "wine/heap.h"#include "wine/pe_image.h"#include "wine/module.h"#include "wine/debugtools.h"#include "ext.h"#include "win32.h"#undef memcpy#define memcpy uc_memcpy#define RVA(x) ((void *)((char *)load_addr+(unsigned int)(x)))#define AdjustPtr(ptr,delta) ((char *)(ptr) + (delta))static void dump_exports( HMODULE hModule ){   char		*Module;  unsigned int i, j;  u_short	*ordinal;  u_long	*function,*functions;  u_char	**name;  unsigned int load_addr = hModule;  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);  Module = (char*)RVA(pe_exports->Name);  TRACE("*******EXPORT DATA*******\n");  TRACE("Module name is %s, %ld functions, %ld names\n",         Module, pe_exports->NumberOfFunctions, pe_exports->NumberOfNames);  ordinal=(u_short*) RVA(pe_exports->AddressOfNameOrdinals);  functions=function=(u_long*) RVA(pe_exports->AddressOfFunctions);  name=(u_char**) RVA(pe_exports->AddressOfNames);  TRACE(" Ord    RVA     Addr   Name\n" );  for (i=0;i<pe_exports->NumberOfFunctions;i++, function++)  {      if (!*function) continue;        if (TRACE_ON(win32))      {	DPRINTF( "%4ld %08lx %p", i + pe_exports->Base, *function, RVA(*function) );		for (j = 0; j < pe_exports->NumberOfNames; j++)          if (ordinal[j] == i)          {              DPRINTF( "  %s", (char*)RVA(name[j]) );              break;          }	if ((*function >= rva_start) && (*function <= rva_end))	  DPRINTF(" (forwarded -> %s)", (char *)RVA(*function));	DPRINTF("\n");      }  }}/* Look up the specified function or ordinal in the exportlist: * If it is a string: * 	- look up the name in the Name list.  *	- look up the ordinal with that index. *	- use the ordinal as offset into the functionlist * If it is a ordinal: *	- use ordinal-pe_export->Base as offset into the functionlist */FARPROC PE_FindExportedFunction( 	WINE_MODREF *wm,		LPCSTR funcName,	        WIN_BOOL snoop ){	u_short				* ordinals;	u_long				* function;	u_char				** name;	const char *ename = NULL;	int				i, ordinal;	PE_MODREF			*pem = &(wm->binfmt.pe);	IMAGE_EXPORT_DIRECTORY 		*exports = pem->pe_export;	unsigned int			load_addr = wm->module;	u_long				rva_start, rva_end, addr;	char				* forward;	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,pem);		return NULL;	}	ordinals= (u_short*)  RVA(exports->AddressOfNameOrdinals);	function= (u_long*)   RVA(exports->AddressOfFunctions);	name	= (u_char **) 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;	if (HIWORD(funcName))        {                        int min = 0, max = exports->NumberOfNames - 1;            while (min <= max)            {                int res, pos = (min + max) / 2;		ename = (const char*) RVA(name[pos]);		if (!(res = strcmp( ename, funcName )))                {                    ordinal = ordinals[pos];                    goto found;                }                if (res > 0) max = pos - 1;                else min = pos + 1;            }            	    for (i = 0; i < exports->NumberOfNames; i++)            {		ename = (const char*) RVA(name[i]);                if (!strcmp( ename, funcName ))                {		    ERR( "%s.%s required a linear search\n", wm->modname, funcName );                    ordinal = ordinals[i];                    goto found;                }            }            return NULL;	}        else          {            ordinal = LOWORD(funcName) - exports->Base;            if (snoop && name)              {                for (i = 0; i < exports->NumberOfNames; i++)                    if (ordinals[i] == ordinal)                    {                        ename = RVA(name[i]);                        break;                    }            }	} found:        if (ordinal >= exports->NumberOfFunctions)        {            TRACE("	ordinal %ld out of range!\n", ordinal + exports->Base );            return NULL;        }        addr = function[ordinal];        if (!addr) return NULL;        if ((addr < rva_start) || (addr >= rva_end))        {            FARPROC proc = RVA(addr);            if (snoop)            {                if (!ename) ename = "@";//                proc = SNOOP_GetProcAddress(wm->module,ename,ordinal,proc);		TRACE("SNOOP_GetProcAddress n/a\n");		            }            return proc;        }        else          {                WINE_MODREF *wm;                char *forward = RVA(addr);		char module[256];		char *end = strchr(forward, '.');		if (!end) return NULL;                if (end - forward >= sizeof(module)) return NULL;                memcpy( module, forward, end - forward );		module[end-forward] = 0;                if (!(wm = MODULE_FindModule( module )))                {                    ERR("module not found for forward '%s'\n", forward );                    return NULL;                }		return MODULE_GetProcAddress( wm->module, end + 1, snoop );	}}static DWORD fixup_imports( WINE_MODREF *wm ){    IMAGE_IMPORT_DESCRIPTOR	*pe_imp;    PE_MODREF			*pem;    unsigned int load_addr	= wm->module;    int				i,characteristics_detection=1;    char			*modname;        assert(wm->type==MODULE32_PE);    pem = &(wm->binfmt.pe);    if (pem->pe_export)    	modname = (char*) RVA(pem->pe_export->Name);    else        modname = "<unknown>";        TRACE("Dumping imports list\n");        pe_imp = pem->pe_import;    if (!pe_imp) return 0;    /* We assume that we have at least one import with !0 characteristics and     * detect broken imports with all characteristsics 0 (notably Borland) and     * switch the detection off for them.     */    for (i = 0; pe_imp->Name ; pe_imp++) {	if (!i && !pe_imp->u.Characteristics)		characteristics_detection = 0;	if (characteristics_detection && !pe_imp->u.Characteristics)		break;	i++;    }    if (!i) return 0;          wm->nDeps = i;    wm->deps  = HeapAlloc( GetProcessHeap(), 0, i*sizeof(WINE_MODREF *) );    /* load the imported modules. They are automatically      * added to the modref list of the process.     */     for (i = 0, pe_imp = pem->pe_import; pe_imp->Name ; pe_imp++) {	IMAGE_IMPORT_BY_NAME	*pe_name;	PIMAGE_THUNK_DATA	import_list,thunk_list; 	char			*name = (char *) RVA(pe_imp->Name);	if (characteristics_detection && !pe_imp->u.Characteristics)		break;//#warning FIXME: here we should fill imports        TRACE("Loading imports for %s.dll\n", name);    	if (pe_imp->u.OriginalFirstThunk != 0) { 	    TRACE("Microsoft style imports used\n");	    import_list =(PIMAGE_THUNK_DATA) RVA(pe_imp->u.OriginalFirstThunk);	    thunk_list = (PIMAGE_THUNK_DATA) RVA(pe_imp->FirstThunk);	    while (import_list->u1.Ordinal) {		if (IMAGE_SNAP_BY_ORDINAL(import_list->u1.Ordinal)) {		    int ordinal = IMAGE_ORDINAL(import_list->u1.Ordinal);//		    TRACE("--- Ordinal %s,%d\n", name, ordinal);		    		    thunk_list->u1.Function=LookupExternal(name, ordinal);		} else {				    pe_name = (PIMAGE_IMPORT_BY_NAME)RVA(import_list->u1.AddressOfData);//		    TRACE("--- %s %s.%d\n", pe_name->Name, name, pe_name->Hint);		    thunk_list->u1.Function=LookupExternalByName(name, pe_name->Name);		}		import_list++;		thunk_list++;	    }	} else {		    TRACE("Borland style imports used\n");	    thunk_list = (PIMAGE_THUNK_DATA) RVA(pe_imp->FirstThunk);	    while (thunk_list->u1.Ordinal) {		if (IMAGE_SNAP_BY_ORDINAL(thunk_list->u1.Ordinal)) {		    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -