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 e958176
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 12 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
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 e958176

Please sign in to comment.