Skip to content
This repository has been archived by the owner on Jan 27, 2020. It is now read-only.

Increased limit for number of entries in import directory #13

Merged
merged 4 commits into from
Nov 15, 2019
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 27 additions & 31 deletions include/pelib/ImportDirectory.h
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,9 @@ namespace PeLib
unsigned int uiDescCounter = 0;
unsigned int uiDescOffset = uiOffset;

// For tracking unique imported DLLs
std::unordered_map<std::string, int> uniqueDllList;

// Read and store all descriptors
for (;;)
{
Expand Down Expand Up @@ -565,8 +568,8 @@ namespace PeLib
if (iidCurr.impdesc.Name == 0 || iidCurr.impdesc.FirstThunk == 0)
break;

// We ignore names and thunks that go beyond the file
if (iidCurr.impdesc.Name > SizeOfImage)
// We ignore import names that go beyond the file
if (iidCurr.impdesc.Name > SizeOfImage || !peHeader.isValidRva(iidCurr.impdesc.Name))
{
setLoaderError(LDR_ERROR_IMPDIR_NAME_RVA_INVALID);
break;
Expand All @@ -578,46 +581,39 @@ namespace PeLib
break;
}

// Retrieve the import name string from the image
getStringFromFileOffset(inStream_w, iidCurr.name, peHeader.rvaToOffset(iidCurr.impdesc.Name), IMPORT_LIBRARY_MAX_LENGTH);

// Ignore too large import directories
// Sample: CCE461B6EB23728BA3B8A97B9BE84C0FB9175DB31B9949E64144198AB3F702CE
// Number of import descriptors: 0x6253
if (vOldIidCurr.size() > PELIB_MAX_IMPORT_DESCRIPTORS)
// Sample: CCE461B6EB23728BA3B8A97B9BE84C0FB9175DB31B9949E64144198AB3F702CE, # of impdesc 0x6253 (invalid)
// Sample: 395e64e7071d35cb85d8312095aede5166db731aac44920679eee5c7637cc58c, # of impdesc 0x0131 (valid)
if (uniqueDllList.find(iidCurr.name) == uniqueDllList.end())
{
setLoaderError(LDR_ERROR_IMPDIR_COUNT_EXCEEDED);
break;
}
// Remember that the DLL was imported before
uniqueDllList.insert(std::make_pair(iidCurr.name, 1));
s3rvac marked this conversation as resolved.
Show resolved Hide resolved

// Push the import descriptor into the vector
vOldIidCurr.push_back(iidCurr);
}

// Space occupied by import descriptors
m_occupiedAddresses.emplace_back(peHeader.getIddImportRva(), peHeader.getIddImportRva() + (uiDescOffset - uiOffset - 1));

// Name
for (unsigned int i=0;i<vOldIidCurr.size();i++)
{
if (!peHeader.isValidRva(vOldIidCurr[i].impdesc.Name))
{
setLoaderError(LDR_ERROR_IMPDIR_NAME_RVA_INVALID);
return ERROR_INVALID_FILE;
// Check the total number of imported DLLs
if(uniqueDllList.size() >= PELIB_MAX_IMPORT_DLLS)
s3rvac marked this conversation as resolved.
Show resolved Hide resolved
{
setLoaderError(LDR_ERROR_IMPDIR_COUNT_EXCEEDED);
break;
}
}

getStringFromFileOffset(
inStream_w,
vOldIidCurr[i].name,
static_cast<unsigned int>(peHeader.rvaToOffset(vOldIidCurr[i].impdesc.Name)),
IMPORT_LIBRARY_MAX_LENGTH);

// Space occupied by names
// Mark the range occupied by name
// +1 for null terminator
// If the end address is even, we need to align it by 2, so next name always starts at even address
m_occupiedAddresses.emplace_back(static_cast<unsigned int>(vOldIidCurr[i].impdesc.Name),
static_cast<unsigned int>(vOldIidCurr[i].impdesc.Name + vOldIidCurr[i].name.length() + 1));
m_occupiedAddresses.emplace_back(iidCurr.impdesc.Name, iidCurr.impdesc.Name + iidCurr.name.length() + 1);
if (!(m_occupiedAddresses.back().second & 1))
m_occupiedAddresses.back().second += 1;

// Push the import descriptor into the vector
vOldIidCurr.push_back(iidCurr);
}

// Space occupied by import descriptors
m_occupiedAddresses.emplace_back(peHeader.getIddImportRva(), peHeader.getIddImportRva() + (uiDescOffset - uiOffset - 1));

// OriginalFirstThunk - ILT
for (unsigned int i=0;i<vOldIidCurr.size();i++)
{
Expand Down
3 changes: 2 additions & 1 deletion include/pelib/PeLibAux.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#include <numeric>
#include <limits>
#include <unordered_map>

#ifdef _MSC_VER // Reduces number of warnings under MS Visual Studio from ~100000 to zero
#pragma warning(disable:4267) // C4267: 'initializing': conversion from 'size_t' to '_Ty2', possible loss of data
Expand Down Expand Up @@ -207,7 +208,7 @@ namespace PeLib

const dword PELIB_MM_SIZE_OF_LARGEST_IMAGE = 0x77000000;

const dword PELIB_MAX_IMPORT_DESCRIPTORS = 0x100; // Maximum number of import descriptors we support
const dword PELIB_MAX_IMPORT_DLLS = 0x100; // Maximum number of imported DLLs we consider OK
const dword PELIB_MAX_IMPORTED_FUNCTIONS = 0x1000; // Maximum number of exported functions (per DLL) that we support
const dword PELIB_MAX_EXPORTED_FUNCTIONS = 0x1000; // Maximum number of exported functions that we support

Expand Down