VirtualBox

Changeset 70310 in vbox


Ignore:
Timestamp:
Dec 22, 2017 11:47:01 AM (7 years ago)
Author:
vboxsync
Message:

IPRT/ldrPE: Set error info on header validation trouble.

File:
1 edited

Legend:

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

    r70257 r70310  
    31313131 * @param   pszLogName  The log name to  prefix the errors with.
    31323132 * @param   penmArch    Where to store the CPU architecture.
    3133  */
    3134 static int rtldrPEValidateFileHeader(PIMAGE_FILE_HEADER pFileHdr, uint32_t fFlags, const char *pszLogName, PRTLDRARCH penmArch)
     3133 * @param   pErrInfo    Where to return additional error information.
     3134 */
     3135static int rtldrPEValidateFileHeader(PIMAGE_FILE_HEADER pFileHdr, uint32_t fFlags, const char *pszLogName,
     3136                                     PRTLDRARCH penmArch, PRTERRINFO pErrInfo)
    31353137{
    31363138    RT_NOREF_PV(pszLogName);
     
    31493151
    31503152        default:
    3151             Log(("rtldrPEOpen: %s: Unsupported Machine=%#x\n",
    3152                  pszLogName, pFileHdr->Machine));
     3153            Log(("rtldrPEOpen: %s: Unsupported Machine=%#x\n", pszLogName, pFileHdr->Machine));
    31533154            *penmArch = RTLDRARCH_INVALID;
    3154             return VERR_BAD_EXE_FORMAT;
     3155            return RTERRINFO_LOG_SET_F(pErrInfo, VERR_BAD_EXE_FORMAT, "Unsupported Machine=%#x", pszLogName, pFileHdr->Machine);
    31553156    }
    31563157    if (pFileHdr->SizeOfOptionalHeader != cbOptionalHeader)
    31573158    {
    3158         Log(("rtldrPEOpen: %s: SizeOfOptionalHeader=%#x expected %#x\n",
    3159              pszLogName, pFileHdr->SizeOfOptionalHeader, cbOptionalHeader));
    3160         return VERR_BAD_EXE_FORMAT;
     3159        Log(("rtldrPEOpen: %s: SizeOfOptionalHeader=%#x expected %#x\n", pszLogName, pFileHdr->SizeOfOptionalHeader, cbOptionalHeader));
     3160        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_BAD_EXE_FORMAT, "SizeOfOptionalHeader=%#x expected %#x",
     3161                                   pFileHdr->SizeOfOptionalHeader, cbOptionalHeader);
    31613162    }
    31623163    /* This restriction needs to be implemented elsewhere. */
     
    31653166    {
    31663167        Log(("rtldrPEOpen: %s: IMAGE_FILE_RELOCS_STRIPPED\n", pszLogName));
    3167         return VERR_BAD_EXE_FORMAT;
     3168        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_BAD_EXE_FORMAT, "IMAGE_FILE_RELOCS_STRIPPED");
    31683169    }
    31693170    if (pFileHdr->NumberOfSections > 42)
     
    31713172        Log(("rtldrPEOpen: %s: NumberOfSections=%d - our limit is 42, please raise it if the binary makes sense.(!!!)\n",
    31723173             pszLogName, pFileHdr->NumberOfSections));
    3173         return VERR_BAD_EXE_FORMAT;
     3174        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_BAD_EXE_FORMAT, "NumberOfSections=%d, implementation max is 42", pFileHdr->NumberOfSections);
    31743175    }
    31753176    if (pFileHdr->NumberOfSections < 1)
     
    31773178        Log(("rtldrPEOpen: %s: NumberOfSections=%d - we can't have an image without sections (!!!)\n",
    31783179             pszLogName, pFileHdr->NumberOfSections));
    3179         return VERR_BAD_EXE_FORMAT;
     3180        return RTERRINFO_LOG_SET(pErrInfo, VERR_BAD_EXE_FORMAT, "Image has no sections");
    31803181    }
    31813182    return VINF_SUCCESS;
     
    31933194 * @param   cbRawImage  The raw image size.
    31943195 * @param   fFlags      Loader flags, RTLDR_O_XXX.
     3196 * @param   pErrInfo    Where to return additional error information.
    31953197 */
    31963198static int rtldrPEValidateOptionalHeader(const IMAGE_OPTIONAL_HEADER64 *pOptHdr, const char *pszLogName, RTFOFF offNtHdrs,
    3197                                          const IMAGE_FILE_HEADER *pFileHdr, RTFOFF cbRawImage, uint32_t fFlags)
     3199                                         const IMAGE_FILE_HEADER *pFileHdr, RTFOFF cbRawImage, uint32_t fFlags, PRTERRINFO pErrInfo)
    31983200{
    31993201    RT_NOREF_PV(pszLogName);
     
    32043206    {
    32053207        Log(("rtldrPEOpen: %s: Magic=%#x - expected %#x!!!\n", pszLogName, pOptHdr->Magic, CorrectMagic));
    3206         return VERR_BAD_EXE_FORMAT;
     3208        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_BAD_EXE_FORMAT, "Magic=%#x, expected %#x", pOptHdr->Magic, CorrectMagic);
    32073209    }
    32083210    const uint32_t cbImage = pOptHdr->SizeOfImage;
     
    32103212    {
    32113213        Log(("rtldrPEOpen: %s: SizeOfImage=%#x - Our limit is 1GB (%#x)!!!\n", pszLogName, cbImage, _1G));
    3212         return VERR_BAD_EXE_FORMAT;
     3214        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_BAD_EXE_FORMAT, "SizeOfImage=%#x - Our limit is 1GB (%#x)", cbImage, _1G);
    32133215    }
    32143216    const uint32_t cbMinImageSize = pFileHdr->SizeOfOptionalHeader + sizeof(*pFileHdr) + 4 + (uint32_t)offNtHdrs;
     
    32163218    {
    32173219        Log(("rtldrPEOpen: %s: SizeOfImage=%#x to small, minimum %#x!!!\n", pszLogName, cbImage, cbMinImageSize));
    3218         return VERR_BAD_EXE_FORMAT;
     3220        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_BAD_EXE_FORMAT, "SizeOfImage=%#x to small, minimum %#x", cbImage, cbMinImageSize);
    32193221    }
    32203222    if (pOptHdr->AddressOfEntryPoint >= cbImage)
     
    32223224        Log(("rtldrPEOpen: %s: AddressOfEntryPoint=%#x - beyond image size (%#x)!!!\n",
    32233225             pszLogName, pOptHdr->AddressOfEntryPoint, cbImage));
    3224         return VERR_BAD_EXE_FORMAT;
     3226        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_BAD_EXE_FORMAT,
     3227                                   "AddressOfEntryPoint=%#x - beyond image size (%#x)", pOptHdr->AddressOfEntryPoint, cbImage);
    32253228    }
    32263229    if (pOptHdr->BaseOfCode >= cbImage)
     
    32283231        Log(("rtldrPEOpen: %s: BaseOfCode=%#x - beyond image size (%#x)!!!\n",
    32293232             pszLogName, pOptHdr->BaseOfCode, cbImage));
    3230         return VERR_BAD_EXE_FORMAT;
     3233        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_BAD_EXE_FORMAT,
     3234                                   "BaseOfCode=%#x - beyond image size (%#x)", pOptHdr->BaseOfCode, cbImage);
    32313235    }
    32323236#if 0/* only in 32-bit header */
     
    32353239        Log(("rtldrPEOpen: %s: BaseOfData=%#x - beyond image size (%#x)!!!\n",
    32363240             pszLogName, pOptHdr->BaseOfData, cbImage));
    3237         return VERR_BAD_EXE_FORMAT;
     3241        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_BAD_EXE_FORMAT, "BaseOfData=%#x - beyond image size (%#x)", pOptHdr->BaseOfData, cbImage);
    32383242    }
    32393243#endif
     
    32423246        Log(("rtldrPEOpen: %s: SizeOfHeaders=%#x - beyond image size (%#x)!!!\n",
    32433247             pszLogName, pOptHdr->SizeOfHeaders, cbImage));
    3244         return VERR_BAD_EXE_FORMAT;
     3248        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_BAD_EXE_FORMAT,
     3249                                   "SizeOfHeaders=%#x - beyond image size (%#x)", pOptHdr->SizeOfHeaders, cbImage);
    32453250    }
    32463251    /* don't know how to do the checksum, so ignore it. */
     
    32483253    {
    32493254        Log(("rtldrPEOpen: %s: Subsystem=%#x (unknown)!!!\n", pszLogName, pOptHdr->Subsystem));
    3250         return VERR_BAD_EXE_FORMAT;
     3255        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_BAD_EXE_FORMAT, "Subsystem=%#x (unknown)", pOptHdr->Subsystem);
    32513256    }
    32523257    if (pOptHdr->SizeOfHeaders < cbMinImageSize + pFileHdr->NumberOfSections * sizeof(IMAGE_SECTION_HEADER))
     
    32563261             cbMinImageSize, pFileHdr->NumberOfSections * sizeof(IMAGE_SECTION_HEADER),
    32573262             cbMinImageSize + pFileHdr->NumberOfSections * sizeof(IMAGE_SECTION_HEADER)));
    3258         return VERR_BAD_EXE_FORMAT;
     3263        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_BAD_EXE_FORMAT, "SizeOfHeaders=%#x - cbMinImageSize %#x + sections %#x = %#llx",
     3264                                   pOptHdr->SizeOfHeaders, cbMinImageSize,
     3265                                   pFileHdr->NumberOfSections * sizeof(IMAGE_SECTION_HEADER),
     3266                                   cbMinImageSize + pFileHdr->NumberOfSections * sizeof(IMAGE_SECTION_HEADER) );
    32593267    }
    32603268    if (pOptHdr->SizeOfStackReserve < pOptHdr->SizeOfStackCommit)
     
    32623270        Log(("rtldrPEOpen: %s: SizeOfStackReserve %#x < SizeOfStackCommit %#x!!!\n",
    32633271             pszLogName, pOptHdr->SizeOfStackReserve, pOptHdr->SizeOfStackCommit));
    3264         return VERR_BAD_EXE_FORMAT;
     3272        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_BAD_EXE_FORMAT, "SizeOfStackReserve %#x < SizeOfStackCommit %#x",
     3273                                   pOptHdr->SizeOfStackReserve, pOptHdr->SizeOfStackCommit);
    32653274    }
    32663275    if (pOptHdr->SizeOfHeapReserve < pOptHdr->SizeOfHeapCommit)
     
    32683277        Log(("rtldrPEOpen: %s: SizeOfStackReserve %#x < SizeOfStackCommit %#x!!!\n",
    32693278             pszLogName, pOptHdr->SizeOfStackReserve, pOptHdr->SizeOfStackCommit));
    3270         return VERR_BAD_EXE_FORMAT;
     3279        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_BAD_EXE_FORMAT, "SizeOfStackReserve %#x < SizeOfStackCommit %#x\n",
     3280                                   pOptHdr->SizeOfStackReserve, pOptHdr->SizeOfStackCommit);
    32713281    }
    32723282
     
    32753285    {
    32763286        Log(("rtldrPEOpen: %s: NumberOfRvaAndSizes=%d!!!\n", pszLogName, pOptHdr->NumberOfRvaAndSizes));
    3277         return VERR_BAD_EXE_FORMAT;
     3287        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_BAD_EXE_FORMAT, "NumberOfRvaAndSizes=%d, expected %d",
     3288                                   pOptHdr->NumberOfRvaAndSizes, RT_ELEMENTS(pOptHdr->DataDirectory));
    32783289    }
    32793290    for (unsigned i = 0; i < RT_ELEMENTS(pOptHdr->DataDirectory); i++)
     
    33043315                Log(("rtldrPEOpen: %s: dir no. %d (DELAY_IMPORT) VirtualAddress=%#x Size=%#x is not supported!!!\n",
    33053316                     pszLogName, i, pDir->VirtualAddress, pDir->Size));
    3306                 return VERR_LDRPE_DELAY_IMPORT;
     3317                return RTERRINFO_LOG_SET_F(pErrInfo, VERR_LDRPE_DELAY_IMPORT,
     3318                                           "DELAY_IMPORT VirtualAddress=%#x Size=%#x: not supported", pDir->VirtualAddress, pDir->Size);
    33073319
    33083320            case IMAGE_DIRECTORY_ENTRY_SECURITY:      // 4
     
    33143326                {
    33153327                    Log(("rtldrPEOpen: %s: Security directory #%u is too small: %#x bytes\n", pszLogName, i, pDir->Size));
    3316                     return VERR_LDRPE_CERT_MALFORMED;
     3328                    return RTERRINFO_LOG_SET_F(pErrInfo, VERR_LDRPE_CERT_MALFORMED,
     3329                                               "Security directory is too small: %#x bytes", pDir->Size);
    33173330                }
    33183331                if (pDir->Size >= RTLDRMODPE_MAX_SECURITY_DIR_SIZE)
    33193332                {
    33203333                    Log(("rtldrPEOpen: %s: Security directory #%u is too large: %#x bytes\n", pszLogName, i, pDir->Size));
    3321                     return VERR_LDRPE_CERT_MALFORMED;
     3334                    return RTERRINFO_LOG_SET_F(pErrInfo, VERR_LDRPE_CERT_MALFORMED,
     3335                                               "Security directory is too large: %#x bytes", pDir->Size);
    33223336                }
    33233337                if (pDir->VirtualAddress & 7)
    33243338                {
    33253339                    Log(("rtldrPEOpen: %s: Security directory #%u is misaligned: %#x\n", pszLogName, i, pDir->VirtualAddress));
    3326                     return VERR_LDRPE_CERT_MALFORMED;
     3340                    return RTERRINFO_LOG_SET_F(pErrInfo, VERR_LDRPE_CERT_MALFORMED,
     3341                                               "Security directory is misaligned: %#x", pDir->VirtualAddress);
    33273342                }
    33283343                /* When using the in-memory reader with a debugger, we may get
     
    33373352                Log(("rtldrPEOpen: %s: dir no. %d (GLOBALPTR) VirtualAddress=%#x Size=%#x is not supported!!!\n",
    33383353                     pszLogName, i, pDir->VirtualAddress, pDir->Size));
    3339                 return VERR_LDRPE_GLOBALPTR;
     3354                return RTERRINFO_LOG_SET_F(pErrInfo, VERR_LDRPE_GLOBALPTR, "GLOBALPTR VirtualAddress=%#x Size=%#x: not supported",
     3355                                           pDir->VirtualAddress, pDir->Size);
    33403356
    33413357            case IMAGE_DIRECTORY_ENTRY_TLS:           // 9
     
    33443360                Log(("rtldrPEOpen: %s: dir no. %d (TLS) VirtualAddress=%#x Size=%#x is not supported!!!\n",
    33453361                     pszLogName, i, pDir->VirtualAddress, pDir->Size));
    3346                 return VERR_LDRPE_TLS;
     3362                return RTERRINFO_LOG_SET_F(pErrInfo, VERR_LDRPE_TLS, "TLS VirtualAddress=%#x Size=%#x: not supported",
     3363                                           pDir->VirtualAddress, pDir->Size);
    33473364
    33483365            case IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR:// 14
     
    33513368                Log(("rtldrPEOpen: %s: dir no. %d (COM_DESCRIPTOR) VirtualAddress=%#x Size=%#x is not supported!!!\n",
    33523369                     pszLogName, i, pDir->VirtualAddress, pDir->Size));
    3353                 return VERR_LDRPE_COM_DESCRIPTOR;
     3370                return RTERRINFO_LOG_SET_F(pErrInfo, VERR_LDRPE_COM_DESCRIPTOR,
     3371                                           "COM_DESCRIPTOR VirtualAddress=%#x Size=%#x: not supported",
     3372                                           pDir->VirtualAddress, pDir->Size);
    33543373
    33553374            default:
    33563375                Log(("rtldrPEOpen: %s: dir no. %d VirtualAddress=%#x Size=%#x is not supported!!!\n",
    33573376                     pszLogName, i, pDir->VirtualAddress, pDir->Size));
    3358                 return VERR_BAD_EXE_FORMAT;
     3377                return RTERRINFO_LOG_SET_F(pErrInfo, VERR_BAD_EXE_FORMAT, "dir no. %d VirtualAddress=%#x Size=%#x is not supported",
     3378                                           i, pDir->VirtualAddress, pDir->Size);
    33593379        }
    33603380        if (pDir->VirtualAddress >= cb)
     
    33623382            Log(("rtldrPEOpen: %s: dir no. %d VirtualAddress=%#x is invalid (limit %#x)!!!\n",
    33633383                 pszLogName, i, pDir->VirtualAddress, cb));
    3364             return VERR_BAD_EXE_FORMAT;
     3384            return RTERRINFO_LOG_SET_F(pErrInfo, VERR_BAD_EXE_FORMAT, "dir no. %d VirtualAddress=%#x is invalid (limit %#x)",
     3385                                       i, pDir->VirtualAddress, cb);
    33653386        }
    33663387        if (pDir->Size > cb - pDir->VirtualAddress)
     
    33683389            Log(("rtldrPEOpen: %s: dir no. %d Size=%#x is invalid (rva=%#x, limit=%#x)!!!\n",
    33693390                 pszLogName, i, pDir->Size, pDir->VirtualAddress, cb));
    3370             return VERR_BAD_EXE_FORMAT;
     3391            return RTERRINFO_LOG_SET_F(pErrInfo, VERR_BAD_EXE_FORMAT, "dir no. %d Size=%#x is invalid (rva=%#x, limit=%#x)",
     3392                                       i, pDir->Size, pDir->VirtualAddress, cb);
    33713393        }
    33723394    }
     
    39293951    RTLDRARCH enmArchImage;
    39303952    const char *pszLogName = pReader->pfnLogName(pReader);
    3931     rc = rtldrPEValidateFileHeader(&FileHdr, fFlags, pszLogName, &enmArchImage);
     3953    rc = rtldrPEValidateFileHeader(&FileHdr, fFlags, pszLogName, &enmArchImage, pErrInfo);
    39323954    if (RT_FAILURE(rc))
    39333955        return rc;
     
    39423964    {
    39433965        if (!(fFlags & RTLDR_O_IGNORE_ARCH_IF_NO_CODE))
    3944             return RTErrInfoSetF(pErrInfo, VERR_LDR_ARCH_MISMATCH, "Image is for '%s', only accepting images for '%s'.",
    3945                                  rtldrPEGetArchName(FileHdr.Machine), rtLdrArchName(enmArch));
     3966            return RTERRINFO_LOG_SET_F(pErrInfo, VERR_LDR_ARCH_MISMATCH, "Image is for '%s', only accepting images for '%s'.",
     3967                                       rtldrPEGetArchName(FileHdr.Machine), rtLdrArchName(enmArch));
    39463968        fArchNoCodeCheckPending = true;
    39473969    }
     
    39563978    if (FileHdr.SizeOfOptionalHeader != sizeof(OptHdr))
    39573979        rtldrPEConvert32BitOptionalHeaderTo64Bit(&OptHdr);
    3958     rc = rtldrPEValidateOptionalHeader(&OptHdr, pszLogName, offNtHdrs, &FileHdr, pReader->pfnSize(pReader), fFlags);
     3980    rc = rtldrPEValidateOptionalHeader(&OptHdr, pszLogName, offNtHdrs, &FileHdr, pReader->pfnSize(pReader), fFlags, pErrInfo);
    39593981    if (RT_FAILURE(rc))
    39603982        return rc;
    39613983    if (fArchNoCodeCheckPending && OptHdr.SizeOfCode != 0)
    3962         return RTErrInfoSetF(pErrInfo, VERR_LDR_ARCH_MISMATCH,
    3963                              "Image is for '%s' and contains code (%#x), only accepting images for '%s' with code.",
    3964                              rtldrPEGetArchName(FileHdr.Machine), OptHdr.SizeOfCode, rtLdrArchName(enmArch));
     3984        return RTERRINFO_LOG_SET_F(pErrInfo, VERR_LDR_ARCH_MISMATCH,
     3985                                   "Image is for '%s' and contains code (%#x), only accepting images for '%s' with code.",
     3986                                   rtldrPEGetArchName(FileHdr.Machine), OptHdr.SizeOfCode, rtLdrArchName(enmArch));
    39653987
    39663988    /*
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