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/winimagepeldr.cpp

    r10001 r10397  
    1 /* $Id: winimagepeldr.cpp,v 1.108 2003-04-09 12:24:45 sandervl Exp $ */
     1/* $Id: winimagepeldr.cpp,v 1.109 2004-01-15 10:39:13 sandervl Exp $ */
    22
    33/*
     
    66 * Copyright 1998-2000 Sander van Leeuwen (sandervl@xs4all.nl)
    77 * Copyright 1998 Knut St. Osmundsen
     8 * Copyright 2003 Innotek Systemberatung GmbH (sandervl@innotek.de)
     9 *
    810 *
    911 * Project Odin Software License can be found in LICENSE.TXT
     
    110112    nrsections(0), imageSize(0), dwFlags(0), section(NULL),
    111113    imageVirtBase(-1), realBaseAddress(0), imageVirtEnd(0),
    112     nrNameExports(0), nrOrdExports(0), nameexports(NULL), ordexports(NULL),
    113     memmap(NULL), pFixups(NULL), dwFixupSize(0), curnameexport(NULL), curordexport(NULL),
    114     nrOrdExportsRegistered(0), peview(NULL)
    115 {
    116     HFILE  dllfile;
     114    memmap(NULL), pFixups(NULL), dwFixupSize(0), peview(NULL),
     115    originalBaseAddress(0)
     116{
     117    HFILE                 dllfile;
    117118
    118119    fIsPEImage = TRUE;
     
    166167    }
    167168
    168     if(nameexports)
    169         free(nameexports);
    170 
    171     if(ordexports)
    172         free(ordexports);
    173 
    174169    if(section)
    175170        free(section);
     
    181176 ULONG  filesize, ulRead, ulNewPos;
    182177 PIMAGE_SECTION_HEADER psh;
    183  IMAGE_SECTION_HEADER sh;
     178 IMAGE_SECTION_HEADER  sh;
     179 IMAGE_OPTIONAL_HEADER oh;
     180 IMAGE_FILE_HEADER     fh;
    184181 IMAGE_TLS_DIRECTORY *tlsDir = NULL;
    185182 int    nSections, i;
     
    245242        oh.SizeOfImage = OSLibDosGetFileSize(hFile, NULL);
    246243    }
     244    Characteristics = fh.Characteristics;
     245
     246    //save original base address of image
     247    originalBaseAddress = oh.ImageBase;
    247248
    248249    imageSize = oh.SizeOfImage;
     
    264265        setFullPath(szFullPath);
    265266    }
     267
     268    //Use pointer to image header as module handle now. Some apps needs this
     269#ifdef COMMIT_ALL
     270    commitPage(realBaseAddress, FALSE, SINGLE_PAGE);
     271#endif
     272    hinstance = (HINSTANCE)realBaseAddress;
     273
     274    //Calculate address of optional header
     275    poh = (PIMAGE_OPTIONAL_HEADER)OPTHEADEROFF(hinstance);
    266276
    267277    if(!(fh.Characteristics & IMAGE_FILE_EXECUTABLE_IMAGE)) {//not valid
     
    373383                continue;
    374384            }
    375             if(IsSectionType(peview, &psh[i], IMAGE_DIRECTORY_ENTRY_DEBUG))
    376             {
    377                 dprintf((LOG, ".rdebug" ));
    378                 addSection(SECTION_DEBUG,  psh[i].PointerToRawData,
    379                            psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
    380                            psh[i].Misc.VirtualSize, psh[i].Characteristics);
    381                 continue;
    382             }
    383385            if(IsSectionType(peview, &psh[i], IMAGE_DIRECTORY_ENTRY_IMPORT))
    384386            {
     
    406408                continue;
    407409            }
     410            /* bird: Do this test as late as possible since marking a section as debug
     411             *       because it the section will not be preloaded if marked SECTION_DEBUG
     412             *       causeing a lot of annoying page faults when all should be preloaded.
     413             *       A debug section may contain more than just the debug directory.
     414             *
     415             * IIRC the debug directory doesn't contain the debug info, it's a table telling
     416             * raw file offsets of the different debug types. It's never been any custom of
     417             * linkers to put debug info into loadable segments/sections/objects, so I've some
     418             * difficulty seeing why we're doing this in the first place.
     419             *
     420             * Why aren't we just using a general approach, which trust the section flags and
     421             * only precommits the tree directories we use (fixups/imports/exports)?
     422             */
     423            if(IsSectionType(peview, &psh[i], IMAGE_DIRECTORY_ENTRY_DEBUG))
     424            {
     425                dprintf((LOG, ".rdebug" ));
     426                addSection(SECTION_DEBUG,  psh[i].PointerToRawData,
     427                           psh[i].SizeOfRawData, psh[i].VirtualAddress + oh.ImageBase,
     428                           psh[i].Misc.VirtualSize, psh[i].Characteristics);
     429                continue;
     430            }
    408431            if(!(psh[i].Characteristics & IMAGE_SCN_MEM_WRITE)) { //read only data section
    409432                dprintf((LOG, "Read Only Data Section" ));
     
    474497        pFixups     = (PIMAGE_BASE_RELOCATION)ImageDirectoryOffset(peview, IMAGE_DIRECTORY_ENTRY_BASERELOC);
    475498        dwFixupSize = ImageDirectorySize(peview, IMAGE_DIRECTORY_ENTRY_BASERELOC);
    476         commitPage((ULONG)pFixups, FALSE);
    477     }
    478 
    479     //Use pointer to image header as module handle now. Some apps needs this
    480     hinstance = (HINSTANCE)realBaseAddress;
     499        /* commit complete section to avoid getting exceptions inside setFixups(). */
     500        commitPage((ULONG)pFixups, FALSE, COMPLETE_SECTION);
     501    }
    481502
    482503    if(!(dwFlags & FLAG_PELDR_LOADASDATAFILE))
     
    811832    }
    812833    if(fPageCmd == COMPLETE_SECTION && (section && section->type == SECTION_DEBUG)) {//ignore
     834#ifdef DEBUG
     835        /* check for env. var. ODIN_PELDR_COMMIT_ALL, committing it anyway if that is set. */
     836        static int f = -1;
     837        if (f == -1)
     838            f = (getenv("ODIN_PELDR_COMMIT_ALL") != NULL);
     839        if (!f)
     840#endif
    813841        return TRUE;
    814842    }
     
    931959BOOL Win32PeLdrImage::allocSections(ULONG reservedMem)
    932960{
    933  APIRET rc;
    934  ULONG  baseAddress;
     961    APIRET rc;
     962    ULONG  baseAddress;
    935963
    936964    realBaseAddress = 0;
    937965
    938966    //Allocated in by pe.exe
    939     if(reservedMem && reservedMem == oh.ImageBase) {
    940         realBaseAddress = oh.ImageBase;
     967    if(reservedMem && reservedMem == originalBaseAddress) {
     968        realBaseAddress = originalBaseAddress;
    941969        return TRUE;
    942970    }
    943971
    944972    //SvL: We don't care where the image is loaded for resource lookup
    945     if(fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED && !(dwFlags & FLAG_PELDR_LOADASDATAFILE)) {
     973    if(Characteristics & IMAGE_FILE_RELOCS_STRIPPED && !(dwFlags & FLAG_PELDR_LOADASDATAFILE)) {
    946974        return allocFixedMem(reservedMem);
    947975    }
     
    10291057    }
    10301058
    1031     if(oh.ImageBase < 512*1024*1024) {
     1059    if(originalBaseAddress < 512*1024*1024) {
    10321060        fLowMemory = TRUE;
    10331061    }
     
    10371065
    10381066        dprintf((LOG, "DosAllocMem returned %x", address ));
    1039         if(address + FALLOC_SIZE >= oh.ImageBase) {
    1040             if(address > oh.ImageBase) {//we've passed it!
     1067        if(address + FALLOC_SIZE >= originalBaseAddress) {
     1068            if(address > originalBaseAddress) {//we've passed it!
    10411069                OSLibDosFreeMem((PVOID)address);
    10421070                break;
     
    10451073            OSLibDosFreeMem((PVOID)address);
    10461074
    1047             diff = oh.ImageBase - address;
     1075            diff = originalBaseAddress - address;
    10481076            if(diff) {
    10491077                rc = OSLibDosAllocMem((PPVOID)&address, diff, PAG_READ, fLowMemory);
     
    10781106  // Process all the image sections
    10791107  for(i=0;i<nrsections;i++) {
    1080         section[i].realvirtaddr = realBaseAddress + (section[i].virtaddr - oh.ImageBase);
     1108        section[i].realvirtaddr = realBaseAddress + (section[i].virtaddr - originalBaseAddress);
    10811109  }
    10821110
     
    11281156 PIMAGE_BASE_RELOCATION prel = pFixups;
    11291157
    1130   if(realBaseAddress == oh.ImageBase || fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) {
     1158  if(realBaseAddress == originalBaseAddress || Characteristics & IMAGE_FILE_RELOCS_STRIPPED) {
    11311159        return(TRUE);
    11321160  }
     
    12261254 ULONG count;
    12271255
    1228   if(fh.Characteristics & IMAGE_FILE_RELOCS_STRIPPED) {
     1256  if(Characteristics & IMAGE_FILE_RELOCS_STRIPPED) {
    12291257        return(TRUE);
    12301258  }
     
    12801308    fixup   = (ULONG *)(fixupaddr + realBaseAddress);
    12811309    orgaddr = *fixup;
    1282 //  dprintf((LOG, "AddOff32Fixup 0x%x org 0x%x -> new 0x%x", fixup, orgaddr, realBaseAddress + (*fixup - oh.ImageBase)));
    1283     *fixup  = realBaseAddress + (*fixup - oh.ImageBase);
     1310//  dprintf((LOG, "AddOff32Fixup 0x%x org 0x%x -> new 0x%x", fixup, orgaddr, realBaseAddress + (*fixup - originalBaseAddress)));
     1311    *fixup  = realBaseAddress + (*fixup - originalBaseAddress);
    12841312}
    12851313//******************************************************************************
     
    12931321    orgaddr = *fixup;
    12941322    if(fHighFixup) {
    1295         *fixup  += (USHORT)((realBaseAddress - oh.ImageBase) >> 16);
     1323        *fixup  += (USHORT)((realBaseAddress - originalBaseAddress) >> 16);
    12961324//        dprintf((LOG, "AddOff16FixupH 0x%x org 0x%x -> new 0x%x", fixup, orgaddr, *fixup));
    12971325    }
    12981326    else {
    1299         *fixup  += (USHORT)((realBaseAddress - oh.ImageBase) & 0xFFFF);
     1327        *fixup  += (USHORT)((realBaseAddress - originalBaseAddress) & 0xFFFF);
    13001328//        dprintf((LOG, "AddOff16FixupL 0x%x org 0x%x -> new 0x%x", fixup, orgaddr, *fixup));
    13011329    }
     
    13391367        char *code = (char *)_cmalloc(sizeof(missingapicode));
    13401368
     1369#ifdef DEBUG
     1370        MissingApiOrd(WinImage->getModuleName(), getModuleName(), ordinal);
     1371#endif
    13411372        memcpy(code, missingapicode, sizeof(missingapicode));
    13421373        *(DWORD *)&code[MISSINGOFFSET_PUSHIMPORTIMAGE] = (DWORD)getModuleName();
     
    13671398        char *code = (char *)_cmalloc(sizeof(missingapicode));
    13681399
     1400#ifdef DEBUG
     1401        MissingApiName(WinImage->getModuleName(), getModuleName(), impname);
     1402#endif
     1403
    13691404        memcpy(code, missingapicode, sizeof(missingapicode));
    13701405        *(DWORD *)&code[MISSINGOFFSET_PUSHIMPORTIMAGE] = (DWORD)getModuleName();
     
    14001435  if((ped = (PIMAGE_EXPORT_DIRECTORY)ImageDirectoryOffset
    14011436     (peview, IMAGE_DIRECTORY_ENTRY_EXPORT)) != NULL &&
    1402      GetSectionHdrByImageDir(peview, IMAGE_DIRECTORY_ENTRY_EXPORT, &sh) ) 
     1437     GetSectionHdrByImageDir(peview, IMAGE_DIRECTORY_ENTRY_EXPORT, &sh) )
    14031438  {
    14041439
     
    14101445    ptrAddress = (ULONG *)((ULONG)ped->AddressOfFunctions +
    14111446                            (ULONG)peview);
    1412     nrOrdExports  = ped->NumberOfFunctions;
    1413     nrNameExports = ped->NumberOfNames;
     1447    int nrOrdExports  = ped->NumberOfFunctions;
     1448    int nrNameExports = ped->NumberOfNames;
    14141449
    14151450    int   ord, RVAExport;
     
    14231458
    14241459        /* forwarder? ulRVA within export directory. */
    1425         if(RVAExport > oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress &&
    1426            RVAExport < oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress
    1427                        + oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size)
     1460        if(RVAExport > poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress &&
     1461           RVAExport < poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress
     1462                       + poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size)
    14281463        {
    1429             fForwarder = AddForwarder(oh.ImageBase + RVAExport, name, ord);
     1464            fForwarder = loadForwarder(originalBaseAddress + RVAExport, name, ord);
    14301465        }
    14311466        if(!fForwarder) {
    1432             //points to code (virtual address relative to oh.ImageBase
    1433             AddNameExport(oh.ImageBase + RVAExport, name, ord);
     1467            //points to code (virtual address relative to originalBaseAddress
    14341468            dprintf((LOG, "address 0x%x %s @%d (0x%08x)", RVAExport, name, ord, realBaseAddress + RVAExport));
    14351469        }
     
    14411475        RVAExport = ptrAddress[i];
    14421476        /* forwarder? ulRVA within export directory. */
    1443         if(RVAExport > oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress &&
    1444            RVAExport < oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress
    1445                        + oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size)
     1477        if(RVAExport > poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress &&
     1478           RVAExport < poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress
     1479                       + poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size)
    14461480        {
    1447             fForwarder = AddForwarder(oh.ImageBase + RVAExport, NULL, ord);
     1481            fForwarder = loadForwarder(originalBaseAddress + RVAExport, NULL, ord);
    14481482        }
    14491483        if(!fForwarder && RVAExport) {
    1450             //points to code (virtual address relative to oh.ImageBase
     1484            //points to code (virtual address relative to originalBaseAddress
    14511485            dprintf((LOG, "ord %d at 0x%08x (0x%08x)", ord, RVAExport, realBaseAddress + RVAExport));
    1452             AddOrdExport(oh.ImageBase + RVAExport, ord);
    14531486        }
    14541487    }
     
    14651498//******************************************************************************
    14661499//******************************************************************************
    1467 void Win32PeLdrImage::AddNameExport(ULONG virtaddr, char *apiname, ULONG ordinal, BOOL fAbsoluteAddress)
    1468 {
    1469     ULONG nsize;
    1470     int iApiNameLength = strlen(apiname);
    1471 
    1472     if(nameexports == NULL) {
    1473         // think of a maximum of bytes per export name,
    1474         // verify if this is true for MFC-DLLs, etc.
    1475         nameExportSize = nrNameExports * (sizeof(NameExport) + 32);
    1476 
    1477         nameexports   = (NameExport *)malloc(nameExportSize);
    1478         curnameexport = nameexports;
    1479     }
    1480     nsize = (ULONG)curnameexport - (ULONG)nameexports;
    1481     if(nsize + sizeof(NameExport) + iApiNameLength > nameExportSize) {
    1482         nameExportSize += 4096;
    1483         char *tmp = (char *)nameexports;
    1484         nameexports = (NameExport *)malloc(nameExportSize);
    1485         memcpy(nameexports, tmp, nsize);
    1486         curnameexport = (NameExport *)((ULONG)nameexports + nsize);
    1487         free(tmp);
    1488     }
    1489     if(fAbsoluteAddress) {//forwarders use absolute address
    1490         curnameexport->virtaddr = virtaddr;
    1491     }
    1492     else curnameexport->virtaddr = realBaseAddress + (virtaddr - oh.ImageBase);
    1493     curnameexport->ordinal  = ordinal;
    1494     *(ULONG *)curnameexport->name = 0;
    1495 
    1496     curnameexport->nlength = iApiNameLength + 1;
    1497     memcpy(curnameexport->name, apiname,  curnameexport->nlength);
    1498 
    1499     if(curnameexport->nlength < sizeof(curnameexport->name))
    1500         curnameexport->nlength = sizeof(curnameexport->name);
    1501 
    1502     curnameexport = (NameExport *)((ULONG)curnameexport->name + curnameexport->nlength);
    1503 }
    1504 //******************************************************************************
    1505 //******************************************************************************
    1506 void Win32PeLdrImage::AddOrdExport(ULONG virtaddr, ULONG ordinal, BOOL fAbsoluteAddress)
    1507 {
    1508     if(ordexports == NULL) {
    1509         ordexports   = (OrdExport *)malloc(nrOrdExports * sizeof(OrdExport));
    1510         curordexport = ordexports;
    1511     }
    1512     if(fAbsoluteAddress) {//forwarders use absolute address
    1513         curordexport->virtaddr = virtaddr;
    1514     }
    1515     else curordexport->virtaddr = realBaseAddress + (virtaddr - oh.ImageBase);
    1516 
    1517     curordexport->ordinal  = ordinal;
    1518     curordexport++;
    1519     nrOrdExportsRegistered++;
    1520 }
    1521 //******************************************************************************
    1522 //******************************************************************************
    1523 BOOL Win32PeLdrImage::AddForwarder(ULONG virtaddr, char *apiname, ULONG ordinal)
    1524 {
    1525     char         *forward = (char *)(realBaseAddress + (virtaddr - oh.ImageBase));
     1500BOOL Win32PeLdrImage::loadForwarder(ULONG virtaddr, char *apiname, ULONG ordinal)
     1501{
     1502    char         *forward = (char *)(realBaseAddress + (virtaddr - originalBaseAddress));
    15261503    char         *forwarddll, *forwardapi;
    15271504    Win32DllBase *WinDll;
     
    15691546
    15701547    if(apiname) {
    1571         dprintf((LOG, "address 0x%x %s @%d (0x%08x) forwarder %s.%s", virtaddr - oh.ImageBase, apiname, ordinal, virtaddr, forwarddll, forwardapi));
    1572         AddNameExport(exportaddr, apiname, ordinal, TRUE);
     1548        dprintf((LOG, "address 0x%x %s @%d (0x%08x->0x%08x) forwarder %s.%s", virtaddr - originalBaseAddress, apiname, ordinal, virtaddr, exportaddr, forwarddll, forwardapi));
    15731549    }
    15741550    else {
    1575         dprintf((LOG, "address 0x%x @%d (0x%08x) forwarder %s.%s", virtaddr - oh.ImageBase, ordinal, virtaddr, forwarddll, forwardapi));
    1576         AddOrdExport(exportaddr, ordinal, TRUE);
    1577     }
    1578     return TRUE;
     1551        dprintf((LOG, "address 0x%x @%d (0x%08x->0x%08x) forwarder %s.%s", virtaddr - originalBaseAddress, ordinal, virtaddr, exportaddr, forwarddll, forwardapi));
     1552    }
     1553    return (exportaddr != 0);
    15791554}
    15801555//******************************************************************************
     
    16061581        ULONG  hInstanceNewDll;
    16071582
    1608         char *dot = strchr(modname, '.');
    1609         if(dot == NULL) {
    1610             strcat(modname, DLL_EXTENSION);
    1611         }
    16121583        rc = DosLoadModule(szModuleFailure, sizeof(szModuleFailure), modname, (HMODULE *)&hInstanceNewDll);
    16131584        if(rc) {
     
    16881659    IMAGE_SECTION_HEADER     shID;
    16891660    IMAGE_SECTION_HEADER     shExtra = {0};
    1690     PIMAGE_OPTIONAL_HEADER   pOH;
    16911661    int    i,j, nrPages;
    16921662    BOOL   fBorland = 0;
     
    17781748    /* 2) functions */
    17791749    pszCurModule = pszModules;
    1780     pOH = (PIMAGE_OPTIONAL_HEADER)OPTHEADEROFF(peview);
    17811750    for (i = 0; i < cModules; i++)
    17821751    {
     
    17921761               (ULONG)pID[i].u.OriginalFirstThunk < shID.VirtualAddress ||
    17931762               (ULONG)pID[i].u.OriginalFirstThunk >= shID.VirtualAddress + max(shID.Misc.VirtualSize, shID.SizeOfRawData) ||
    1794                (ULONG)pID[i].u.OriginalFirstThunk >= pOH->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress &&
    1795                (ULONG)pID[i].u.OriginalFirstThunk < sizeof(*pID)*cModules + pOH->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)
     1763               (ULONG)pID[i].u.OriginalFirstThunk >= poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress &&
     1764               (ULONG)pID[i].u.OriginalFirstThunk < sizeof(*pID)*cModules + poh->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)
    17961765            {
    17971766                fBorland = TRUE;
     
    18051774
    18061775        //  b) check if RVA ok
    1807         if (!(pulImport > 0 && (ULONG)pulImport < pOH->SizeOfImage)) {
     1776        if (!(pulImport > 0 && (ULONG)pulImport < poh->SizeOfImage)) {
    18081777            dprintf((LOG, "Invalid RVA %x", pulImport ));
    18091778            break;
     
    18311800            }
    18321801            else {
     1802
    18331803                WinDll = loadDll(pszCurModule);
    18341804                if(WinDll == NULL) {
     
    19011871        }
    19021872        //SvL: And restore original protection flags
    1903         ulCurFixup = (ULONG)pID[i].FirstThunk + pOH->ImageBase;
     1873        ulCurFixup = (ULONG)pID[i].FirstThunk + poh->ImageBase;
    19041874        DosSetMem((PVOID)(ulCurFixup & ~0xfff), PAGE_SIZE*nrPages, section->pageflags);
    19051875
     
    19401910}
    19411911//******************************************************************************
    1942 //******************************************************************************
    1943 NameExport *Win32PeLdrImage::findApi(char *name)
    1944 {
    1945   ULONG       apiaddr, i, apilen;
    1946   char       *apiname;
    1947   char        tmp[4];
    1948   NameExport *curexport;
    1949   ULONG       ulAPIOrdinal;                      /* api requested by ordinal */
    1950 
    1951     apilen = strlen(name) + 1;
    1952     if(apilen < 4)
    1953     {
    1954         *(ULONG *)tmp = 0;
    1955         strcpy(tmp, name);
    1956         apiname = tmp;
    1957         apilen  = 4;
    1958     }
    1959     else  apiname = name;
    1960 
    1961     curexport = nameexports;
    1962     for(i=0; i<nrNameExports; i++)
    1963     {
    1964         if(apilen == curexport->nlength &&
    1965            *(ULONG *)curexport->name == *(ULONG *)apiname)
    1966         {
    1967             if(strcmp(curexport->name, apiname) == 0)
    1968                 return curexport;
    1969         }
    1970         curexport = (NameExport *)((ULONG)curexport->name + curexport->nlength);
    1971     }
    1972     return NULL;
    1973 }
    1974 //******************************************************************************
    1975 //******************************************************************************
    1976 ULONG Win32PeLdrImage::getApi(char *name)
    1977 {
    1978     NameExport *curexport;
    1979 
    1980     curexport = findApi(name);
    1981     if(curexport) {
    1982         return(curexport->virtaddr);
    1983     }
    1984     return 0;
    1985 }
    1986 //******************************************************************************
    1987 //Override a name export
    1988 //******************************************************************************
    1989 ULONG Win32PeLdrImage::setApi(char *name, ULONG pfnNewProc)
    1990 {
    1991     NameExport *curexport;
    1992 
    1993     curexport = findApi(name);
    1994     if(curexport) {
    1995         ULONG pfnOldProc = curexport->virtaddr;
    1996 
    1997         curexport->virtaddr = pfnNewProc;
    1998         return pfnOldProc;
    1999     }
    2000     return -1;
    2001 }
    2002 //******************************************************************************
    2003 //******************************************************************************
    2004 OrdExport *Win32PeLdrImage::findApi(int ordinal)
    2005 {
    2006  ULONG       apiaddr, i;
    2007  OrdExport  *curexport;
    2008 
    2009     curexport = ordexports;
    2010 
    2011   /* accelerated resolving of ordinal exports
    2012    * is based on the assumption the ordinal export
    2013    * table is always sorted ascending.
    2014    *
    2015    * When the step size is too small, we continue
    2016    * with the linear search.
    2017    */
    2018 
    2019   // start in the middle of the tree
    2020   i = nrOrdExportsRegistered >> 1;
    2021   int iStep = i;
    2022 
    2023   for(;;)
    2024   {
    2025     int iThisExport = curexport[i].ordinal;
    2026 
    2027     iStep >>= 1;                    // next step will be narrower
    2028 
    2029     if (iThisExport < ordinal)
    2030       i += min(iStep, (ordinal-iThisExport)); // move farther down the list
    2031     else
    2032       if (iThisExport == ordinal)   // found the export?
    2033         return &curexport[i];
    2034       else
    2035         i -= min(iStep, (iThisExport-ordinal));                 // move farther up the list
    2036 
    2037     // if we're in the direct neighbourhood search linearly
    2038     if (iStep <= 1)
    2039     {
    2040       // decide if we're to search backward or forward
    2041       if (ordinal > curexport[i].ordinal)
    2042       {
    2043         // As a certain number of exports are 0 at the end
    2044         // of the array, this case will hit fairly often.
    2045         // the last comparison will send the loop off into the
    2046         // wrong direction!
    2047 #ifdef DEBUG
    2048         if (curexport[i].ordinal == 0)
    2049         {
    2050             DebugInt3();
    2051         }
    2052 #endif
    2053 
    2054         for (;i<nrOrdExports;i++) // scan forward
    2055         {
    2056           iThisExport = curexport[i].ordinal;
    2057           if(iThisExport == ordinal)
    2058             return &curexport[i];
    2059           else
    2060             if (iThisExport > ordinal)
    2061             {
    2062               // Oops, cannot find the ordinal in the sorted list
    2063               break;
    2064             }
    2065         }
    2066       }
    2067       else
    2068       {
    2069         for (;i>=0;i--) // scan backward
    2070         {
    2071           iThisExport = curexport[i].ordinal;
    2072           if(curexport[i].ordinal == ordinal)
    2073             return &curexport[i];
    2074           else
    2075             if (iThisExport < ordinal)
    2076               // Oops, cannot find the ordinal in the sorted list
    2077               break;
    2078         }
    2079       }
    2080 
    2081       // not found yet.
    2082       break;
    2083     }
    2084   }
    2085   return NULL;
    2086 }
    2087 //******************************************************************************
    2088 //******************************************************************************
    2089 ULONG Win32PeLdrImage::getApi(int ordinal)
    2090 {
    2091     OrdExport  *curexport;
    2092     NameExport *nexport;
    2093 
    2094     curexport = findApi(ordinal);
    2095     if(curexport) {
    2096         return curexport->virtaddr;
    2097     }
    2098 
    2099     //Name exports also contain an ordinal, so check this
    2100     nexport = nameexports;
    2101     for(int i=0;i<nrNameExports;i++) {
    2102         if(nexport->ordinal == ordinal)
    2103             return(nexport->virtaddr);
    2104 
    2105         nexport = (NameExport *)((ULONG)nexport->name + nexport->nlength);
    2106     }
    2107     return(0);
    2108 }
    2109 //******************************************************************************
    2110 //Override an ordinal export
    2111 //******************************************************************************
    2112 ULONG Win32PeLdrImage::setApi(int ordinal, ULONG pfnNewProc)
    2113 {
    2114     OrdExport  *curexport;
    2115     NameExport *nexport;
    2116 
    2117     curexport = findApi(ordinal);
    2118     if(curexport) {
    2119         ULONG pfnOldProc = curexport->virtaddr;
    2120 
    2121         curexport->virtaddr = pfnNewProc;
    2122         return pfnOldProc;
    2123     }
    2124 
    2125     //Name exports also contain an ordinal, so check this
    2126     nexport = nameexports;
    2127     for(int i=0;i<nrNameExports;i++)
    2128     {
    2129         if(nexport->ordinal == ordinal) {
    2130             ULONG pfnOldProc = nexport->virtaddr;
    2131 
    2132             nexport->virtaddr = pfnNewProc;
    2133             return pfnOldProc;
    2134         }
    2135 
    2136         nexport = (NameExport *)((ULONG)nexport->name + nexport->nlength);
    2137     }
    2138     return -1;
    2139 }
    2140 //******************************************************************************
    21411912//Returns required OS version for this image
    21421913//******************************************************************************
    21431914ULONG Win32PeLdrImage::getVersion()
    21441915{
    2145     return (oh.MajorOperatingSystemVersion << 16) | oh.MinorOperatingSystemVersion;
     1916    return (poh->MajorOperatingSystemVersion << 16) | poh->MinorOperatingSystemVersion;
    21461917}
    21471918//******************************************************************************
Note: See TracChangeset for help on using the changeset viewer.