Changeset 70310 in vbox
- Timestamp:
- Dec 22, 2017 11:47:01 AM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/ldr/ldrPE.cpp
r70257 r70310 3131 3131 * @param pszLogName The log name to prefix the errors with. 3132 3132 * @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 */ 3135 static int rtldrPEValidateFileHeader(PIMAGE_FILE_HEADER pFileHdr, uint32_t fFlags, const char *pszLogName, 3136 PRTLDRARCH penmArch, PRTERRINFO pErrInfo) 3135 3137 { 3136 3138 RT_NOREF_PV(pszLogName); … … 3149 3151 3150 3152 default: 3151 Log(("rtldrPEOpen: %s: Unsupported Machine=%#x\n", 3152 pszLogName, pFileHdr->Machine)); 3153 Log(("rtldrPEOpen: %s: Unsupported Machine=%#x\n", pszLogName, pFileHdr->Machine)); 3153 3154 *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); 3155 3156 } 3156 3157 if (pFileHdr->SizeOfOptionalHeader != cbOptionalHeader) 3157 3158 { 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); 3161 3162 } 3162 3163 /* This restriction needs to be implemented elsewhere. */ … … 3165 3166 { 3166 3167 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"); 3168 3169 } 3169 3170 if (pFileHdr->NumberOfSections > 42) … … 3171 3172 Log(("rtldrPEOpen: %s: NumberOfSections=%d - our limit is 42, please raise it if the binary makes sense.(!!!)\n", 3172 3173 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); 3174 3175 } 3175 3176 if (pFileHdr->NumberOfSections < 1) … … 3177 3178 Log(("rtldrPEOpen: %s: NumberOfSections=%d - we can't have an image without sections (!!!)\n", 3178 3179 pszLogName, pFileHdr->NumberOfSections)); 3179 return VERR_BAD_EXE_FORMAT;3180 return RTERRINFO_LOG_SET(pErrInfo, VERR_BAD_EXE_FORMAT, "Image has no sections"); 3180 3181 } 3181 3182 return VINF_SUCCESS; … … 3193 3194 * @param cbRawImage The raw image size. 3194 3195 * @param fFlags Loader flags, RTLDR_O_XXX. 3196 * @param pErrInfo Where to return additional error information. 3195 3197 */ 3196 3198 static 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) 3198 3200 { 3199 3201 RT_NOREF_PV(pszLogName); … … 3204 3206 { 3205 3207 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); 3207 3209 } 3208 3210 const uint32_t cbImage = pOptHdr->SizeOfImage; … … 3210 3212 { 3211 3213 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); 3213 3215 } 3214 3216 const uint32_t cbMinImageSize = pFileHdr->SizeOfOptionalHeader + sizeof(*pFileHdr) + 4 + (uint32_t)offNtHdrs; … … 3216 3218 { 3217 3219 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); 3219 3221 } 3220 3222 if (pOptHdr->AddressOfEntryPoint >= cbImage) … … 3222 3224 Log(("rtldrPEOpen: %s: AddressOfEntryPoint=%#x - beyond image size (%#x)!!!\n", 3223 3225 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); 3225 3228 } 3226 3229 if (pOptHdr->BaseOfCode >= cbImage) … … 3228 3231 Log(("rtldrPEOpen: %s: BaseOfCode=%#x - beyond image size (%#x)!!!\n", 3229 3232 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); 3231 3235 } 3232 3236 #if 0/* only in 32-bit header */ … … 3235 3239 Log(("rtldrPEOpen: %s: BaseOfData=%#x - beyond image size (%#x)!!!\n", 3236 3240 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); 3238 3242 } 3239 3243 #endif … … 3242 3246 Log(("rtldrPEOpen: %s: SizeOfHeaders=%#x - beyond image size (%#x)!!!\n", 3243 3247 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); 3245 3250 } 3246 3251 /* don't know how to do the checksum, so ignore it. */ … … 3248 3253 { 3249 3254 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); 3251 3256 } 3252 3257 if (pOptHdr->SizeOfHeaders < cbMinImageSize + pFileHdr->NumberOfSections * sizeof(IMAGE_SECTION_HEADER)) … … 3256 3261 cbMinImageSize, pFileHdr->NumberOfSections * sizeof(IMAGE_SECTION_HEADER), 3257 3262 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) ); 3259 3267 } 3260 3268 if (pOptHdr->SizeOfStackReserve < pOptHdr->SizeOfStackCommit) … … 3262 3270 Log(("rtldrPEOpen: %s: SizeOfStackReserve %#x < SizeOfStackCommit %#x!!!\n", 3263 3271 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); 3265 3274 } 3266 3275 if (pOptHdr->SizeOfHeapReserve < pOptHdr->SizeOfHeapCommit) … … 3268 3277 Log(("rtldrPEOpen: %s: SizeOfStackReserve %#x < SizeOfStackCommit %#x!!!\n", 3269 3278 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); 3271 3281 } 3272 3282 … … 3275 3285 { 3276 3286 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)); 3278 3289 } 3279 3290 for (unsigned i = 0; i < RT_ELEMENTS(pOptHdr->DataDirectory); i++) … … 3304 3315 Log(("rtldrPEOpen: %s: dir no. %d (DELAY_IMPORT) VirtualAddress=%#x Size=%#x is not supported!!!\n", 3305 3316 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); 3307 3319 3308 3320 case IMAGE_DIRECTORY_ENTRY_SECURITY: // 4 … … 3314 3326 { 3315 3327 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); 3317 3330 } 3318 3331 if (pDir->Size >= RTLDRMODPE_MAX_SECURITY_DIR_SIZE) 3319 3332 { 3320 3333 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); 3322 3336 } 3323 3337 if (pDir->VirtualAddress & 7) 3324 3338 { 3325 3339 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); 3327 3342 } 3328 3343 /* When using the in-memory reader with a debugger, we may get … … 3337 3352 Log(("rtldrPEOpen: %s: dir no. %d (GLOBALPTR) VirtualAddress=%#x Size=%#x is not supported!!!\n", 3338 3353 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); 3340 3356 3341 3357 case IMAGE_DIRECTORY_ENTRY_TLS: // 9 … … 3344 3360 Log(("rtldrPEOpen: %s: dir no. %d (TLS) VirtualAddress=%#x Size=%#x is not supported!!!\n", 3345 3361 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); 3347 3364 3348 3365 case IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR:// 14 … … 3351 3368 Log(("rtldrPEOpen: %s: dir no. %d (COM_DESCRIPTOR) VirtualAddress=%#x Size=%#x is not supported!!!\n", 3352 3369 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); 3354 3373 3355 3374 default: 3356 3375 Log(("rtldrPEOpen: %s: dir no. %d VirtualAddress=%#x Size=%#x is not supported!!!\n", 3357 3376 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); 3359 3379 } 3360 3380 if (pDir->VirtualAddress >= cb) … … 3362 3382 Log(("rtldrPEOpen: %s: dir no. %d VirtualAddress=%#x is invalid (limit %#x)!!!\n", 3363 3383 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); 3365 3386 } 3366 3387 if (pDir->Size > cb - pDir->VirtualAddress) … … 3368 3389 Log(("rtldrPEOpen: %s: dir no. %d Size=%#x is invalid (rva=%#x, limit=%#x)!!!\n", 3369 3390 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); 3371 3393 } 3372 3394 } … … 3929 3951 RTLDRARCH enmArchImage; 3930 3952 const char *pszLogName = pReader->pfnLogName(pReader); 3931 rc = rtldrPEValidateFileHeader(&FileHdr, fFlags, pszLogName, &enmArchImage );3953 rc = rtldrPEValidateFileHeader(&FileHdr, fFlags, pszLogName, &enmArchImage, pErrInfo); 3932 3954 if (RT_FAILURE(rc)) 3933 3955 return rc; … … 3942 3964 { 3943 3965 if (!(fFlags & RTLDR_O_IGNORE_ARCH_IF_NO_CODE)) 3944 return RTE rrInfoSetF(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)); 3946 3968 fArchNoCodeCheckPending = true; 3947 3969 } … … 3956 3978 if (FileHdr.SizeOfOptionalHeader != sizeof(OptHdr)) 3957 3979 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); 3959 3981 if (RT_FAILURE(rc)) 3960 3982 return rc; 3961 3983 if (fArchNoCodeCheckPending && OptHdr.SizeOfCode != 0) 3962 return RTE rrInfoSetF(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)); 3965 3987 3966 3988 /*
Note:
See TracChangeset
for help on using the changeset viewer.