VirtualBox

Changeset 70257 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Dec 21, 2017 6:15:11 AM (7 years ago)
Author:
vboxsync
Message:

IPRT/ldrPE.cpp: Almost forgotten old linkers didn't set IMAGE_SECTION_HEADER::Misc.VirtualSize - implemented the usual workaround.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/ldr/ldrPE.cpp

    r69111 r70257  
    33763376
    33773377/**
    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.
    33793382 *
    33803383 * @returns iprt status code.
     
    33873390 * @param   fNoCode     Verify that the image contains no code.
    33883391 */
    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)
     3392static 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)
    33913395{
    33923396    RT_NOREF_PV(pszLogName);
    33933397
     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     */
    33943414    const uint32_t              cbImage  = pOptHdr->SizeOfImage;
    3395     const IMAGE_SECTION_HEADER *pSH      = &paSections[0];
    33963415    uint32_t                    uRvaPrev = pOptHdr->SizeOfHeaders;
     3416    pSH = &paSections[0];
    33973417    Log3(("RTLdrPE: Section Headers:\n"));
    3398     for (unsigned cSHdrsLeft = cSections;  cSHdrsLeft > 0; cSHdrsLeft--, pSH++)
     3418    for (unsigned cSHdrsLeft = cSections; cSHdrsLeft > 0; cSHdrsLeft--, pSH++)
    33993419    {
    34003420        const unsigned iSH = (unsigned)(pSH - &paSections[0]); NOREF(iSH);
     
    34193439        }
    34203440
    3421         if (    pSH->Misc.VirtualSize
    3422             &&  !(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_RVA
    3445             /* Our loader code assume rva matches the file offset. */
    3446             if (    pSH->SizeOfRawData
    3447                 &&  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 #endif
    3454         }
    3455 
    3456         /// @todo only if SizeOfRawData > 0 ?
    34573441        if (    pSH->PointerToRawData > cbRawImage /// @todo pSH->PointerToRawData >= cbRawImage ?
    34583442            ||  pSH->SizeOfRawData > cbRawImage
     
    34723456        }
    34733457
     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
    34743511        /* ignore the relocations and linenumbers. */
    3475 
    3476         uRvaPrev = pSH->VirtualAddress + pSH->Misc.VirtualSize;
    34773512    }
    34783513
     
    39403975    if (RT_SUCCESS(rc))
    39413976    {
    3942         rc = rtldrPEValidateSectionHeaders(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);
    39443979        if (RT_SUCCESS(rc))
    39453980        {
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette