コード例 #1
0
ファイル: pe_image.c プロジェクト: 0p1pp1/mplayer
/* 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 )
{
	unsigned short			* ordinals;
	unsigned long			* function;
	unsigned 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;
	unsigned 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= (unsigned short*)  RVA(exports->AddressOfNameOrdinals);
	function= (unsigned long*)   RVA(exports->AddressOfFunctions);
	name	= (unsigned 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 );
	}
}
コード例 #2
0
ファイル: module.c プロジェクト: BOTCrusher/sagetv
/***********************************************************************
 *           GetProcAddress   		(KERNEL32.257)
 */
FARPROC WINAPI GetProcAddress( HMODULE hModule, LPCSTR function )
{
    return MODULE_GetProcAddress( hModule, function, TRUE );
}