Skip to content

Commit

Permalink
Fixing an issue causing some RT_BITMAP resources to be corrupted during
Browse files Browse the repository at this point in the history
the extraction.
Fixing an issue causing ressources with the same ID to overwrite each
other when being extracted.
Fixed a crash which occurred when trying to extract a ressource with a
null size in some cases.
  • Loading branch information
JusticeRage committed May 28, 2016
1 parent 2a4886b commit 7d1827c
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 13 deletions.
27 changes: 25 additions & 2 deletions manape/resources.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -294,8 +294,14 @@ DECLSPEC const_shared_strings Resource::interpret_as()
{
std::wstring s = utils::read_prefixed_unicode_wstring(f);
std::vector<boost::uint8_t> utf8result;
utf8::utf16to8(s.begin(), s.end(), std::back_inserter(utf8result));
res->push_back(std::string(utf8result.begin(), utf8result.end()));
try
{
utf8::utf16to8(s.begin(), s.end(), std::back_inserter(utf8result));
res->push_back(std::string(utf8result.begin(), utf8result.end()));
}
catch (utf8::invalid_utf16) {
PRINT_WARNING << "Couldn't convert a string from a RT_STRING resource to UTF-8!" << std::endl;
}
}

END:
Expand Down Expand Up @@ -329,8 +335,15 @@ DECLSPEC pbitmap Resource::interpret_as()
}
boost::uint32_t dib_header_size = 0;
boost::uint32_t colors_used = 0;
boost::uint16_t bit_count;
memcpy(&dib_header_size, &(res->data[0]), sizeof(boost::uint32_t)); // DIB header size is located at offset 0.
memcpy(&bit_count, &(res->data[14]), sizeof(boost::uint16_t));
memcpy(&colors_used, &(res->data[32]), sizeof(boost::uint32_t));


if (colors_used == 0 && bit_count != 32 && bit_count != 24) {
colors_used = 1 << bit_count;
}

res->OffsetToData = header_size + dib_header_size + 4*colors_used;
return res;
Expand Down Expand Up @@ -642,6 +655,10 @@ std::vector<boost::uint8_t> reconstruct_icon(pgroup_icon_directory directory, co
*/
bool write_data_to_file(const boost::filesystem::path& destination, std::vector<boost::uint8_t> data)
{
if (data.size() == 0) {
return true;
}

FILE* f = fopen(destination.string().c_str(), "wb+");
if (f == nullptr)
{
Expand Down Expand Up @@ -732,6 +749,12 @@ bool Resource::icon_extract(const boost::filesystem::path& destination,
return extract(destination);
}
data = reconstruct_icon(interpret_as<pgroup_icon_directory>(), resources);
if (data.size() == 0)
{
PRINT_WARNING << "Resource " << _name << " is empty!" << DEBUG_INFO << std::endl;
return true;
}

return write_data_to_file(destination, data);
}

Expand Down
2 changes: 1 addition & 1 deletion plugins/plugin_mitigation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ class ExploitMitigationsPlugin : public IPlugin
else
{
std::stringstream ss;
ss << "enabled (" << config->SEHandlerCount << " registered handler" << (config->SEHandlerCount == 1 ? "s" : "") << ")";
ss << "enabled (" << config->SEHandlerCount << " registered handler" << (config->SEHandlerCount == 1 ? "" : "s") << ")";
res->add_information("SafeSEH", ss.str());
}

Expand Down
14 changes: 4 additions & 10 deletions src/dump.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -574,17 +574,17 @@ bool extract_resources(const mana::PE& pe, const std::string& destination_folder
std::stringstream ss;
if (*(*it)->get_type() == "RT_GROUP_ICON" || *(*it)->get_type() == "RT_GROUP_CURSOR")
{
ss << base << "_" << (*it)->get_id() << "_" << *(*it)->get_type() << ".ico";
ss << base << "_" << *(*it)->get_name() << "_" << *(*it)->get_type() << ".ico";
res &= (*it)->icon_extract(bfs::path(destination_folder) / bfs::path(ss.str()), *pe.get_resources());
}
else if (*(*it)->get_type() == "RT_MANIFEST")
{
ss << base << "_" << (*it)->get_id() << "_RT_MANIFEST.xml";
ss << base << "_" << *(*it)->get_name() << "_RT_MANIFEST.xml";
res &= (*it)->extract(bfs::path(destination_folder) / bfs::path(ss.str()));
}
else if (*(*it)->get_type() == "RT_BITMAP")
{
ss << base << "_" << (*it)->get_id() << "_RT_BITMAP.bmp";
ss << base << "_" << *(*it)->get_name() << "_RT_BITMAP.bmp";
res &= (*it)->extract(bfs::path(destination_folder) / bfs::path(ss.str()));
}
else if (*(*it)->get_type() == "RT_ICON" || *(*it)->get_type() == "RT_CURSOR" || *(*it)->get_type() == "RT_VERSION") {
Expand All @@ -599,13 +599,7 @@ bool extract_resources(const mana::PE& pe, const std::string& destination_folder
}
else // General case
{
ss << base << "_";
if (*(*it)->get_name() != "") {
ss << *(*it)->get_name();
}
else {
ss << (*it)->get_id();
}
ss << base << "_" << *(*it)->get_name();

// Try to guess the file extension
auto m = detect_filetype(*it);
Expand Down

0 comments on commit 7d1827c

Please sign in to comment.