Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added sanity check for page index when loading pages from broken samples #1120

Merged
merged 3 commits into from
Nov 7, 2022
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion include/retdec/pelib/ImageLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ enum struct PELIB_COMPARE_RESULT : std::uint32_t
//-----------------------------------------------------------------------------
// Windows build numbers

const std::uint32_t BuildNumberXP = 2600; // Behavior equal to Windows XP
const std::uint32_t BuildNumberXP = 2600; // Behavior equal to Windows XP
const std::uint32_t BuildNumberVista = 6000; // Behavior equal to Windows Vista (SP0 = 6000, SP1 = 6001, SP2 = 6002)
const std::uint32_t BuildNumber7 = 7600; // Behavior equal to Windows 7 (SP0 = 7600, SP1 = 7601)
const std::uint32_t BuildNumber8 = 9200; // Behavior equal to Windows 8
Expand Down
22 changes: 17 additions & 5 deletions src/pelib/ImageLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2239,15 +2239,21 @@ int PeLib::ImageLoader::captureImageSections(ByteBuffer & fileData, std::uint32_
{
// If loading as image, we need to take data from its virtual address
std::uint32_t pointerToRawData = (loadFlags & IoFlagLoadAsImage) ? sectionHeader.VirtualAddress : sectionHeader.PointerToRawData;
std::uint32_t sectionEnd;

// Capture all pages from the section
if(captureImageSection(fileData, sectionHeader.VirtualAddress,
sectionEnd = captureImageSection(fileData,
sectionHeader.VirtualAddress,
sectionHeader.VirtualSize,
pointerToRawData,
sectionHeader.SizeOfRawData,
sectionHeader.Characteristics) == 0)
sectionHeader.Characteristics);

// There must not be a Virtual Address overflow,
// nor the end of the section must be beyond the end of the image
if(sectionEnd < sectionHeader.VirtualAddress || sectionEnd > sizeOfImage)
{
setLoaderError(LDR_ERROR_INVALID_SECTION_VA);
setLoaderError(LDR_ERROR_INVALID_SECTION_VSIZE);
break;
}
}
Expand Down Expand Up @@ -2522,7 +2528,13 @@ std::uint32_t PeLib::ImageLoader::captureImageSection(
// * has 0x1000 bytes of inaccessible memory at ImageBase+0x1000 (1 page after section header)
sizeOfInitializedPages = AlignToSize(sizeOfRawData, PELIB_PAGE_SIZE);
sizeOfValidPages = AlignToSize(virtualSize, PELIB_PAGE_SIZE);

// Calculate aligned size of the section. Mind invalid sizes.
// Example: 83e9cb2a6e78c742e1090292acf3c78baf76e82950d96548673795a1901db061
// * Size of the last section is 0xfffff000, sizeOfSection becomes 0
sizeOfSection = AlignToSize(virtualSize, optionalHeader.SectionAlignment);
if(sizeOfSection < virtualSize)
sizeOfSection = virtualSize;

// Get the range of the file containing valid data (aka nonzeros)
// Pointer to raw data is aligned down to the sector size
Expand All @@ -2549,7 +2561,7 @@ std::uint32_t PeLib::ImageLoader::captureImageSection(
if(pointerToRawData || isImageHeader)
{
// Fill all pages that contain data
while(pageOffset < sizeOfInitializedPages)
while(pageOffset < sizeOfInitializedPages && pageIndex < pages.size())
{
PELIB_FILE_PAGE & filePage = pages[pageIndex++];

Expand Down Expand Up @@ -2579,7 +2591,7 @@ std::uint32_t PeLib::ImageLoader::captureImageSection(
}

// Fill all pages that contain zeroed pages
while(pageOffset < sizeOfValidPages)
while(pageOffset < sizeOfValidPages && pageIndex < pages.size())
{
PELIB_FILE_PAGE & filePage = pages[pageIndex++];

Expand Down