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

Lz retdec 54 #981

Merged
merged 5 commits into from
Jul 21, 2021
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
4 changes: 2 additions & 2 deletions include/retdec/fileformat/file_format/pe/pe_format_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,8 +265,8 @@ class PeFormatParser
section.setType(sectionType);
section.setIndex(secIndex);
section.setOffset(imageLoader.getRealPointerToRawData(secIndex));
section.setSizeInFile(pSectionHeader->SizeOfRawData);
section.setSizeInMemory(pSectionHeader->VirtualSize);
section.setSizeInFile(imageLoader.getRealSizeOfRawData(secIndex));
section.setSizeInMemory((pSectionHeader->VirtualSize != 0) ? pSectionHeader->VirtualSize : pSectionHeader->SizeOfRawData);
section.setAddress(pSectionHeader->VirtualAddress ? imageLoader.getImageBase() + pSectionHeader->VirtualAddress : 0);
section.setMemory(section.getAddress());
section.setPeCoffFlags(pSectionHeader->Characteristics);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ class ResourceIcon : public Resource
/// @{
bool hasLoadedProperties() const;
bool hasValidColorCount() const;
bool hasValidDimensions() const;

/// @}
};

Expand Down
12 changes: 9 additions & 3 deletions include/retdec/pelib/DelayImportDirectory.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ namespace PeLib
return ERROR_INVALID_FILE;
init();

// Keep loading until we encounter an entry filles with zeros
// Keep loading until we encounter an entry filled with zeros
for(std::uint32_t i = 0;; i += sizeof(PELIB_IMAGE_DELAY_LOAD_DESCRIPTOR))
{
PELIB_IMAGE_DELAY_IMPORT_DIRECTORY_RECORD rec;
Expand All @@ -113,8 +113,14 @@ namespace PeLib
if(!imageLoader.readImage(&rec.delayedImport, rva + i, sizeof(PELIB_IMAGE_DELAY_LOAD_DESCRIPTOR)))
break;

// Valid delayed import entry starts either with 0 or 0x01
if(rec.delayedImport.Attributes & 0xFFFF0000)
// Valid delayed import entry starts either with 0 or 0x01.
// We strict require one of the valid values here
if(rec.delayedImport.Attributes > PELIB_DELAY_ATTRIBUTE_V2)
break;

// Stop on blatantly invalid entries
if(rec.delayedImport.NameRva < sizeof(PELIB_IMAGE_DOS_HEADER) ||
rec.delayedImport.DelayImportNameTableRva < sizeof(PELIB_IMAGE_DOS_HEADER))
break;

// Check for the termination entry
Expand Down
1 change: 1 addition & 0 deletions include/retdec/pelib/ImageLoader.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ class ImageLoader
std::uint32_t vaToRva(std::uint64_t VirtualAddress) const;
std::uint32_t getFileOffsetFromRva(std::uint32_t rva) const;
std::uint32_t getRealPointerToRawData(std::size_t sectionIndex) const;
std::uint32_t getRealSizeOfRawData(std::size_t sectionIndex) const;
std::uint32_t getImageProtection(std::uint32_t characteristics) const;
std::size_t getSectionIndexByRva(std::uint32_t Rva) const;

Expand Down
2 changes: 1 addition & 1 deletion src/fileformat/file_format/file_format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ bool isAddressFromRegion(const SecSeg *actualRegion, const SecSeg *newRegion, st
return false;
}

unsigned long long newRegionSize;
unsigned long long newRegionSize = 0;
if(!newRegion->getSizeInMemory(newRegionSize))
{
newRegionSize = newRegion->getSizeInFile();
Expand Down
10 changes: 10 additions & 0 deletions src/fileformat/types/resource_table/resource_icon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -179,5 +179,15 @@ bool ResourceIcon::hasValidColorCount() const
return validColorCount;
}

/**
* Returns tru if the icon dimensions were already set before
* @return @c `true` if they were, otherwise `false`
*/
bool ResourceIcon::hasValidDimensions() const
{
return (width && height);
}


} // namespace fileformat
} // namespace retdec
28 changes: 16 additions & 12 deletions src/fileformat/types/resource_table/resource_icon_group.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,27 +39,31 @@ constexpr std::pair<uint16_t, uint16_t> iconPriorities[] =
bool iconCompare(const retdec::fileformat::ResourceIcon *i1, const retdec::fileformat::ResourceIcon *i2)
{
auto i1Width = i1->getWidth();
auto i1Height = i1->getHeight();
auto i1BitCount = i1->getBitCount();
auto i2Width = i2->getWidth();
auto i2Height = i2->getHeight();
auto i2BitCount = i2->getBitCount();

if(i2Width != i2Height)
{
// Priority 1: icon with the same dimensions over icons
if((i1Width == i1Height) && (i2Width != i2Height))
return false;
}
if((i1Width != i1Height) && (i2Width == i2Height))
return true;

for(const auto &p : iconPriorities)
{
// Priority 2: Icons where both size and bit count match
if(p.first == i1Width && p.second == i1BitCount)
{
return false;
}

if(p.first == i2Width && p.second == i2BitCount)
{
return true;
}

// Priority 3: Icons where size matches
if(p.first == i1Width)
return false;
if(p.first == i2Width)
return true;
}

return false;
Expand Down Expand Up @@ -183,8 +187,8 @@ bool ResourceIconGroup::getEntryWidth(std::size_t eIndex, std::uint16_t &width)
return false;
}

