Ignore:
Timestamp:
Jan 15, 2004, 11:39:15 AM (22 years ago)
Author:
sandervl
Message:

Loader updates

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kernel32/winimagebase.cpp

    r9617 r10397  
    1 /* $Id: winimagebase.cpp,v 1.36 2003-01-05 12:31:25 sandervl Exp $ */
     1/* $Id: winimagebase.cpp,v 1.37 2004-01-15 10:39:11 sandervl Exp $ */
    22
    33/*
     
    66 * Copyright 1998-1999 Sander van Leeuwen (sandervl@xs4all.nl)
    77 * Copyright 1998-2000 knut st. osmundsen (knut.stange.osmundsen@mynd.no)
     8 * Copyright 2003 Innotek Systemberatung GmbH (sandervl@innotek.de)
    89 *
    910 * Project Odin Software License can be found in LICENSE.TXT
     
    4849    errorState(NO_ERROR), entryPoint(0), fullpath(NULL),
    4950    tlsAddress(0), tlsIndexAddr(0), tlsInitSize(0), tlsTotalSize(0),
    50     tlsCallBackAddr(0), tlsIndex(-1), pResRootDir(NULL),
    51     ulRVAResourceSection(0), fIsPEImage(FALSE)
     51    tlsCallBackAddr(0), tlsIndex(-1), pResRootDir(NULL), poh(NULL),
     52    ulRVAResourceSection(0), fIsPEImage(FALSE), pExportDir(NULL)
    5253{
    5354  char *name;
     
    153154}
    154155//******************************************************************************
     156//
     157//  Win32ImageBase::findApi: find function in export table and change if necessary
     158//
     159//  Parameters:
     160//      char *name              - function name (NULL for ordinal search)
     161//      int ordinal             - function ordinal (only used if name == NULL)
     162//      ULONG pfnNewProc        - new function address (ignored if 0)
     163//
     164//  Returns:
     165//      0                       - not found
     166//      <>0                     - function address
     167//
     168//******************************************************************************
     169ULONG Win32ImageBase::findApi(char *pszName, ULONG ulOrdinal, ULONG pfnNewProc)
     170{
     171    PIMAGE_EXPORT_DIRECTORY ped = pExportDir;
     172
     173    /*
     174     * Get ped if it's NULL.
     175     */
     176    if (!ped)
     177    {
     178        if (!poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress)
     179            return 0;
     180        ped = (PIMAGE_EXPORT_DIRECTORY)getPointerFromRVA(poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
     181        pExportDir = ped;
     182    }
     183
     184    int     iExpOrdinal = 0;            /* index into address table. */
     185    if (pszName)
     186    {
     187        /*
     188         * Find Named Export: Do binary search on the name table.
     189         */
     190        const char**paRVANames = (const char **)getPointerFromRVA(ped->AddressOfNames);
     191        PUSHORT     paOrdinals = (PUSHORT)getPointerFromRVA(ped->AddressOfNameOrdinals);
     192        int         iStart = 1;
     193        int         iEnd = ped->NumberOfNames;
     194
     195        for (;;)
     196        {
     197            /* end of search? */
     198            if (iStart > iEnd)
     199            {
     200            #ifdef DEBUG
     201                /* do a linear search just to verify the correctness of the above algorithm */
     202                for (int i = 0; i < ped->NumberOfNames; i++)
     203                    if (!strcmp(paRVANames[i - 1] + (unsigned)hinstance, pszName))
     204                    {
     205                        dprintf(("bug in binary export search!!!\n"));
     206                        DebugInt3();
     207                    }
     208            #endif
     209                return 0;
     210            }
     211
     212            int i  = (iEnd - iStart) / 2 + iStart;
     213            const char *pszExpName  = (const char *)getPointerFromRVA(paRVANames[i - 1]);
     214            int         diff        = strcmp(pszExpName, pszName);
     215            if (diff > 0)       /* pszExpName > pszName: search chunck before i */
     216                iEnd = i - 1;
     217            else if (diff)      /* pszExpName < pszName: search chunk after i */
     218                iStart = i + 1;
     219            else                /* pszExpName == pszName */
     220            {
     221                iExpOrdinal = paOrdinals[i - 1];
     222                break;
     223            }
     224        } /* binary search thru name table */
     225    }
     226    else
     227    {
     228        /*
     229         * Find ordinal export: Simple table lookup.
     230         */
     231        if (    ulOrdinal >= ped->Base + max(ped->NumberOfNames, ped->NumberOfFunctions)
     232            ||  ulOrdinal < ped->Base)
     233            return NULL;
     234        iExpOrdinal = ulOrdinal - ped->Base;
     235    }
     236
     237    /*
     238     * Found export (iExpOrdinal).
     239     */
     240    PULONG      paAddress = (PULONG)getPointerFromRVA(ped->AddressOfFunctions);
     241    unsigned    uRVAExport  = paAddress[iExpOrdinal];
     242    unsigned    uRet;
     243
     244    /* Install override for the export (if requested) */
     245    if (pfnNewProc && uRet)
     246        paAddress[iExpOrdinal] = getRVAFromPointer((void*)pfnNewProc, TRUE);
     247
     248    if (    uRVAExport > poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress
     249        &&  uRVAExport < poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress
     250            + poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size)
     251        /* Resolve forwarder. */
     252        uRet = findForwarder(poh->ImageBase + uRVAExport, pszName, iExpOrdinal);
     253    else
     254        /* Get plain export address */
     255        uRet = (ULONG)getPointerFromRVA(uRVAExport, TRUE);
     256
     257    return uRet;
     258}
     259//******************************************************************************
     260//******************************************************************************
     261ULONG Win32ImageBase::findForwarder(ULONG virtaddr, char *apiname, ULONG ordinal)
     262{
     263    char         *forward;
     264    char         *forwarddll, *forwardapi;
     265    Win32DllBase *WinDll;
     266    DWORD         exportaddr;
     267    int           forwardord;
     268    int           iForwardDllLength;
     269    int           iForwardApiLength;
     270
     271    forward = (char *)(hinstance + (virtaddr - poh->ImageBase));
     272    iForwardDllLength = strlen(forward);
     273
     274    if(iForwardDllLength == 0)
     275        return 0;
     276
     277    forwarddll = (char*)alloca(iForwardDllLength);
     278    if(forwarddll == NULL) {
     279        DebugInt3();
     280        return 0;
     281    }
     282    memcpy(forwarddll, forward, iForwardDllLength + 1);
     283
     284    forwardapi = strchr(forwarddll, '.');
     285    if(forwardapi == NULL) {
     286        return 0;
     287    }
     288    *forwardapi++ = 0;
     289    iForwardApiLength = strlen(forwardapi);
     290    if(iForwardApiLength == 0) {
     291        return FALSE;
     292    }
     293    WinDll = Win32DllBase::findModule(forwarddll);
     294    if(WinDll == NULL) {
     295        return 0;
     296    }
     297    //check if name or ordinal forwarder
     298    forwardord = 0;
     299    if(*forwardapi >= '0' && *forwardapi <= '9') {
     300        forwardord = atoi(forwardapi);
     301    }
     302    if(forwardord != 0 || (iForwardApiLength == 1 && *forwardapi == '0')) {
     303         exportaddr = WinDll->getApi(forwardord);
     304    }
     305    else exportaddr = WinDll->getApi(forwardapi);
     306
     307    return exportaddr;
     308}
     309//******************************************************************************
    155310//******************************************************************************
    156311ULONG Win32ImageBase::setApi(char *name, ULONG pfnNewProc)
    157312{
    158     return -1; //only implemented for PE modules
     313    return findApi(name, 0, pfnNewProc);
    159314}
    160315//******************************************************************************
     
    162317ULONG Win32ImageBase::setApi(int ordinal, ULONG pfnNewProc)
    163318{
    164     return -1; //only implemented for PE modules
     319    return findApi(NULL, ordinal, pfnNewProc);
     320}
     321//******************************************************************************
     322//******************************************************************************
     323ULONG Win32ImageBase::getApi(char *name)
     324{
     325    return findApi(name, 0);
     326}
     327//******************************************************************************
     328//******************************************************************************
     329ULONG Win32ImageBase::getApi(int ordinal)
     330{
     331    return findApi(NULL, ordinal);
    165332}
    166333//******************************************************************************
     
    227394//the Characteristics member of the file header structure)
    228395//******************************************************************************
    229 ULONG Win32ImageBase::isPEImage(char *szFileName, DWORD *Characteristics, 
     396ULONG Win32ImageBase::isPEImage(char *szFileName, DWORD *Characteristics,
    230397                                DWORD *subsystem, DWORD *fNEExe)
    231398{
     
    243410 int    nSections, i;
    244411
    245   if(fNEExe) 
     412  if(fNEExe)
    246413      *fNEExe = FALSE;
    247414
     
    306473  }
    307474
    308   if(GetPEFileHeader (win32file, &fh) == FALSE) 
     475  if(GetPEFileHeader (win32file, &fh) == FALSE)
    309476  {
    310477        if(*(WORD *)PE_HEADER(win32file) == IMAGE_OS2_SIGNATURE) {
    311             if(fNEExe) 
     478            if(fNEExe)
    312479                *fNEExe = TRUE;
    313480        }
     
    334501        *subsystem = oh.Subsystem;
    335502  }
    336  
     503
    337504  free(win32file);
    338505  DosClose(win32handle);
     
    414581    return stricmp(pszModName, szModule) == 0;
    415582}
     583
     584/** Converts a RVA to an pointer into the loaded image.
     585 * @returns Pointer corresponding to the RVA.
     586 * @param   ulRVA       RVA to make a pointer.
     587 * @param   fOverride   Flags if the RVA might be to an overridden address (export).
     588 */
     589void *Win32ImageBase::getPointerFromRVA(ULONG ulRVA, BOOL fOverride/* = FALSE*/)
     590{
     591    return (PVOID)((char*)hinstance + ulRVA);
     592}
     593
     594/** Converts a pointer to an RVA for the loaded image.
     595 * @returns Pointer corresponding to the RVA.
     596 * @param   ulRVA       RVA to make a pointer.
     597 * @param   fOverride   Flags if the pointer might be to an overridden address (export).
     598 */
     599ULONG Win32ImageBase::getRVAFromPointer(void *pv, BOOL fOverride/* = FALSE*/)
     600{
     601    return (ULONG)pv - (ULONG)hinstance;
     602}
     603
Note: See TracChangeset for help on using the changeset viewer.