From 172c574cb17027a1d3a64636db5924d4f02af357 Mon Sep 17 00:00:00 2001 From: Zezula Ladislav Date: Thu, 16 Jan 2020 14:12:30 +0100 Subject: [PATCH] Fixed detection of cut import directory --- include/pelib/ImportDirectory.h | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/include/pelib/ImportDirectory.h b/include/pelib/ImportDirectory.h index 6517c22..c5208ed 100644 --- a/include/pelib/ImportDirectory.h +++ b/include/pelib/ImportDirectory.h @@ -542,7 +542,8 @@ namespace PeLib } std::uint64_t ulFileSize = fileSize(inStream_w); - unsigned int uiOffset = (unsigned int)peHeader.rvaToOffset(peHeader.getIddImportRva()); + unsigned int uiRva = peHeader.getIddImportRva(); + unsigned int uiOffset = (unsigned int)peHeader.rvaToOffset(uiRva); if ((uiOffset + PELIB_IMAGE_IMPORT_DESCRIPTOR::size()) > ulFileSize) { @@ -563,15 +564,26 @@ namespace PeLib // Read and store all descriptors for (;;) { - // Are we getting out of the file? - if (uiDescOffset + PELIB_IMAGE_IMPORT_DESCRIPTOR::size() > ulFileSize) + std::vector vImportDescriptor(PELIB_IMAGE_IMPORT_DESCRIPTOR::size()); + + // If the required range is within the file, then we read the data. + // If not, it's RVA may still be valid due mapping -> keep zeros. + // Example sample: de0dea00414015bacbcbfc1fa53af9f6731522687d82f5de2e9402410488d190 + // (single entry in the import directory at file offset 0x3EC4 followed by end-of-file) + if ((uiDescOffset + PELIB_IMAGE_IMPORT_DESCRIPTOR::size()) <= ulFileSize) { - setLoaderError(LDR_ERROR_IMPDIR_CUT); - break; + // The offset is within the file range -> read it from the file + inStream_w.read(reinterpret_cast(vImportDescriptor.data()), PELIB_IMAGE_IMPORT_DESCRIPTOR::size()); + } + else + { + // The offset is out of physical file -> is the RVA still valid? + if (!peHeader.isValidRva(uiRva + PELIB_IMAGE_IMPORT_DESCRIPTOR::size())) + { + setLoaderError(LDR_ERROR_IMPDIR_CUT); + break; + } } - - std::vector vImportDescriptor(PELIB_IMAGE_IMPORT_DESCRIPTOR::size()); - inStream_w.read(reinterpret_cast(vImportDescriptor.data()), PELIB_IMAGE_IMPORT_DESCRIPTOR::size()); InputBuffer inpBuffer(vImportDescriptor); @@ -582,6 +594,7 @@ namespace PeLib inpBuffer >> iidCurr.impdesc.FirstThunk; uiDescOffset += PELIB_IMAGE_IMPORT_DESCRIPTOR::size(); + uiRva += PELIB_IMAGE_IMPORT_DESCRIPTOR::size(); uiDescCounter++; // If Name or FirstThunk are 0, this descriptor is considered as null-terminator.