width = bytes[0];

if((width = bytes[0]) == 0)
width = 256; // https://devblogs.microsoft.com/oldnewthing/20101018-00/?p=12513
return true;
}

Expand All @@ -203,8 +207,8 @@ bool ResourceIconGroup::getEntryHeight(std::size_t eIndex, std::uint16_t &height
return false;
}

height = bytes[0];

if((height = bytes[0]) == 0)
height = 256; // https://devblogs.microsoft.com/oldnewthing/20101018-00/?p=12513
return true;
}

Expand Down
5 changes: 5 additions & 0 deletions src/fileformat/types/resource_table/resource_table.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,11 @@ void ResourceTable::linkResourceIconGroups()
continue;
}

// Multiple icon group may reference an icon. If that happens, do not rewrite
// icon dimensions. Doing so messes up with the icon hash, and we only care for the first icon anyway
if(icon->hasValidDimensions())
continue;

icon->setWidth(width);
icon->setHeight(height);
icon->setIconSize(iconSize);
Expand Down
12 changes: 12 additions & 0 deletions src/pelib/ImageLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,18 @@ uint32_t PeLib::ImageLoader::getRealPointerToRawData(size_t sectionIndex) const
return sections[sectionIndex].PointerToRawData & ~(PELIB_SECTOR_SIZE - 1);
}

uint32_t PeLib::ImageLoader::getRealSizeOfRawData(std::size_t sectionIndex) const
{
if(sectionIndex >= sections.size())
return UINT32_MAX;
if(optionalHeader.SectionAlignment < PELIB_PAGE_SIZE)
return sections[sectionIndex].SizeOfRawData;

uint32_t beginOfRawData = sections[sectionIndex].PointerToRawData & ~(PELIB_SECTOR_SIZE - 1);
uint32_t endOfRawData = sections[sectionIndex].PointerToRawData + AlignToSize(sections[sectionIndex].SizeOfRawData, optionalHeader.FileAlignment);
return endOfRawData - beginOfRawData;
}

uint32_t PeLib::ImageLoader::getImageProtection(uint32_t sectionCharacteristics) const
{
uint32_t Index = 0;
Expand Down
5 changes: 2 additions & 3 deletions src/pelib/ResourceDirectory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -669,15 +669,14 @@ namespace PeLib
return ERROR_NONE;
}

// Load all entries to the vector
std::vector<PELIB_IMAGE_RESOURCE_DIRECTORY_ENTRY> vResourceChildren(uiNumberOfEntries);
resDir->insertNodeOffset(uiOffset);

if (uiNumberOfEntries > 0)
{
resDir->addOccupiedAddressRange(uiRva, uiRva + uiNumberOfEntries * PELIB_IMAGE_RESOURCE_DIRECTORY_ENTRY::size() - 1);
}

// Load all entries to the vector
for (unsigned int i = 0; i < uiNumberOfEntries; i++)
{
ResourceChild rc;
Expand Down Expand Up @@ -720,7 +719,7 @@ namespace PeLib
{
// Check whether we have enough space to read at least one character
unsigned int uiNameOffset = rc.entry.irde.Name & PELIB_IMAGE_RESOURCE_RVA_MASK;
if (uiRva + uiNameOffset + sizeof(std::uint16_t) > sizeOfImage)
if (uiRsrcRva + uiNameOffset + sizeof(std::uint16_t) > sizeOfImage)
{
return ERROR_INVALID_FILE;
}
Expand Down