From aa15ad90a8f437fd7e2b6cf75219ca110a9257c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marek=20Milkovi=C4=8D?= Date: Fri, 8 Jan 2021 00:16:25 +0100 Subject: [PATCH] unpacker/mpress: Properly copy non-packer related sections to the unpacked file --- src/unpackertool/plugins/mpress/mpress.cpp | 17 +++++++++++------ src/unpackertool/plugins/mpress/mpress.h | 2 +- src/unpackertool/plugins/upx/pe/pe_upx_stub.cpp | 2 +- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/unpackertool/plugins/mpress/mpress.cpp b/src/unpackertool/plugins/mpress/mpress.cpp index 2734a6f3e..a0651965e 100644 --- a/src/unpackertool/plugins/mpress/mpress.cpp +++ b/src/unpackertool/plugins/mpress/mpress.cpp @@ -658,17 +658,18 @@ void MpressPlugin::saveFile(const std::string& fileName, DynamicBuffer& content) // Headers imageLoader.Save(fileName.c_str()); + std::fstream outputFile(fileName, std::ios::binary | std::ios::out | std::ios::in); // Copy the section bytes from original file for the sections preceding the packed section for (std::uint32_t index = 0; index < _packedContentSect->getSecSeg()->getIndex(); ++index) - copySectionFromOriginalFile(index, fileName, index); + copySectionFromOriginalFile(index, outputFile, index); // Copy the section bytes in between packed section and EP section for (std::uint32_t index = _packedContentSect->getSecSeg()->getIndex() + _addedSectionCount; index < _file->getEpSegment()->getSecSeg()->getIndex(); ++index) - copySectionFromOriginalFile(index, fileName, index + _addedSectionCount); + copySectionFromOriginalFile(index, outputFile, index + _addedSectionCount); // Copy the section bytes from original file for sections after EP section excluded for (std::uint32_t index = _file->getEpSegment()->getSecSeg()->getIndex() + 1; index < _file->getNumberOfSegments(); ++index) - copySectionFromOriginalFile(index, fileName, index + _addedSectionCount); + copySectionFromOriginalFile(index, outputFile, index + _addedSectionCount); // Write content of new import section std::uint32_t Rva = imageLoader.getDataDirRva(PeLib::PELIB_IMAGE_DIRECTORY_ENTRY_IMPORT); @@ -691,18 +692,22 @@ void MpressPlugin::saveFile(const std::string& fileName, DynamicBuffer& content) // Write the unpacked content to the packed content section // Use regular file as we will write more sections at once - std::fstream outputFile(fileName, std::ios::binary | std::ios::out | std::ios::in); outputFile.seekp(imageLoader.getSectionHeader(_packedContentSect->getSecSeg()->getIndex())->PointerToRawData, std::ios_base::beg); outputFile.write(reinterpret_cast(content.getRawBuffer()), content.getRealDataSize()); outputFile.close(); } -void MpressPlugin::copySectionFromOriginalFile(std::uint32_t origSectIndex, const std::string& newFileName, std::uint32_t newSectIndex) +void MpressPlugin::copySectionFromOriginalFile(std::uint32_t origSectIndex, std::ostream& outputFile, std::uint32_t newSectIndex) { const retdec::loader::Segment* seg = _file->getSegment(origSectIndex); std::vector bytes; seg->getBytes(bytes); - //_peFile->peHeader().writeSectionData(newFileName, newSectIndex, bytes); + + PeLib::ImageLoader & imageLoader = _peFile->imageLoader(); + const auto* newSect = imageLoader.getSectionHeader(newSectIndex); + outputFile.seekp(newSect->PointerToRawData, std::ios_base::beg); + outputFile.write(reinterpret_cast(bytes.data()), std::min(static_cast(bytes.size()), newSect->SizeOfRawData)); + } } // namespace mpress diff --git a/src/unpackertool/plugins/mpress/mpress.h b/src/unpackertool/plugins/mpress/mpress.h index b5bd576ae..453644614 100644 --- a/src/unpackertool/plugins/mpress/mpress.h +++ b/src/unpackertool/plugins/mpress/mpress.h @@ -86,7 +86,7 @@ class MpressPlugin : public Plugin MpressUnpackerStub detectUnpackerStubVersion(); MpressFixStub detectFixStubVersion(retdec::utils::DynamicBuffer& unpackedContent); void saveFile(const std::string& fileName, retdec::utils::DynamicBuffer& content); - void copySectionFromOriginalFile(std::uint32_t origSectIndex, const std::string& newFileName, std::uint32_t newSectIndex); + void copySectionFromOriginalFile(std::uint32_t origSectIndex, std::ostream& outputFile, std::uint32_t newSectIndex); std::unique_ptr _file; PeLib::PeFileT * _peFile; diff --git a/src/unpackertool/plugins/upx/pe/pe_upx_stub.cpp b/src/unpackertool/plugins/upx/pe/pe_upx_stub.cpp index 22618ddff..95a3bc0e4 100644 --- a/src/unpackertool/plugins/upx/pe/pe_upx_stub.cpp +++ b/src/unpackertool/plugins/upx/pe/pe_upx_stub.cpp @@ -1238,7 +1238,7 @@ template void PeUpxStub::saveFile(const std::string& outputFile if (!_coffSymbolTable.empty()) retdec::utils::writeFile(outputFileHandle, _coffSymbolTable, imageLoader.getPointerToSymbolTable()); outputFileHandle.close(); - + // Write resources at the end, because they would be rewritten by unpackedData which have them zeroed if((Rva = imageLoader.getDataDirRva(PeLib::PELIB_IMAGE_DIRECTORY_ENTRY_RESOURCE)) != 0) _newPeFile->resDir().write(outputFile, imageLoader.getFileOffsetFromRva(Rva), Rva);