Changeset 70257 in vbox for trunk/src/VBox
- Timestamp:
- Dec 21, 2017 6:15:11 AM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/ldr/ldrPE.cpp
r69111 r70257 3376 3376 3377 3377 /** 3378 * Validates the section headers. 3378 * Validates and touch up the section headers. 3379 * 3380 * The touching up is restricted to setting the VirtualSize field for old-style 3381 * linkers that sets it to zero. 3379 3382 * 3380 3383 * @returns iprt status code. … … 3387 3390 * @param fNoCode Verify that the image contains no code. 3388 3391 */ 3389 static int rtldrPEValidateSectionHeaders(const IMAGE_SECTION_HEADER *paSections, unsigned cSections, const char *pszLogName, 3390 const IMAGE_OPTIONAL_HEADER64 *pOptHdr, RTFOFF cbRawImage, uint32_t fFlags, bool fNoCode) 3392 static int rtldrPEValidateAndTouchUpSectionHeaders(IMAGE_SECTION_HEADER *paSections, unsigned cSections, const char *pszLogName, 3393 const IMAGE_OPTIONAL_HEADER64 *pOptHdr, RTFOFF cbRawImage, uint32_t fFlags, 3394 bool fNoCode) 3391 3395 { 3392 3396 RT_NOREF_PV(pszLogName); 3393 3397 3398 /* 3399 * Do a quick pass to detect linker setting VirtualSize to zero. 3400 */ 3401 bool fFixupVirtualSize = true; 3402 IMAGE_SECTION_HEADER *pSH = &paSections[0]; 3403 for (unsigned cSHdrsLeft = cSections; cSHdrsLeft > 0; cSHdrsLeft--, pSH++) 3404 if ( pSH->Misc.VirtualSize != 0 3405 && !(pSH->Characteristics & IMAGE_SCN_TYPE_NOLOAD)) 3406 { 3407 fFixupVirtualSize = false; 3408 break; 3409 } 3410 3411 /* 3412 * Actual pass. 3413 */ 3394 3414 const uint32_t cbImage = pOptHdr->SizeOfImage; 3395 const IMAGE_SECTION_HEADER *pSH = &paSections[0];3396 3415 uint32_t uRvaPrev = pOptHdr->SizeOfHeaders; 3416 pSH = &paSections[0]; 3397 3417 Log3(("RTLdrPE: Section Headers:\n")); 3398 for (unsigned cSHdrsLeft = cSections; 3418 for (unsigned cSHdrsLeft = cSections; cSHdrsLeft > 0; cSHdrsLeft--, pSH++) 3399 3419 { 3400 3420 const unsigned iSH = (unsigned)(pSH - &paSections[0]); NOREF(iSH); … … 3419 3439 } 3420 3440 3421 if ( pSH->Misc.VirtualSize3422 && !(pSH->Characteristics & IMAGE_SCN_TYPE_NOLOAD)) /* binutils uses this for '.stab' even if it's reserved/obsoleted by MS. */3423 {3424 if (pSH->VirtualAddress < uRvaPrev)3425 {3426 Log(("rtldrPEOpen: %s: Overlaps previous section or sections aren't in ascending order, VirtualAddress=%#x uRvaPrev=%#x - section #%d '%.*s'!!!\n",3427 pszLogName, pSH->VirtualAddress, uRvaPrev, iSH, sizeof(pSH->Name), pSH->Name));3428 return VERR_BAD_EXE_FORMAT;3429 }3430 if (pSH->VirtualAddress > cbImage)3431 {3432 Log(("rtldrPEOpen: %s: VirtualAddress=%#x - beyond image size (%#x) - section #%d '%.*s'!!!\n",3433 pszLogName, pSH->VirtualAddress, cbImage, iSH, sizeof(pSH->Name), pSH->Name));3434 return VERR_BAD_EXE_FORMAT;3435 }3436 3437 if (pSH->VirtualAddress & (pOptHdr->SectionAlignment - 1)) //ASSUMES power of 2 alignment.3438 {3439 Log(("rtldrPEOpen: %s: VirtualAddress=%#x misaligned (%#x) - section #%d '%.*s'!!!\n",3440 pszLogName, pSH->VirtualAddress, pOptHdr->SectionAlignment, iSH, sizeof(pSH->Name), pSH->Name));3441 return VERR_BAD_EXE_FORMAT;3442 }3443 3444 #ifdef PE_FILE_OFFSET_EQUALS_RVA3445 /* Our loader code assume rva matches the file offset. */3446 if ( pSH->SizeOfRawData3447 && pSH->PointerToRawData != pSH->VirtualAddress)3448 {3449 Log(("rtldrPEOpen: %s: ASSUMPTION FAILED: file offset %#x != RVA %#x - section #%d '%.*s'!!!\n",3450 pszLogName, pSH->PointerToRawData, pSH->VirtualAddress, iSH, sizeof(pSH->Name), pSH->Name));3451 return VERR_BAD_EXE_FORMAT;3452 }3453 #endif3454 }3455 3456 /// @todo only if SizeOfRawData > 0 ?3457 3441 if ( pSH->PointerToRawData > cbRawImage /// @todo pSH->PointerToRawData >= cbRawImage ? 3458 3442 || pSH->SizeOfRawData > cbRawImage … … 3472 3456 } 3473 3457 3458 if (!(pSH->Characteristics & IMAGE_SCN_TYPE_NOLOAD)) /* binutils uses this for '.stab' even if it's reserved/obsoleted by MS. */ 3459 { 3460 /* Calc VirtualSize if necessary. This is for internal reasons. */ 3461 if ( pSH->Misc.VirtualSize == 0 3462 && fFixupVirtualSize) 3463 { 3464 pSH->Misc.VirtualSize = cbImage - RT_MIN(pSH->VirtualAddress, cbImage); 3465 for (uint32_t i = 1; i < cSHdrsLeft; i++) 3466 if ( !(pSH[i].Characteristics & IMAGE_SCN_TYPE_NOLOAD) 3467 && pSH[i].VirtualAddress >= pSH->VirtualAddress) 3468 { 3469 pSH->Misc.VirtualSize = RT_MIN(pSH[i].VirtualAddress - pSH->VirtualAddress, pSH->Misc.VirtualSize); 3470 break; 3471 } 3472 } 3473 3474 if (pSH->Misc.VirtualSize > 0) 3475 { 3476 if (pSH->VirtualAddress < uRvaPrev) 3477 { 3478 Log(("rtldrPEOpen: %s: Overlaps previous section or sections aren't in ascending order, VirtualAddress=%#x uRvaPrev=%#x - section #%d '%.*s'!!!\n", 3479 pszLogName, pSH->VirtualAddress, uRvaPrev, iSH, sizeof(pSH->Name), pSH->Name)); 3480 return VERR_BAD_EXE_FORMAT; 3481 } 3482 if (pSH->VirtualAddress > cbImage) 3483 { 3484 Log(("rtldrPEOpen: %s: VirtualAddress=%#x - beyond image size (%#x) - section #%d '%.*s'!!!\n", 3485 pszLogName, pSH->VirtualAddress, cbImage, iSH, sizeof(pSH->Name), pSH->Name)); 3486 return VERR_BAD_EXE_FORMAT; 3487 } 3488 3489 if (pSH->VirtualAddress & (pOptHdr->SectionAlignment - 1)) //ASSUMES power of 2 alignment. 3490 { 3491 Log(("rtldrPEOpen: %s: VirtualAddress=%#x misaligned (%#x) - section #%d '%.*s'!!!\n", 3492 pszLogName, pSH->VirtualAddress, pOptHdr->SectionAlignment, iSH, sizeof(pSH->Name), pSH->Name)); 3493 return VERR_BAD_EXE_FORMAT; 3494 } 3495 3496 #ifdef PE_FILE_OFFSET_EQUALS_RVA 3497 /* Our loader code assume rva matches the file offset. */ 3498 if ( pSH->SizeOfRawData 3499 && pSH->PointerToRawData != pSH->VirtualAddress) 3500 { 3501 Log(("rtldrPEOpen: %s: ASSUMPTION FAILED: file offset %#x != RVA %#x - section #%d '%.*s'!!!\n", 3502 pszLogName, pSH->PointerToRawData, pSH->VirtualAddress, iSH, sizeof(pSH->Name), pSH->Name)); 3503 return VERR_BAD_EXE_FORMAT; 3504 } 3505 #endif 3506 3507 uRvaPrev = pSH->VirtualAddress + pSH->Misc.VirtualSize; 3508 } 3509 } 3510 3474 3511 /* ignore the relocations and linenumbers. */ 3475 3476 uRvaPrev = pSH->VirtualAddress + pSH->Misc.VirtualSize;3477 3512 } 3478 3513 … … 3940 3975 if (RT_SUCCESS(rc)) 3941 3976 { 3942 rc = rtldrPEValidate SectionHeaders(paSections, FileHdr.NumberOfSections, pszLogName,3943 &OptHdr, pReader->pfnSize(pReader), fFlags, fArchNoCodeCheckPending);3977 rc = rtldrPEValidateAndTouchUpSectionHeaders(paSections, FileHdr.NumberOfSections, pszLogName, 3978 &OptHdr, pReader->pfnSize(pReader), fFlags, fArchNoCodeCheckPending); 3944 3979 if (RT_SUCCESS(rc)) 3945 3980 {
Note:
See TracChangeset
for help on using the changeset viewer.