Changeset 4422


Ignore:
Timestamp:
Oct 4, 2000, 9:36:26 PM (25 years ago)
Author:
sandervl
Message:

added forwarder support for PE loader

Location:
trunk/src/kernel32
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • TabularUnified trunk/src/kernel32/KERNEL32.CPP

    r4372 r4422  
    1 /* $Id: KERNEL32.CPP,v 1.55 2000-10-02 13:38:55 sandervl Exp $ */
     1/* $Id: KERNEL32.CPP,v 1.56 2000-10-04 19:36:24 sandervl Exp $ */
    22
    33/*
     
    121121
    122122  rc = O32_IsBadReadPtr(lpvPtr, cbBytes);
    123   dprintf(("KERNEL32:  IsBadWritePtr: 0x%X size %d rc = %d\n", (int)lpvPtr, cbBytes, rc));
     123  dprintf(("KERNEL32:  IsBadReadPtr: 0x%X size %d rc = %d\n", (int)lpvPtr, cbBytes, rc));
    124124  return(rc);
    125125#else
  • TabularUnified trunk/src/kernel32/winimagepeldr.cpp

    r4407 r4422  
    1 /* $Id: winimagepeldr.cpp,v 1.54 2000-10-03 17:28:31 sandervl Exp $ */
     1/* $Id: winimagepeldr.cpp,v 1.55 2000-10-04 19:36:25 sandervl Exp $ */
    22
    33/*
     
    1111 * TODO: Check psh[i].Characteristics for more than only the code section
    1212 * TODO: Make resource section readonly when GDI32 is fixed
     13 * TODO: Loading of forwarder dlls before handling imports might not be correct
     14 *       (circular dependencies; have to check what NT does)
    1315 *
    1416 * NOTE: RSRC_LOAD is a special flag to only load the resource directory
     
    106108    imageVirtBase(-1), realBaseAddress(0), imageVirtEnd(0),
    107109    nrNameExports(0), nrOrdExports(0), nameexports(NULL), ordexports(NULL),
    108     memmap(NULL), pFixups(NULL), dwFixupSize(0)
     110    memmap(NULL), pFixups(NULL), dwFixupSize(0), curnameexport(NULL), curordexport(NULL)
    109111{
    110112 HFILE  dllfile;
     
    11251127 ULONG *ptrNames, *ptrAddress;
    11261128 USHORT *ptrOrd;
     1129 BOOL fForwarder;
    11271130 int i;
    11281131
     
    11441147    int   ord, RVAExport;
    11451148    char *name;
    1146     for(i=0;i<ped->NumberOfNames;i++) {
    1147         ord       = ptrOrd[i] + ped->Base;
    1148         name      = (char *)((ULONG)ptrNames[i] + (ULONG)win32file);
    1149         RVAExport = ptrAddress[ptrOrd[i]];
    1150 #ifdef FORWARDERS
    1151         if(RVAExport < sh.VirtualAddress || RVAExport > sh.VirtualAddress + sh.SizeOfRawData) {
    1152 #endif
     1149    for(i=0;i<ped->NumberOfNames;i++)
     1150    {
     1151        fForwarder = FALSE;
     1152        ord        = ptrOrd[i] + ped->Base;
     1153        name       = (char *)((ULONG)ptrNames[i] + (ULONG)win32file);
     1154        RVAExport  = ptrAddress[ptrOrd[i]];
     1155
     1156        /* forwarder? ulRVA within export directory. */
     1157        if(RVAExport > oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress &&
     1158           RVAExport < oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress
     1159                       + oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size)
     1160        {
     1161            fForwarder = AddForwarder(oh.ImageBase + RVAExport, name, ord);
     1162        }
     1163        if(!fForwarder) {
    11531164            //points to code (virtual address relative to oh.ImageBase
    11541165            AddNameExport(oh.ImageBase + RVAExport, name, ord);
    1155             dprintf((LOG, "address 0x%x %s @%d", RVAExport, name, ord));
    1156 #ifdef FORWARDERS
    1157 
    1158         }
    1159         else {//forwarder
    1160             char *forward = (char *)((ULONG)RVAExport + (ULONG)win32file);
    1161             fout << RVAExport << " ", name << " @", ord << " is forwarder to ", (int)forward ));
    1162         }
    1163 #endif
     1166            dprintf((LOG, "address 0x%x %s @%d (0x%08x)", RVAExport, name, ord, realBaseAddress + RVAExport));
     1167        }
    11641168    }
    1165     for(i=0;i<max(ped->NumberOfNames,ped->NumberOfFunctions);i++) {
     1169    for(i=0;i<max(ped->NumberOfNames,ped->NumberOfFunctions);i++)
     1170    {
     1171        fForwarder = FALSE;
    11661172        ord = ped->Base + i;  //Correct??
    11671173        RVAExport = ptrAddress[i];
    1168 #ifdef FORWARDERS
    1169         if(RVAExport < sh.VirtualAddress || RVAExport > sh.VirtualAddress + sh.SizeOfRawData) {
    1170 #endif
    1171             if(RVAExport) {
    1172               //points to code (virtual address relative to oh.ImageBase
    1173               dprintf((LOG, "ord %d at 0x%x", ord, RVAExport));
    1174               AddOrdExport(oh.ImageBase + RVAExport, ord);
    1175             }
    1176 #ifdef FORWARDERS
    1177         }
    1178         else {//forwarder or empty
    1179             char *forward = (char *)((ULONG)RVAExport + (ULONG)win32file);
    1180             dprintf((LOG, "ord ", ord << " at 0x";
    1181             fout << RVAExport << " is forwarder to 0x", (int)forward ));
    1182         }
    1183 #endif
     1174        /* forwarder? ulRVA within export directory. */
     1175        if(RVAExport > oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress &&
     1176           RVAExport < oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress
     1177                       + oh.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].Size)
     1178        {
     1179            fForwarder = AddForwarder(oh.ImageBase + RVAExport, NULL, ord);
     1180        }
     1181        if(!fForwarder && RVAExport) {
     1182            //points to code (virtual address relative to oh.ImageBase
     1183            dprintf((LOG, "ord %d at 0x%08x (0x%08x)", ord, RVAExport, realBaseAddress + RVAExport));
     1184            AddOrdExport(oh.ImageBase + RVAExport, ord);
     1185        }
    11841186    }
    11851187  }
     
    11881190//******************************************************************************
    11891191//******************************************************************************
    1190 void Win32PeLdrImage::AddNameExport(ULONG virtaddr, char *apiname, ULONG ordinal)
     1192void Win32PeLdrImage::AddNameExport(ULONG virtaddr, char *apiname, ULONG ordinal, BOOL fAbsoluteAddress)
    11911193{
    11921194 ULONG nsize;
     
    12061208        free(tmp);
    12071209  }
    1208   curnameexport->virtaddr = realBaseAddress + (virtaddr - oh.ImageBase);
     1210  if(fAbsoluteAddress) {//forwarders use absolute address
     1211        curnameexport->virtaddr = virtaddr;
     1212  }
     1213  else  curnameexport->virtaddr = realBaseAddress + (virtaddr - oh.ImageBase);
    12091214  curnameexport->ordinal  = ordinal;
    12101215  *(ULONG *)curnameexport->name = 0;
     
    12191224//******************************************************************************
    12201225//******************************************************************************
    1221 void Win32PeLdrImage::AddOrdExport(ULONG virtaddr, ULONG ordinal)
     1226void Win32PeLdrImage::AddOrdExport(ULONG virtaddr, ULONG ordinal, BOOL fAbsoluteAddress)
    12221227{
    12231228  if(ordexports == NULL) {
     
    12251230        curordexport = ordexports;
    12261231  }
    1227   curordexport->virtaddr = realBaseAddress + (virtaddr - oh.ImageBase);
     1232  if(fAbsoluteAddress) {//forwarders use absolute address
     1233        curordexport->virtaddr = virtaddr;
     1234  }
     1235  else  curordexport->virtaddr = realBaseAddress + (virtaddr - oh.ImageBase);
    12281236  curordexport->ordinal  = ordinal;
    12291237  curordexport++;
     1238}
     1239//******************************************************************************
     1240//******************************************************************************
     1241BOOL Win32PeLdrImage::AddForwarder(ULONG virtaddr, char *apiname, ULONG ordinal)
     1242{
     1243 char         *forward = (char *)(realBaseAddress + (virtaddr - oh.ImageBase));
     1244 char         *forwarddll, *forwardapi;
     1245 Win32DllBase *WinDll;
     1246 DWORD         exportaddr;
     1247 int           forwardord;
     1248 
     1249  forwarddll = strdup(forward);
     1250  if(forwarddll == NULL) {
     1251        return FALSE;
     1252  }
     1253  forwardapi = strchr(forwarddll, '.');
     1254  if(forwardapi == NULL) {
     1255        goto fail;
     1256  }
     1257  *forwardapi++ = 0;
     1258  if(strlen(forwarddll) == 0 || strlen(forwardapi) == 0) {
     1259        goto fail;
     1260  }
     1261  WinDll = Win32DllBase::findModule(forwarddll);
     1262  if(WinDll == NULL) {
     1263        WinDll = loadDll(forwarddll);
     1264        if(WinDll == NULL) {
     1265                dprintf((LOG, "ERROR: couldn't find forwarder %s.%s", forwarddll, forwardapi));
     1266                goto fail;
     1267        }
     1268  }
     1269  //check if name or ordinal forwarder
     1270  forwardord = 0;
     1271  if(*forwardapi >= '0' && *forwardapi <= '9') {
     1272        forwardord = atoi(forwardapi);
     1273  }
     1274  if(forwardord != 0 || (strlen(forwardapi) == 1 && *forwardapi == '0')) {
     1275        exportaddr = WinDll->getApi(forwardord);
     1276  }
     1277  else  exportaddr = WinDll->getApi(forwardapi);
     1278
     1279  if(apiname) {
     1280        dprintf((LOG, "address 0x%x %s @%d (0x%08x) forwarder %s.%s", virtaddr - oh.ImageBase, apiname, ordinal, virtaddr, forwarddll, forwardapi));
     1281        AddNameExport(exportaddr, apiname, ordinal, TRUE);
     1282  }
     1283  else {
     1284        dprintf((LOG, "address 0x%x @%d (0x%08x) forwarder %s.%s", virtaddr - oh.ImageBase, ordinal, virtaddr, forwarddll, forwardapi));
     1285        AddOrdExport(exportaddr, ordinal, TRUE);
     1286  }
     1287  free(forwarddll);
     1288  return TRUE;
     1289
     1290fail:
     1291  free(forwarddll);
     1292  return FALSE;
     1293}
     1294//******************************************************************************
     1295//******************************************************************************
     1296Win32DllBase *Win32PeLdrImage::loadDll(char *pszCurModule)
     1297{
     1298 Win32DllBase *WinDll = NULL;
     1299 char modname[CCHMAXPATH];
     1300
     1301        strcpy(modname, pszCurModule);
     1302        //rename dll if necessary (i.e. OLE32 -> OLE32OS2)
     1303        Win32DllBase::renameDll(modname);
     1304
     1305        if(isPEImage(modname) != ERROR_SUCCESS_W)
     1306        {//LX image, so let OS/2 do all the work for us
     1307                APIRET rc;
     1308                char   szModuleFailure[CCHMAXPATH] = "";
     1309                ULONG  hInstanceNewDll;
     1310                Win32LxDll *lxdll;
     1311
     1312                char *dot = strchr(modname, '.');
     1313                if(dot) {
     1314                        *dot = 0;
     1315                }
     1316                strcat(modname, ".DLL");
     1317                rc = DosLoadModule(szModuleFailure, sizeof(szModuleFailure), modname, (HMODULE *)&hInstanceNewDll);
     1318                if(rc) {
     1319                        dprintf((LOG, "DosLoadModule returned %X for %s\n", rc, szModuleFailure));
     1320                        sprintf(szErrorModule, "%s.DLL", szModuleFailure);
     1321                        errorState = rc;
     1322                        return NULL;
     1323                }
     1324                lxdll = Win32LxDll::findModuleByOS2Handle(hInstanceNewDll);
     1325                if(lxdll == NULL) {//shouldn't happen!
     1326                        dprintf((LOG, "Just loaded the dll, but can't find it anywhere?!!?"));
     1327                        errorState = ERROR_INTERNAL;
     1328                        return NULL;
     1329                }
     1330                lxdll->setDllHandleOS2(hInstanceNewDll);
     1331                if(lxdll->AddRef() == -1) {//-1 -> load failed (attachProcess)
     1332                        dprintf((LOG, "Dll %s refused to be loaded; aborting", modname));
     1333                        delete lxdll;
     1334                        errorState = ERROR_INTERNAL;
     1335                        return NULL;
     1336                }
     1337                WinDll = (Win32DllBase*)lxdll;
     1338        }
     1339        else {
     1340         Win32PeLdrDll *pedll;
     1341
     1342                pedll = new Win32PeLdrDll(modname, this);
     1343                if(pedll == NULL) {
     1344                    dprintf((LOG, "pedll: Error allocating memory" ));
     1345                    WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szMemErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE);
     1346                    errorState = ERROR_INTERNAL;
     1347                    return NULL;
     1348                }
     1349                dprintf((LOG, "**********************************************************************" ));
     1350                dprintf((LOG, "**********************     Loading Module        *********************" ));
     1351                dprintf((LOG, "**********************************************************************" ));
     1352                if(pedll->init(0) == FALSE) {
     1353                    dprintf((LOG, "Internal WinDll error ", pedll->getError() ));
     1354                    delete pedll;
     1355                    return NULL;
     1356                }
     1357#ifdef DEBUG
     1358                pedll->AddRef(getModuleName());
     1359#else
     1360                pedll->AddRef();
     1361#endif
     1362                if(pedll->attachProcess() == FALSE) {
     1363                    dprintf((LOG, "attachProcess failed!" ));
     1364                    delete pedll;
     1365                    errorState = ERROR_INTERNAL;
     1366                    return NULL;
     1367                }
     1368                WinDll = (Win32DllBase*)pedll;
     1369        }
     1370
     1371        dprintf((LOG, "**********************************************************************" ));
     1372        dprintf((LOG, "**********************  Finished Loading Module %s ", modname ));
     1373        dprintf((LOG, "**********************************************************************" ));
     1374
     1375        return WinDll;
    12301376}
    12311377//******************************************************************************
     
    13311477  {
    13321478    dprintf((LOG, "Module %s", pszCurModule ));
     1479    dprintf((LOG, "ForwarderChain: %x", pID[i].ForwarderChain));
    13331480    //  a) check that OriginalFirstThunk not is 0 and look for Borland-styled PE
    13341481    if (i == 0)
     
    13731520    if(WinDll == NULL)
    13741521    {  //not found, so load it
    1375         char modname[CCHMAXPATH];
    1376 
    1377         strcpy(modname, pszCurModule);
    1378         //rename dll if necessary (i.e. OLE32 -> OLE32OS2)
    1379         Win32DllBase::renameDll(modname);
    1380 
    1381         if(isPEImage(modname) != ERROR_SUCCESS_W)
    1382         {//LX image, so let OS/2 do all the work for us
    1383                 APIRET rc;
    1384                 char   szModuleFailure[CCHMAXPATH] = "";
    1385                 ULONG  hInstanceNewDll;
    1386                 Win32LxDll *lxdll;
    1387 
    1388                 char *dot = strchr(modname, '.');
    1389                 if(dot) {
    1390                         *dot = 0;
    1391                 }
    1392                 strcat(modname, ".DLL");
    1393                 rc = DosLoadModule(szModuleFailure, sizeof(szModuleFailure), modname, (HMODULE *)&hInstanceNewDll);
    1394                 if(rc) {
    1395                         dprintf((LOG, "DosLoadModule returned %X for %s\n", rc, szModuleFailure));
    1396                         sprintf(szErrorModule, "%s.DLL", szModuleFailure);
    1397                         errorState = rc;
    1398                         return(FALSE);
    1399                 }
    1400                 lxdll = Win32LxDll::findModuleByOS2Handle(hInstanceNewDll);
    1401                 if(lxdll == NULL) {//shouldn't happen!
    1402                         dprintf((LOG, "Just loaded the dll, but can't find it anywhere?!!?"));
    1403                         errorState = ERROR_INTERNAL;
    1404                         return(FALSE);
    1405                 }
    1406                 lxdll->setDllHandleOS2(hInstanceNewDll);
    1407                 if(lxdll->AddRef() == -1) {//-1 -> load failed (attachProcess)
    1408                         dprintf((LOG, "Dll %s refused to be loaded; aborting", modname));
    1409                         delete lxdll;
    1410                         errorState = ERROR_INTERNAL;
    1411                         return(FALSE);
    1412                 }
    1413                 WinDll = (Win32DllBase*)lxdll;
    1414         }
    1415         else {
    1416          Win32PeLdrDll *pedll;
    1417 
    1418                 pedll = new Win32PeLdrDll(modname, this);
    1419                 if(pedll == NULL) {
    1420                     dprintf((LOG, "pedll: Error allocating memory" ));
    1421                     WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, szMemErrorMsg, szErrorTitle, 0, MB_OK | MB_ERROR | MB_MOVEABLE);
    1422                     errorState = ERROR_INTERNAL;
    1423                     return(FALSE);
    1424                 }
    1425                 dprintf((LOG, "**********************************************************************" ));
    1426                 dprintf((LOG, "**********************     Loading Module        *********************" ));
    1427                 dprintf((LOG, "**********************************************************************" ));
    1428                 if(pedll->init(0) == FALSE) {
    1429                     dprintf((LOG, "Internal WinDll error ", pedll->getError() ));
    1430                     delete pedll;
    1431                     return(FALSE);
    1432                 }
    1433 #ifdef DEBUG
    1434                 pedll->AddRef(getModuleName());
    1435 #else
    1436                 pedll->AddRef();
    1437 #endif
    1438                 if(pedll->attachProcess() == FALSE) {
    1439                     dprintf((LOG, "attachProcess failed!" ));
    1440                     delete pedll;
    1441                     errorState = ERROR_INTERNAL;
    1442                     return(FALSE);
    1443                 }
    1444                 WinDll = (Win32DllBase*)pedll;
    1445         }
    1446 
    1447         dprintf((LOG, "**********************************************************************" ));
    1448         dprintf((LOG, "**********************  Finished Loading Module  *********************" ));
    1449         dprintf((LOG, "**********************************************************************" ));
     1522        WinDll = loadDll(pszCurModule);
     1523        if(WinDll == NULL) {
     1524                return FALSE;
     1525        }
    14501526    }
    14511527    else {
     
    14931569            //KSO - Aug 6 1998 1:15am:this eases comparing...
    14941570            char *pszFunctionName = (char*)(pulImport[j] + (ULONG)win32file + 2);
    1495             dprintf((LOG, "0x%08x Imported function %s", ulCurFixup,  pszFunctionName ));
     1571            dprintf((LOG, "0x%08x Imported function %s (0x%08x)", ulCurFixup,  pszFunctionName, WinDll->getApi(pszFunctionName)));
    14961572            StoreImportByName(WinDll, pszFunctionName, ulCurFixup);
    14971573        }
  • TabularUnified trunk/src/kernel32/winimagepeldr.h

    r3761 r4422  
    1 /* $Id: winimagepeldr.h,v 1.4 2000-06-27 12:20:46 sandervl Exp $ */
     1/* $Id: winimagepeldr.h,v 1.5 2000-10-04 19:36:25 sandervl Exp $ */
    22
    33/*
     
    118118
    119119        BOOL  processExports(char *win32file);
    120         void  AddNameExport(ULONG virtaddr, char *apiname, ULONG ordinal);
    121         void  AddOrdExport(ULONG virtaddr, ULONG ordinal);
     120        void  AddNameExport(ULONG virtaddr, char *apiname, ULONG ordinal, BOOL fAbsoluteAddress=FALSE);
     121        void  AddOrdExport(ULONG virtaddr, ULONG ordinal, BOOL fAbsoluteAddress=FALSE);
     122        BOOL  AddForwarder(ULONG virtaddr, char *apiname, ULONG ordinal);
     123
     124Win32DllBase *loadDll(char *pszCurModule);
    122125
    123126        IMAGE_OPTIONAL_HEADER oh;
  • TabularUnified trunk/src/kernel32/wprocess.cpp

    r4417 r4422  
    1 /* $Id: wprocess.cpp,v 1.100 2000-10-03 20:17:20 sandervl Exp $ */
     1/* $Id: wprocess.cpp,v 1.101 2000-10-04 19:36:26 sandervl Exp $ */
    22
    33/*
     
    13681368
    13691369    if (cch > 0)
    1370         dprintf(("KERNEL32:  GetModuleFileNameA(%x,...): %s %d\n", hModule, lpszPath, cch));
     1370        dprintf(("KERNEL32:  GetModuleFileNameA(%x %x): %s %d\n", hModule, lpszPath, lpszPath, cch));
    13711371    else
    13721372        dprintf(("KERNEL32:  WARNING: GetModuleFileNameA(%x,...) - not found!", hModule));
Note: See TracChangeset for help on using the changeset viewer.