Changeset 2861 for trunk/kLdr/kLdrModPE.c
- Timestamp:
- Nov 10, 2006, 4:04:42 AM (19 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kLdr/kLdrModPE.c
r2860 r2861 113 113 static int kldrModPEDoForwarderQuery(PKLDRMODPE pModPE, const void *pvBits, const char *pszForwarder, 114 114 PFNKLDRMODGETIMPORT pfnGetImport, void *pvUser, PKLDRADDR puValue, uint32_t *pfKind); 115 static int kldrModPEUnprotect(PKLDRMODPE pModPE, const void *pvMapping);116 static int kldrModPEProtect(PKLDRMODPE pModPE, const void *pvMapping);117 115 static int kldrModPEDoFixups(PKLDRMODPE pModPE, void *pvMapping, KLDRADDR NewBaseAddress, KLDRADDR OldBaseAddress); 118 116 static int kldrModPEDoImports32Bit(PKLDRMODPE pModPE, void *pvMapping, const IMAGE_IMPORT_DESCRIPTOR *pImpDesc, … … 554 552 unsigned fFixed; 555 553 void *pvBase; 556 size_t cb;557 554 int rc; 558 555 uint32_t i; 559 556 560 557 /* 561 * Prepare it. 562 */ 563 /* size */ 564 cb = (size_t)pMod->pOps->pfnSize(pModPE->pMod); 565 if (cb != pMod->pOps->pfnSize(pModPE->pMod)) 566 return KLDR_ERR_ADDRESS_OVERFLOW; 567 558 * Map it. 559 */ 568 560 /* fixed image? */ 569 561 fFixed = fForReal … … 580 572 581 573 /* try do the prepare */ 582 rc = kLdrRdr Prepare(pMod->pRdr, &pvBase, cb, fFixed);574 rc = kLdrRdrMap(pMod->pRdr, &pvBase, pMod->cSegments, pMod->aSegments, fFixed); 583 575 if (rc) 584 576 return rc; 585 577 586 578 /* 587 * Map the segments (sub sections in PE terms). 588 */ 589 for (i = 0; i < pMod->cSegments; i++) 590 { 591 void *pvSeg; 592 593 if (!pMod->aSegments[i].Alignment) 594 continue; 595 596 pvSeg = (uint8_t *)pvBase + pMod->aSegments[i].RVA; 597 rc = kLdrRdrMap(pMod->pRdr, pvSeg, pMod->aSegments[i].cbMapped, pMod->aSegments[i].enmProt, 598 pMod->aSegments[i].offFile, pMod->aSegments[i].cbFile); 599 if (rc) 579 * Update the segments with their map addresses. 580 */ 581 if (fForReal) 582 { 583 for (i = 0; i < pMod->cSegments; i++) 600 584 { 601 /* bailout */ 602 while (i-- > 0) 603 { 604 if (!pMod->aSegments[i].Alignment) 605 continue; 606 607 kLdrRdrUnmap(pMod->pRdr, (void *)pMod->aSegments[i].MapAddress, pMod->aSegments[i].cbMapped); 608 pMod->aSegments[i].MapAddress = 0; 609 } 610 break; 585 if (pMod->aSegments[i].RVA != NIL_KLDRADDR) 586 pMod->aSegments[i].MapAddress = (uintptr_t)pvBase + (uintptr_t)pMod->aSegments[i].RVA; 611 587 } 612 pMod->aSegments[i].MapAddress = (uintptr_t)pvSeg; 613 } 614 615 if (!rc) 616 { 617 if (fForReal) 618 pModPE->pvMapping = pvBase; 619 else 620 pModPE->pvBits = pvBase; 588 pModPE->pvMapping = pvBase; 621 589 } 622 590 else 623 kLdrRdrUnprepare(pMod->pRdr, pvBase, cb);624 return rc;591 pModPE->pvBits = pvBase; 592 return 0; 625 593 } 626 594 … … 640 608 PKLDRMOD pMod = pModPE->pMod; 641 609 size_t cb = (size_t)pMod->pOps->pfnSize(pModPE->pMod); 642 int rc2; 643 int rc = 0; 610 int rc; 644 611 uint32_t i; 645 612 646 613 /* 647 * Unmap the segments (sub sections in PE terms). 648 */ 649 for (i = 0; i < pMod->cSegments; i++) 650 { 651 if (!pMod->aSegments[i].MapAddress) 652 continue; 653 654 rc2 = kLdrRdrUnmap(pMod->pRdr, (void *)pMod->aSegments[i].MapAddress, pMod->aSegments[i].cbMapped); 655 if (!rc2) 614 * Try unmap the image. 615 */ 616 rc = kLdrRdrUnmap(pMod->pRdr, (void *)pvMapping, pMod->cSegments, pMod->aSegments); 617 if (rc) 618 return rc; 619 620 /* 621 * Update the segments to reflect that they aren't mapped any longer. 622 */ 623 if (pModPE->pvMapping == pvMapping) 624 { 625 pModPE->pvMapping = NULL; 626 for (i = 0; i < pMod->cSegments; i++) 656 627 pMod->aSegments[i].MapAddress = 0; 657 else if (!rc) 658 rc = rc2; 659 } 660 661 /* 662 * 'Unprepare' the mapping region. 663 */ 664 if (!rc) 665 { 666 rc = kLdrRdrUnprepare(pMod->pRdr, (void *)pvMapping, cb); 667 if (!rc) 668 { 669 if (pModPE->pvBits == pvMapping) 670 pModPE->pvBits = NULL; 671 if (pModPE->pvMapping == pvMapping) 672 pModPE->pvMapping = NULL; 673 } 674 } 675 676 return rc; 628 } 629 if (pModPE->pvBits == pvMapping) 630 pModPE->pvBits = NULL; 631 632 return 0; 677 633 } 678 634 … … 717 673 else 718 674 { 719 /** @todo do an internal mapping. */ 720 rc = -1; 675 /* create an internal mapping. */ 676 rc = kldrModPEDoMap(pModPE, 0 /* not for real */); 677 if (rc) 678 return rc; 679 KLDRMODPE_ASSERT(pModPE->pvBits); 680 *ppvBits = pModPE->pvBits; 721 681 } 722 682 } … … 1336 1296 static int kldrModPEReload(PKLDRMOD pMod) 1337 1297 { 1338 PKLDRMODPE pModPE = (PKLDRMODPE)pMod->pvData; 1339 uint32_t i; 1340 int rc; 1341 const size_t cbPage = kLdrRdrPageSize(pMod->pRdr); 1298 PKLDRMODPE pModPE = (PKLDRMODPE)pMod->pvData; 1342 1299 1343 1300 /* … … 1347 1304 return KLDR_ERR_NOT_MAPPED; 1348 1305 1349 /* 1350 * Iterate the objects and ask the file provider to undo all the changes. 1351 */ 1352 for (i = rc = 0; !rc && i < pMod->cSegments; i++) 1353 rc = kLdrRdrRefreshMap(pMod->pRdr, 1354 (void *)pMod->aSegments[i].MapAddress, 1355 (size_t)pMod->aSegments[i].cb, 1356 pMod->aSegments[i].enmProt, 1357 pMod->aSegments[i].offFile, 1358 pMod->aSegments[i].cbFile); 1359 return rc; 1306 /* the file provider does it all */ 1307 return kLdrRdrRefresh(pMod->pRdr, (void *)pModPE->pvMapping, pMod->cSegments, pMod->aSegments); 1360 1308 } 1361 1309 … … 1376 1324 * Before doing anything we'll have to make all pages writable. 1377 1325 */ 1378 rc = k ldrModPEUnprotect(pModPE, pModPE->pvMapping);1326 rc = kLdrRdrProtect(pMod->pRdr, (void *)pModPE->pvMapping, pMod->cSegments, pMod->aSegments, 1 /* unprotect */); 1379 1327 if (rc) 1380 1328 return rc; … … 1395 1343 * Restore protection. 1396 1344 */ 1397 rc2 = k ldrModPEProtect(pModPE, pModPE->pvMapping);1345 rc2 = kLdrRdrProtect(pMod->pRdr, (void *)pModPE->pvMapping, pMod->cSegments, pMod->aSegments, 0 /* protect */); 1398 1346 if (!rc && rc2) 1399 1347 rc = rc2; 1400 return rc;1401 }1402 1403 1404 /**1405 * Make all segment writable so we can apply fixups and setup imports.1406 *1407 * @returns 0 on success, non-zero kLdrRdrProtect() status code on failure.1408 * @param pModPE The PE module interpreter instance.1409 * @param pvMapping The base mapping to unprotect.1410 */1411 static int kldrModPEUnprotect(PKLDRMODPE pModPE, const void *pvMapping)1412 {1413 PKLDRMOD pMod = pModPE->pMod;1414 int rc;1415 uint32_t i;1416 1417 /*1418 * Iterate the segments.1419 */1420 for (i = rc = 0; !rc && i < pMod->cSegments; i++)1421 {1422 KLDRPROT enmProt;1423 1424 /* Skip segments that aren't mapped. */1425 if (!pMod->aSegments[i].Alignment)1426 continue;1427 1428 /* calc writable protection and skip those which are already writable. */1429 enmProt = pMod->aSegments[i].enmProt;1430 switch (enmProt)1431 {1432 case KLDRPROT_NOACCESS:1433 case KLDRPROT_READWRITE:1434 case KLDRPROT_WRITECOPY:1435 case KLDRPROT_EXECUTE_READWRITE:1436 case KLDRPROT_EXECUTE_WRITECOPY:1437 continue;1438 case KLDRPROT_READONLY:1439 enmProt = KLDRPROT_WRITECOPY;1440 break;1441 case KLDRPROT_EXECUTE:1442 case KLDRPROT_EXECUTE_READ:1443 enmProt = KLDRPROT_EXECUTE_WRITECOPY;1444 break;1445 default:1446 KLDRMODPE_ASSERT(!"invalid");1447 continue;1448 }1449 1450 rc = kLdrRdrProtect(pMod->pRdr,1451 (uint8_t *)pvMapping + (pMod->aSegments[i].LinkAddress - pModPE->Hdrs.OptionalHeader.ImageBase),1452 pMod->aSegments[i].cbMapped,1453 enmProt);1454 }1455 1456 return rc;1457 }1458 1459 1460 /**1461 * Restore the correct protection for the segments after we're done with fixups and imports.1462 *1463 * @returns 0 on success, non-zero kLdrRdrProtect() status code on failure.1464 * @param pModPE The PE module interpreter instance.1465 * @param pvMapping The base mapping to unprotect.1466 */1467 static int kldrModPEProtect(PKLDRMODPE pModPE, const void *pvMapping)1468 {1469 PKLDRMOD pMod = pModPE->pMod;1470 int rc;1471 uint32_t i;1472 1473 /*1474 * Iterate the segments.1475 */1476 for (i = rc = 0; !rc && i < pMod->cSegments; i++)1477 {1478 KLDRPROT enmProt;1479 1480 /* Skip segments that aren't mapped. */1481 if (!pMod->aSegments[i].Alignment)1482 continue;1483 1484 /* Skip those which are already writable. */1485 enmProt = pMod->aSegments[i].enmProt;1486 switch (enmProt)1487 {1488 case KLDRPROT_NOACCESS:1489 case KLDRPROT_READWRITE:1490 case KLDRPROT_WRITECOPY:1491 case KLDRPROT_EXECUTE_READWRITE:1492 case KLDRPROT_EXECUTE_WRITECOPY:1493 continue;1494 case KLDRPROT_READONLY:1495 case KLDRPROT_EXECUTE:1496 case KLDRPROT_EXECUTE_READ:1497 break;1498 default:1499 KLDRMODPE_ASSERT(!"invalid");1500 continue;1501 }1502 1503 rc = kLdrRdrProtect(pMod->pRdr,1504 (uint8_t *)pvMapping + (pMod->aSegments[i].LinkAddress - pModPE->Hdrs.OptionalHeader.ImageBase),1505 pMod->aSegments[i].cbMapped,1506 enmProt);1507 }1508 1509 1348 return rc; 1510 1349 }
Note:
See TracChangeset
for help on using the changeset viewer.