Skip to content

Commit

Permalink
Fixed an OOM error when parsing hostile IATs.
Browse files Browse the repository at this point in the history
Added a unit test for the get_overlay function.
Integrating r2's problematic/fuzzing binaries into Manalyze's CI process.
  • Loading branch information
JusticeRage committed Nov 26, 2018
1 parent 00a3f84 commit e4d9254
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 3 deletions.
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,7 @@ script:
- bin/manalyze-tests
- bin/hash-library-test
after_success:
- git clone https://github.com/radare/radare2-regressions.git
- bin/manalyze -r radare2-regressions/bins/pe/
- bin/manalyze -r radare2-regressions/bins/
- coveralls --exclude external/yara --exclude test --exclude plugins/plugin_virustotal/json_spirit --gcov gcov-4.8
29 changes: 27 additions & 2 deletions manape/imports.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,14 +67,15 @@ bool PE::_parse_import_lookup_table(unsigned int offset, pImportedLibrary librar
return false;
}

auto imports = library->get_imports();
while (true) // We stop at the first NULL IMPORT_LOOKUP_TABLE
{
pimport_lookup_table import = boost::make_shared<import_lookup_table>();
import->AddressOfData = 0;
import->Hint = 0;

// The field has a size of 8 for x64 PEs
int size_to_read = (get_architecture() == x86 ? 4 : 8);
unsigned int size_to_read = (get_architecture() == x86 ? 4 : 8);
if (size_to_read != fread(&(import->AddressOfData), 1, size_to_read, _file_handle.get()))
{
PRINT_ERROR << "Could not read the IMPORT_LOOKUP_TABLE." << std::endl;
Expand All @@ -90,6 +91,30 @@ bool PE::_parse_import_lookup_table(unsigned int offset, pImportedLibrary librar
return false;
}

// Verify that the number of imports is sane:
if (imports->size() > 10000)
{
PRINT_ERROR << "Gave up on parsing the import table after reading 10000 entries! This PE was almost certainly crafted manually!"
<< DEBUG_INFO_INSIDEPE << std::endl;
return false;
}

// Verify that the import is not already in the list (avoid parsing loops)
auto found = std::find_if(imports->begin(), imports->end(), [import](const auto& it)->bool
{
return import->AddressOfData == it->AddressOfData &&
import->Hint == it->Hint &&
import->Name == it->Name;
});


if (found != imports->end())
{
PRINT_ERROR << "Read the same import twice! This PE was almost certainly crafted manually!"
<< DEBUG_INFO_INSIDEPE << std::endl;
return false;
}

library->add_import(import);
}
return true;
Expand Down Expand Up @@ -168,7 +193,7 @@ bool PE::_parse_imports()
{
// Non fatal. Stop trying to parse imports, but the ones already read will still be available.
if ((*it)->get_name() != nullptr) {
PRINT_WARNING << "An error occurred while trying to read functions imported by " << *(*it)->get_name()
PRINT_WARNING << "An error occurred while trying to read functions imported by module " << *(*it)->get_name()
<< "." << DEBUG_INFO_INSIDEPE << std::endl;
}
return true;
Expand Down
2 changes: 1 addition & 1 deletion manape/pe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ shared_bytes PE::get_raw_bytes(size_t size) const

shared_bytes PE::get_overlay_bytes(size_t size) const
{
if (_file_handle == nullptr || !_ioh) {
if (_file_handle == nullptr || !_ioh || size == 0) {
return nullptr;
}

Expand Down
19 changes: 19 additions & 0 deletions test/pe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,25 @@ BOOST_AUTO_TEST_CASE(parse_delayed_imports)

// ----------------------------------------------------------------------------

BOOST_AUTO_TEST_CASE(parse_overlay)
{
mana::PE pe("testfiles/manatest3.exe");
auto overlay = pe.get_overlay_bytes();
BOOST_ASSERT(overlay);
std::string s(overlay->begin(), overlay->end());
BOOST_CHECK_EQUAL(s, "Overlay Bytes :)");

overlay = pe.get_overlay_bytes(8);
BOOST_ASSERT(overlay);
std::string s2(overlay->begin(), overlay->end());
BOOST_CHECK_EQUAL(s2, "Overlay ");

overlay = pe.get_overlay_bytes(0);
BOOST_ASSERT(!overlay);
}

// ----------------------------------------------------------------------------

BOOST_AUTO_TEST_CASE(parse_rich_header)
{
mana::PE pe("testfiles/manatest.exe");
Expand Down
Binary file modified test/testfiles/manatest3.exe
Binary file not shown.

0 comments on commit e4d9254

Please sign in to comment.