From ffef28adaf3ec15af138a28381e4678001c1961e Mon Sep 17 00:00:00 2001 From: Zezula Ladislav Date: Wed, 18 Apr 2018 10:41:59 +0200 Subject: [PATCH 01/13] Intermediate commit --- deps/pelib/CMakeLists.txt | 5 +-- .../fileformat/file_format/file_format.h | 15 +++++++++ .../fileformat/file_format/pe/pe_format.h | 3 +- include/retdec/loader/loader/image.h | 3 ++ include/retdec/utils/conversion.h | 33 ++++++++++++++++++- src/fileformat/file_format/pe/pe_format.cpp | 15 +++++++++ src/fileinfo/file_detector/file_detector.cpp | 6 ++++ .../file_information/file_information.cpp | 18 ++++++++++ .../file_information/file_information.h | 10 +++--- .../file_information_types/loader_info.cpp | 11 +++++++ .../file_information_types/loader_info.h | 10 ++++-- .../simple_getter/basic_plain_getter.cpp | 16 +++++++-- .../file_presentation/json_presentation.cpp | 21 ++++++++++++ .../file_presentation/json_presentation.h | 1 + src/loader/loader/image.cpp | 12 ++++++- src/loader/loader/pe/pe_image.cpp | 9 ++++- 16 files changed, 173 insertions(+), 15 deletions(-) diff --git a/deps/pelib/CMakeLists.txt b/deps/pelib/CMakeLists.txt index 39ff2ed47..bf32fa214 100644 --- a/deps/pelib/CMakeLists.txt +++ b/deps/pelib/CMakeLists.txt @@ -8,8 +8,9 @@ if(CMAKE_CXX_COMPILER) endif() ExternalProject_Add(pelib-project - URL https://github.com/avast-tl/pelib/archive/e93eaa7c150f4608a5d02a67f5edc9e54456fe24.zip - URL_HASH SHA256=2ffd7e89451c980a1af6d24d4f6dfbb69a660b06ad5de44c481f6431e21de394 + URL https://github.com/avast-tl/pelib/archive/e7cccb0303f1f928d2503095017faee5e643b3e4.zip +# URL https://github.com/avast-tl/pelib/archive/e93eaa7c150f4608a5d02a67f5edc9e54456fe24.zip +# URL_HASH SHA256=2ffd7e89451c980a1af6d24d4f6dfbb69a660b06ad5de44c481f6431e21de394 DOWNLOAD_NAME pelib.zip CMAKE_ARGS # This does not work on MSVC, but may be useful on Linux. diff --git a/include/retdec/fileformat/file_format/file_format.h b/include/retdec/fileformat/file_format/file_format.h index bbd629307..73c436c79 100644 --- a/include/retdec/fileformat/file_format/file_format.h +++ b/include/retdec/fileformat/file_format/file_format.h @@ -21,6 +21,21 @@ namespace retdec { namespace fileformat { +/** +* LoaderErrorInfo - common structure that contains loader error code, error message and user-friendly error message +*/ + +struct LoaderErrorInfo +{ + LoaderErrorInfo() : loaderErrorCode(0), loaderErrorType(0), loaderError(nullptr), loaderErrorUserFriendly(nullptr) + {} + + std::uint32_t loaderErrorCode:24; // Loader error code, cast to uint32_t + std::uint32_t loaderErrorType:8; // Loader error code source (0 - PE loader). To be extended for ELF, Mach-O etc. + const char * loaderError; + const char * loaderErrorUserFriendly; +}; + /** * FileFormat - abstract class for parsing files */ diff --git a/include/retdec/fileformat/file_format/pe/pe_format.h b/include/retdec/fileformat/file_format/pe/pe_format.h index 2e60ed8f8..ea87f38e6 100644 --- a/include/retdec/fileformat/file_format/pe/pe_format.h +++ b/include/retdec/fileformat/file_format/pe/pe_format.h @@ -147,7 +147,8 @@ class PeFormat : public FileFormat std::size_t getSizeOfHeapCommit() const; std::size_t getNumberOfDataDirectories() const; std::size_t getDeclaredNumberOfDataDirectories() const; - int getPeClass() const; + std::size_t getLoaderErrorInfo(retdec::fileformat::LoaderErrorInfo & ldrErrInfo) const; + int getPeClass() const; bool isDotNet() const; bool isPackedDotNet() const; bool isVisualBasic(unsigned long long &version) const; diff --git a/include/retdec/loader/loader/image.h b/include/retdec/loader/loader/image.h index bea68e453..6ab5db1b4 100644 --- a/include/retdec/loader/loader/image.h +++ b/include/retdec/loader/loader/image.h @@ -74,6 +74,7 @@ class Image : public retdec::utils::ByteValueStorage std::pair getRawSegmentData(std::uint64_t address) const; const std::string& getStatusMessage() const; + const retdec::fileformat::LoaderErrorInfo & getLoaderErrorInfo() const; protected: Segment* insertSegment(std::unique_ptr segment); @@ -82,6 +83,7 @@ class Image : public retdec::utils::ByteValueStorage void sortSegments(); void setStatusMessage(const std::string& message); + void setLoaderErrorInfo(const retdec::fileformat::LoaderErrorInfo & ldrErrInfo); private: const Segment* _getSegment(std::size_t index) const; @@ -93,6 +95,7 @@ class Image : public retdec::utils::ByteValueStorage std::vector> _segments; std::uint64_t _baseAddress; NameGenerator _namelessSegNameGen; + retdec::fileformat::LoaderErrorInfo _ldrErrInfo; std::string _statusMessage; }; diff --git a/include/retdec/utils/conversion.h b/include/retdec/utils/conversion.h index 7c3d14a5e..6961d6d7e 100644 --- a/include/retdec/utils/conversion.h +++ b/include/retdec/utils/conversion.h @@ -205,7 +205,37 @@ template void bytesToHexString(const N *data, std::size_t dataSize, size = (size == 0 || offset + size > dataSize) ? dataSize - offset : size; } - result.clear(); + // Sample: 4A2A008CF1AEE9BA49D8D1DAA22D8E868365ACE633823D464478239F27ED4F18 + // Tool: redec-fileinfo.exe, Debug, x64, data = image, dataSize = 0xE1BC00 + // This code takes 0.106 seconds to convert (measured in VS 2015 IDE) + const char * intToHex = uppercase ? "0123456789ABCDEF" : "0123456789abcdef"; + char * hexString = new char[(size * 2) + 1]; + if (hexString != nullptr) + { + char * hexStringPtr = hexString; + + // Convert to hexa byte-by-byte. No reallocations + for (std::size_t i = 0; i < size; ++i, hexStringPtr += 2) + { + std::uint8_t oneByte = data[offset + i]; + + hexStringPtr[0] = intToHex[(oneByte >> 0x04) & 0x0F]; + hexStringPtr[1] = intToHex[(oneByte >> 0x00) & 0x0F]; + } + + // Assign the hexa string to the result + hexStringPtr[0] = 0; + result = hexString; + + // Free the working string + delete[] hexString; + } + +/* + // Sample: 4A2A008CF1AEE9BA49D8D1DAA22D8E868365ACE633823D464478239F27ED4F18 + // Tool: redec-fileinfo.exe, Debug, x64, data = image, dataSize = 0xE1BC00 + // This code takes 40 seconds to convert (measured in VS 2015 IDE) + result.clear(); result.reserve(size * 2); std::ostringstream oStr; @@ -215,6 +245,7 @@ template void bytesToHexString(const N *data, std::size_t dataSize, } result = oStr.str(); +*/ } /** diff --git a/src/fileformat/file_format/pe/pe_format.cpp b/src/fileformat/file_format/pe/pe_format.cpp index 8f1032d99..d39c74ac4 100644 --- a/src/fileformat/file_format/pe/pe_format.cpp +++ b/src/fileformat/file_format/pe/pe_format.cpp @@ -2299,6 +2299,21 @@ std::size_t PeFormat::getDeclaredNumberOfDataDirectories() const return formatParser->getDeclaredNumberOfDataDirectories(); } +/** +* Get the error code that Windows loader would report +* @return Windows loader error code +*/ +std::size_t PeFormat::getLoaderErrorInfo(retdec::fileformat::LoaderErrorInfo & ldrErrInfo) const +{ + PeLib::LoaderError ldrError = file->loaderError(); + + ldrErrInfo.loaderErrorCode = (std::uint32_t)ldrError; + ldrErrInfo.loaderError = getLoaderErrorString(ldrError, false); + ldrErrInfo.loaderErrorUserFriendly = getLoaderErrorString(ldrError, true); + + return ldrErrInfo.loaderErrorCode; + } + /** * Get class of PE file * @return PeLib::PEFILE32 if file is 32-bit PE file, PeLib::PEFILE64 if file is diff --git a/src/fileinfo/file_detector/file_detector.cpp b/src/fileinfo/file_detector/file_detector.cpp index e7f21b13f..59408b48e 100644 --- a/src/fileinfo/file_detector/file_detector.cpp +++ b/src/fileinfo/file_detector/file_detector.cpp @@ -266,6 +266,12 @@ void FileDetector::getLoaderInfo() { fileInfo.setLoaderStatusMessage(image->getStatusMessage()); } + + const retdec::fileformat::LoaderErrorInfo & ldrErrInfo = image->getLoaderErrorInfo(); + if (ldrErrInfo.loaderErrorCode != 0) + { + fileInfo.setLoaderErrorInfo(ldrErrInfo); + } } /** diff --git a/src/fileinfo/file_information/file_information.cpp b/src/fileinfo/file_information/file_information.cpp index 3422ff166..390ef8288 100644 --- a/src/fileinfo/file_information/file_information.cpp +++ b/src/fileinfo/file_information/file_information.cpp @@ -2716,6 +2716,15 @@ const std::string& FileInformation::getLoaderStatusMessage() const return loaderInfo.getStatusMessage(); } +/** +* Gets loader error message. +* @return The error message of the loader. +*/ +const retdec::fileformat::LoaderErrorInfo & FileInformation::getLoaderErrorInfo() const +{ + return loaderInfo.getLoaderErrorInfo(); +} + /** * Checks whether .NET information are used. * @return @c true if it is used, otherwise @c false/ @@ -3483,6 +3492,15 @@ void FileInformation::setLoaderStatusMessage(const std::string& statusMessage) loaderInfo.setStatusMessage(statusMessage); } +/** +* Sets loader error message. +* @param statusMessage The loader error message. +*/ +void FileInformation::setLoaderErrorInfo(const retdec::fileformat::LoaderErrorInfo & ldrErrInfo) +{ + loaderInfo.setLoaderErrorInfo(ldrErrInfo); +} + /** * Sets whether .NET information are used. * @param set @c true if used, otherwise @c false. diff --git a/src/fileinfo/file_information/file_information.h b/src/fileinfo/file_information/file_information.h index 37566562b..b32aede78 100644 --- a/src/fileinfo/file_information/file_information.h +++ b/src/fileinfo/file_information/file_information.h @@ -37,7 +37,7 @@ class FileInformation std::string endianness; ///< endianness std::string manifest; ///< XML manifest std::string compactManifest; ///< compact version of XML manifest - FileHeader header; ///< file header + FileHeader header; ///< file header RichHeader richHeader; ///< rich header PdbInfo pdbInfo; ///< information about related PDB file ImportTable importTable; ///< information about imports @@ -55,7 +55,7 @@ class FileInformation std::vector malwarePatterns; ///< detected malware patterns std::vector otherPatterns; ///< other detected patterns Strings strings; ///< detected strings - retdec::utils::Maybe signatureVerified; ///< indicates whether the signature is present and if it is verified + retdec::utils::Maybe signatureVerified; ///< indicates whether the signature is present and if it is verified DotnetInfo dotnetInfo; ///< .NET information public: retdec::cpdetect::ToolInformation toolInfo; ///< detected tools @@ -400,7 +400,8 @@ class FileInformation std::string getNumberOfLoadedSegmentsStr(std::ios_base &(* format)(std::ios_base &)) const; const LoadedSegment& getLoadedSegment(std::size_t index) const; const std::string& getLoaderStatusMessage() const; - /// @} + const retdec::fileformat::LoaderErrorInfo & getLoaderErrorInfo() const; + /// @} /// @name Getters of @a dotnetInfo /// @{ @@ -492,7 +493,8 @@ class FileInformation void setSignatureVerified(bool verified); void setLoadedBaseAddress(unsigned long long baseAddress); void setLoaderStatusMessage(const std::string& statusMessage); - void setDotnetUsed(bool set); + void setLoaderErrorInfo(const retdec::fileformat::LoaderErrorInfo & ldrErrInfo); + void setDotnetUsed(bool set); void setDotnetRuntimeVersion(std::uint64_t majorVersion, std::uint64_t minorVersion); void setDotnetMetadataHeaderAddress(std::uint64_t address); void setDotnetMetadataStreamInfo(std::uint64_t streamOffset, std::uint64_t streamSize); diff --git a/src/fileinfo/file_information/file_information_types/loader_info.cpp b/src/fileinfo/file_information/file_information_types/loader_info.cpp index db6926992..7881e97fa 100644 --- a/src/fileinfo/file_information/file_information_types/loader_info.cpp +++ b/src/fileinfo/file_information/file_information_types/loader_info.cpp @@ -4,6 +4,7 @@ * @copyright (c) 2017 Avast Software, licensed under the MIT license */ +#include "retdec/fileformat/file_format/file_format.h" #include "fileinfo/file_information/file_information_types/loader_info.h" #include "fileinfo/file_information/file_information_types/type_conversions.h" @@ -85,6 +86,11 @@ const std::string& LoaderInfo::getStatusMessage() const return _statusMessage; } +const retdec::fileformat::LoaderErrorInfo & LoaderInfo::getLoaderErrorInfo() const +{ + return _ldrErrInfo; +} + void LoaderInfo::setBaseAddress(unsigned long long baseAddress) { _baseAddress = baseAddress; @@ -95,6 +101,11 @@ void LoaderInfo::setStatusMessage(const std::string& statusMessage) _statusMessage = statusMessage; } +void LoaderInfo::setLoaderErrorInfo(const retdec::fileformat::LoaderErrorInfo & ldrErrInfo) +{ + _ldrErrInfo = ldrErrInfo; +} + void LoaderInfo::addLoadedSegment(const LoadedSegment& segment) { _loadedSegments.push_back(segment); diff --git a/src/fileinfo/file_information/file_information_types/loader_info.h b/src/fileinfo/file_information/file_information_types/loader_info.h index 1a7b69d1c..7f9274cda 100644 --- a/src/fileinfo/file_information/file_information_types/loader_info.h +++ b/src/fileinfo/file_information/file_information_types/loader_info.h @@ -37,7 +37,9 @@ class LoaderInfo unsigned long long _baseAddress; std::vector _loadedSegments; std::string _statusMessage; - public: + retdec::fileformat::LoaderErrorInfo _ldrErrInfo; + +public: LoaderInfo(); ~LoaderInfo(); @@ -48,13 +50,15 @@ class LoaderInfo unsigned long long getNumberOfLoadedSegments() const; const LoadedSegment& getLoadedSegment(unsigned long long index) const; const std::string& getStatusMessage() const; - /// @} + const retdec::fileformat::LoaderErrorInfo & getLoaderErrorInfo() const; + /// @} /// @name Setters /// @{ void setBaseAddress(unsigned long long baseAddress); void setStatusMessage(const std::string& statusMessage); - /// @} + void setLoaderErrorInfo(const retdec::fileformat::LoaderErrorInfo & ldrErrInfo); + /// @} /// @name Other methods /// @{ diff --git a/src/fileinfo/file_presentation/getters/simple_getter/basic_plain_getter.cpp b/src/fileinfo/file_presentation/getters/simple_getter/basic_plain_getter.cpp index 6f04ab462..5cce3a734 100644 --- a/src/fileinfo/file_presentation/getters/simple_getter/basic_plain_getter.cpp +++ b/src/fileinfo/file_presentation/getters/simple_getter/basic_plain_getter.cpp @@ -32,6 +32,8 @@ BasicPlainGetter::~BasicPlainGetter() std::size_t BasicPlainGetter::loadInformation(std::vector &desc, std::vector &info) const { + const char * loaderErrorUserFriendly = fileinfo.getLoaderErrorInfo().loaderErrorUserFriendly; + desc.clear(); info.clear(); @@ -41,7 +43,12 @@ std::size_t BasicPlainGetter::loadInformation(std::vector &desc, st desc.push_back("File format : "); desc.push_back("File class : "); desc.push_back("File type : "); - desc.push_back("Architecture : "); + + // Save the title for loader error (if there was a loader error detected) + if(loaderErrorUserFriendly != nullptr) + desc.push_back("Loader error : "); + + desc.push_back("Architecture : "); desc.push_back("Endianness : "); desc.push_back("Image base address : "); desc.push_back("Entry point address : "); @@ -56,7 +63,12 @@ std::size_t BasicPlainGetter::loadInformation(std::vector &desc, st info.push_back(fileinfo.getFileFormat()); info.push_back(fileinfo.getFileClass()); info.push_back(fileinfo.getFileType()); - info.push_back(fileinfo.getTargetArchitecture()); + + // Save the text loader error + if(loaderErrorUserFriendly != nullptr) + info.push_back(loaderErrorUserFriendly); + + info.push_back(fileinfo.getTargetArchitecture()); info.push_back(fileinfo.getEndianness()); info.push_back(fileinfo.getImageBaseStr(hexWithPrefix)); info.push_back(fileinfo.getEpAddressStr(hexWithPrefix)); diff --git a/src/fileinfo/file_presentation/json_presentation.cpp b/src/fileinfo/file_presentation/json_presentation.cpp index 758579dce..ebfe24ac8 100644 --- a/src/fileinfo/file_presentation/json_presentation.cpp +++ b/src/fileinfo/file_presentation/json_presentation.cpp @@ -125,6 +125,26 @@ void JsonPresentation::presentErrors(Json::Value &root) const } } +/** +* Present information about Windows PE loader error +* @param root Parent node in output document +*/ +void JsonPresentation::presentLoaderError(Json::Value &root) const +{ + const retdec::fileformat::LoaderErrorInfo & ldrErrInfo = fileinfo.getLoaderErrorInfo(); + + if (ldrErrInfo.loaderErrorCode != 0) + { + Json::Value loaderErrorNode; + + loaderErrorNode["code"] = ldrErrInfo.loaderErrorCode; + loaderErrorNode["code_text"] = ldrErrInfo.loaderError; + loaderErrorNode["description"] = ldrErrInfo.loaderErrorUserFriendly; + + root["loaderError"] = loaderErrorNode; + } +} + /** * Present information about detected compilers and packers * @param root Parent node in output document @@ -570,6 +590,7 @@ bool JsonPresentation::present() Value root, jEp; root["inputFile"] = fileinfo.getPathToFile(); presentErrors(root); + presentLoaderError(root); presentSimple(BasicJsonGetter(fileinfo), root); if(presentSimple(EntryPointJsonGetter(fileinfo), jEp)) { diff --git a/src/fileinfo/file_presentation/json_presentation.h b/src/fileinfo/file_presentation/json_presentation.h index d96d92877..fda391089 100644 --- a/src/fileinfo/file_presentation/json_presentation.h +++ b/src/fileinfo/file_presentation/json_presentation.h @@ -23,6 +23,7 @@ class JsonPresentation : public FilePresentation /// @name Auxiliary presentation methods /// @{ void presentErrors(Json::Value &root) const; + void presentLoaderError(Json::Value &root) const; void presentCompiler(Json::Value &root) const; void presentLanguages(Json::Value &root) const; void presentRichHeader(Json::Value &root) const; diff --git a/src/loader/loader/image.cpp b/src/loader/loader/image.cpp index ef96592e4..f7768a976 100644 --- a/src/loader/loader/image.cpp +++ b/src/loader/loader/image.cpp @@ -421,7 +421,17 @@ const std::string& Image::getStatusMessage() const void Image::setStatusMessage(const std::string& message) { - _statusMessage = message; + _statusMessage = message; +} + +const retdec::fileformat::LoaderErrorInfo & Image::getLoaderErrorInfo() const +{ + return _ldrErrInfo; +} + +void Image::setLoaderErrorInfo(const retdec::fileformat::LoaderErrorInfo & ldrErrInfo) +{ + _ldrErrInfo = ldrErrInfo; } Segment* Image::insertSegment(std::unique_ptr segment) diff --git a/src/loader/loader/pe/pe_image.cpp b/src/loader/loader/pe/pe_image.cpp index c197f0d53..40d3cc7a5 100644 --- a/src/loader/loader/pe/pe_image.cpp +++ b/src/loader/loader/pe/pe_image.cpp @@ -35,13 +35,20 @@ PeImage::~PeImage() */ bool PeImage::load() { - const retdec::fileformat::PeFormat* peFormat = static_cast(getFileFormat()); + const retdec::fileformat::PeFormat* peFormat = static_cast(getFileFormat()); + retdec::fileformat::LoaderErrorInfo ldrErrInfo; // Load image base address from fileformat and store it into loader image unsigned long long imageBase; peFormat->getImageBaseAddress(imageBase); setBaseAddress(imageBase); + // Propagate the loader error info + if (peFormat->getLoaderErrorInfo(ldrErrInfo) != 0) + { + setLoaderErrorInfo(ldrErrInfo); + } + const auto& sections = peFormat->getSections(); for (const auto& section : sections) { From 92b69d009e095954e335547f346ee19e5562ab19 Mon Sep 17 00:00:00 2001 From: Zezula Ladislav Date: Wed, 18 Apr 2018 15:35:40 +0200 Subject: [PATCH 02/13] FileInfo now supports loader error as if it was Windows loader Fixed long loading times on samples with extremely long import/export directories --- deps/pelib/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/pelib/CMakeLists.txt b/deps/pelib/CMakeLists.txt index bf32fa214..45fdb3da9 100644 --- a/deps/pelib/CMakeLists.txt +++ b/deps/pelib/CMakeLists.txt @@ -8,7 +8,7 @@ if(CMAKE_CXX_COMPILER) endif() ExternalProject_Add(pelib-project - URL https://github.com/avast-tl/pelib/archive/e7cccb0303f1f928d2503095017faee5e643b3e4.zip + URL https://github.com/avast-tl/pelib/archive/3a5d796693d2be5e1fe69b5f554f2f5b78965c76.zip # URL https://github.com/avast-tl/pelib/archive/e93eaa7c150f4608a5d02a67f5edc9e54456fe24.zip # URL_HASH SHA256=2ffd7e89451c980a1af6d24d4f6dfbb69a660b06ad5de44c481f6431e21de394 DOWNLOAD_NAME pelib.zip From b5fda9100abcb7315aee234ae20fd6304217ff87 Mon Sep 17 00:00:00 2001 From: Zezula Ladislav Date: Thu, 19 Apr 2018 12:59:38 +0200 Subject: [PATCH 03/13] Cosmetics 4Spaces -> 1Tab --- deps/pelib/CMakeLists.txt | 2 +- .../fileformat/file_format/file_format.h | 14 +++-- .../fileformat/file_format/pe/pe_format.h | 5 +- include/retdec/loader/loader/image.h | 4 +- include/retdec/utils/conversion.h | 55 ++++++------------- src/fileformat/file_format/file_format.cpp | 13 ++++- src/fileformat/file_format/pe/pe_format.cpp | 31 ++++++----- src/fileinfo/file_detector/file_detector.cpp | 10 ++-- .../file_information/file_information.cpp | 4 +- .../file_presentation/json_presentation.cpp | 20 +++---- src/loader/loader/image.cpp | 9 +-- src/loader/loader/pe/pe_image.cpp | 9 +-- 12 files changed, 76 insertions(+), 100 deletions(-) diff --git a/deps/pelib/CMakeLists.txt b/deps/pelib/CMakeLists.txt index 45fdb3da9..a1adaf3b9 100644 --- a/deps/pelib/CMakeLists.txt +++ b/deps/pelib/CMakeLists.txt @@ -8,7 +8,7 @@ if(CMAKE_CXX_COMPILER) endif() ExternalProject_Add(pelib-project - URL https://github.com/avast-tl/pelib/archive/3a5d796693d2be5e1fe69b5f554f2f5b78965c76.zip + URL https://github.com/avast-tl/pelib/archive/05b28f32cd3955b71c618a16911467ce5321ff8f.zip # URL https://github.com/avast-tl/pelib/archive/e93eaa7c150f4608a5d02a67f5edc9e54456fe24.zip # URL_HASH SHA256=2ffd7e89451c980a1af6d24d4f6dfbb69a660b06ad5de44c481f6431e21de394 DOWNLOAD_NAME pelib.zip diff --git a/include/retdec/fileformat/file_format/file_format.h b/include/retdec/fileformat/file_format/file_format.h index 73c436c79..f7b936db7 100644 --- a/include/retdec/fileformat/file_format/file_format.h +++ b/include/retdec/fileformat/file_format/file_format.h @@ -27,13 +27,12 @@ namespace fileformat { struct LoaderErrorInfo { - LoaderErrorInfo() : loaderErrorCode(0), loaderErrorType(0), loaderError(nullptr), loaderErrorUserFriendly(nullptr) - {} + LoaderErrorInfo() : loaderErrorCode(0), loaderError(nullptr), loaderErrorUserFriendly(nullptr) + {} - std::uint32_t loaderErrorCode:24; // Loader error code, cast to uint32_t - std::uint32_t loaderErrorType:8; // Loader error code source (0 - PE loader). To be extended for ELF, Mach-O etc. - const char * loaderError; - const char * loaderErrorUserFriendly; + std::uint32_t loaderErrorCode; // Loader error code, cast to uint32_t + const char * loaderError; + const char * loaderErrorUserFriendly; }; /** @@ -82,6 +81,7 @@ class FileFormat : public retdec::utils::ByteValueStorage, private retdec::utils PdbInfo *pdbInfo; ///< information about related PDB debug file CertificateTable *certificateTable; ///< table of certificates Format fileFormat; ///< format of input file + LoaderErrorInfo _ldrErrInfo; ///< loader error (e.g. Windows loader error for PE files) bool stateIsValid; ///< internal state of instance std::vector> secHashInfo; ///< information for calculation of section table hash retdec::utils::Maybe signatureVerified; ///< indicates whether the signature is present and also verified @@ -143,7 +143,9 @@ class FileFormat : public retdec::utils::ByteValueStorage, private retdec::utils virtual std::size_t getByteLength() const override; virtual std::size_t getWordLength() const override; virtual std::size_t getNumberOfNibblesInByte() const override; + /// @} + const LoaderErrorInfo & getLoaderErrorInfo() const; /// @name Detection methods /// @{ diff --git a/include/retdec/fileformat/file_format/pe/pe_format.h b/include/retdec/fileformat/file_format/pe/pe_format.h index ea87f38e6..cd11a5f50 100644 --- a/include/retdec/fileformat/file_format/pe/pe_format.h +++ b/include/retdec/fileformat/file_format/pe/pe_format.h @@ -44,6 +44,7 @@ class PeFormat : public FileFormat /// @name Initialization methods /// @{ + void initLoaderErrorInfo(); void initStructures(); /// @} @@ -147,8 +148,8 @@ class PeFormat : public FileFormat std::size_t getSizeOfHeapCommit() const; std::size_t getNumberOfDataDirectories() const; std::size_t getDeclaredNumberOfDataDirectories() const; - std::size_t getLoaderErrorInfo(retdec::fileformat::LoaderErrorInfo & ldrErrInfo) const; - int getPeClass() const; + + int getPeClass() const; bool isDotNet() const; bool isPackedDotNet() const; bool isVisualBasic(unsigned long long &version) const; diff --git a/include/retdec/loader/loader/image.h b/include/retdec/loader/loader/image.h index 6ab5db1b4..7136c4dad 100644 --- a/include/retdec/loader/loader/image.h +++ b/include/retdec/loader/loader/image.h @@ -74,7 +74,7 @@ class Image : public retdec::utils::ByteValueStorage std::pair getRawSegmentData(std::uint64_t address) const; const std::string& getStatusMessage() const; - const retdec::fileformat::LoaderErrorInfo & getLoaderErrorInfo() const; + const retdec::fileformat::LoaderErrorInfo & getLoaderErrorInfo() const; protected: Segment* insertSegment(std::unique_ptr segment); @@ -83,7 +83,6 @@ class Image : public retdec::utils::ByteValueStorage void sortSegments(); void setStatusMessage(const std::string& message); - void setLoaderErrorInfo(const retdec::fileformat::LoaderErrorInfo & ldrErrInfo); private: const Segment* _getSegment(std::size_t index) const; @@ -95,7 +94,6 @@ class Image : public retdec::utils::ByteValueStorage std::vector> _segments; std::uint64_t _baseAddress; NameGenerator _namelessSegNameGen; - retdec::fileformat::LoaderErrorInfo _ldrErrInfo; std::string _statusMessage; }; diff --git a/include/retdec/utils/conversion.h b/include/retdec/utils/conversion.h index 6961d6d7e..95fe70f39 100644 --- a/include/retdec/utils/conversion.h +++ b/include/retdec/utils/conversion.h @@ -205,47 +205,24 @@ template void bytesToHexString(const N *data, std::size_t dataSize, size = (size == 0 || offset + size > dataSize) ? dataSize - offset : size; } - // Sample: 4A2A008CF1AEE9BA49D8D1DAA22D8E868365ACE633823D464478239F27ED4F18 - // Tool: redec-fileinfo.exe, Debug, x64, data = image, dataSize = 0xE1BC00 - // This code takes 0.106 seconds to convert (measured in VS 2015 IDE) - const char * intToHex = uppercase ? "0123456789ABCDEF" : "0123456789abcdef"; - char * hexString = new char[(size * 2) + 1]; - if (hexString != nullptr) - { - char * hexStringPtr = hexString; - - // Convert to hexa byte-by-byte. No reallocations - for (std::size_t i = 0; i < size; ++i, hexStringPtr += 2) - { - std::uint8_t oneByte = data[offset + i]; - - hexStringPtr[0] = intToHex[(oneByte >> 0x04) & 0x0F]; - hexStringPtr[1] = intToHex[(oneByte >> 0x00) & 0x0F]; - } - - // Assign the hexa string to the result - hexStringPtr[0] = 0; - result = hexString; - - // Free the working string - delete[] hexString; - } - -/* - // Sample: 4A2A008CF1AEE9BA49D8D1DAA22D8E868365ACE633823D464478239F27ED4F18 - // Tool: redec-fileinfo.exe, Debug, x64, data = image, dataSize = 0xE1BC00 - // This code takes 40 seconds to convert (measured in VS 2015 IDE) - result.clear(); - result.reserve(size * 2); - std::ostringstream oStr; - - for(std::size_t i = 0; i < size; ++i) + // Sample: 4A2A008CF1AEE9BA49D8D1DAA22D8E868365ACE633823D464478239F27ED4F18 + // Tool: redec-fileinfo.exe, Debug, x64, data = image, dataSize = 0xE1BC00 + // Optimized: This code now takes 0.106 seconds to convert (measured in VS 2015 IDE) + // (down from about 40 seconds) + const char * intToHex = uppercase ? "0123456789ABCDEF" : "0123456789abcdef"; + std::size_t hexIndex = 0; + + // Reserve the necessary space for the hexa string + result.resize(size * 2); + + // Convert to hexa byte-by-byte. No reallocations + for (std::size_t i = 0; i < size; ++i, hexIndex += 2) { - byteToHexString(oStr, data[offset + i], uppercase); - } + std::uint8_t oneByte = data[offset + i]; - result = oStr.str(); -*/ + result[hexIndex + 0] = intToHex[(oneByte >> 0x04) & 0x0F]; + result[hexIndex + 1] = intToHex[(oneByte >> 0x00) & 0x0F]; + } } /** diff --git a/src/fileformat/file_format/file_format.cpp b/src/fileformat/file_format/file_format.cpp index 329d4cdcc..97b3923c5 100644 --- a/src/fileformat/file_format/file_format.cpp +++ b/src/fileformat/file_format/file_format.cpp @@ -117,7 +117,7 @@ bool isAddressFromRegion(const SecSeg *actualRegion, const SecSeg *newRegion, st * @param loadFlags Load flags */ FileFormat::FileFormat(std::istream &inputStream, LoadFlags loadFlags) : loadedBytes(&bytes), - loadFlags(loadFlags), fileStream(inputStream) + loadFlags(loadFlags), fileStream(inputStream), _ldrErrInfo() { stateIsValid = !inputStream.fail(); init(); @@ -129,7 +129,7 @@ FileFormat::FileFormat(std::istream &inputStream, LoadFlags loadFlags) : loadedB * @param loadFlags Load flags */ FileFormat::FileFormat(std::string pathToFile, LoadFlags loadFlags) : loadedBytes(&bytes), - loadFlags(loadFlags), filePath(pathToFile), fileStream(auxStream) + loadFlags(loadFlags), filePath(pathToFile), fileStream(auxStream), _ldrErrInfo() { auxStream.open(filePath, std::ifstream::binary); stateIsValid = auxStream.is_open(); @@ -700,6 +700,15 @@ std::size_t FileFormat::getNumberOfNibblesInByte() const return !getNibbleLength() ? 0 : !(getByteLength() % getNibbleLength()) ? getByteLength() / getNibbleLength() : 0; } +/** +* Get reference to the loader error info +* @return The LoaderErrorInfo structire +*/ +const LoaderErrorInfo & FileFormat::getLoaderErrorInfo() const +{ + return _ldrErrInfo; +} + /** * Find out if target architecture is x86 * @return @c true if target architecture is x86, @c false otherwise diff --git a/src/fileformat/file_format/pe/pe_format.cpp b/src/fileformat/file_format/pe/pe_format.cpp index d39c74ac4..e581a6e2d 100644 --- a/src/fileformat/file_format/pe/pe_format.cpp +++ b/src/fileformat/file_format/pe/pe_format.cpp @@ -305,6 +305,18 @@ PeFormat::~PeFormat() delete formatParser; } +/** +* Init information from PE loader +*/ +void PeFormat::initLoaderErrorInfo() +{ + PeLib::LoaderError ldrError = file->loaderError(); + + _ldrErrInfo.loaderErrorCode = static_cast(ldrError); + _ldrErrInfo.loaderError = getLoaderErrorString(ldrError, false); + _ldrErrInfo.loaderErrorUserFriendly = getLoaderErrorString(ldrError, true); +} + /** * Init internal structures */ @@ -332,6 +344,10 @@ void PeFormat::initStructures() file->readResourceDirectory(); file->readSecurityDirectory(); file->readComHeaderDirectory(); + + // Fill-in the loader error info from PE file + initLoaderErrorInfo(); + mzHeader = file->mzHeader(); switch((peClass = getFileType(filePath))) { @@ -2299,21 +2315,6 @@ std::size_t PeFormat::getDeclaredNumberOfDataDirectories() const return formatParser->getDeclaredNumberOfDataDirectories(); } -/** -* Get the error code that Windows loader would report -* @return Windows loader error code -*/ -std::size_t PeFormat::getLoaderErrorInfo(retdec::fileformat::LoaderErrorInfo & ldrErrInfo) const -{ - PeLib::LoaderError ldrError = file->loaderError(); - - ldrErrInfo.loaderErrorCode = (std::uint32_t)ldrError; - ldrErrInfo.loaderError = getLoaderErrorString(ldrError, false); - ldrErrInfo.loaderErrorUserFriendly = getLoaderErrorString(ldrError, true); - - return ldrErrInfo.loaderErrorCode; - } - /** * Get class of PE file * @return PeLib::PEFILE32 if file is 32-bit PE file, PeLib::PEFILE64 if file is diff --git a/src/fileinfo/file_detector/file_detector.cpp b/src/fileinfo/file_detector/file_detector.cpp index 59408b48e..e9b2d0899 100644 --- a/src/fileinfo/file_detector/file_detector.cpp +++ b/src/fileinfo/file_detector/file_detector.cpp @@ -267,11 +267,11 @@ void FileDetector::getLoaderInfo() fileInfo.setLoaderStatusMessage(image->getStatusMessage()); } - const retdec::fileformat::LoaderErrorInfo & ldrErrInfo = image->getLoaderErrorInfo(); - if (ldrErrInfo.loaderErrorCode != 0) - { - fileInfo.setLoaderErrorInfo(ldrErrInfo); - } + auto ldrErrInfo = image->getLoaderErrorInfo(); + if (ldrErrInfo.loaderErrorCode != 0) + { + fileInfo.setLoaderErrorInfo(ldrErrInfo); + } } /** diff --git a/src/fileinfo/file_information/file_information.cpp b/src/fileinfo/file_information/file_information.cpp index 390ef8288..fa2749241 100644 --- a/src/fileinfo/file_information/file_information.cpp +++ b/src/fileinfo/file_information/file_information.cpp @@ -2722,7 +2722,7 @@ const std::string& FileInformation::getLoaderStatusMessage() const */ const retdec::fileformat::LoaderErrorInfo & FileInformation::getLoaderErrorInfo() const { - return loaderInfo.getLoaderErrorInfo(); + return loaderInfo.getLoaderErrorInfo(); } /** @@ -3498,7 +3498,7 @@ void FileInformation::setLoaderStatusMessage(const std::string& statusMessage) */ void FileInformation::setLoaderErrorInfo(const retdec::fileformat::LoaderErrorInfo & ldrErrInfo) { - loaderInfo.setLoaderErrorInfo(ldrErrInfo); + loaderInfo.setLoaderErrorInfo(ldrErrInfo); } /** diff --git a/src/fileinfo/file_presentation/json_presentation.cpp b/src/fileinfo/file_presentation/json_presentation.cpp index ebfe24ac8..7b0bc4287 100644 --- a/src/fileinfo/file_presentation/json_presentation.cpp +++ b/src/fileinfo/file_presentation/json_presentation.cpp @@ -131,18 +131,18 @@ void JsonPresentation::presentErrors(Json::Value &root) const */ void JsonPresentation::presentLoaderError(Json::Value &root) const { - const retdec::fileformat::LoaderErrorInfo & ldrErrInfo = fileinfo.getLoaderErrorInfo(); + auto ldrErrInfo = fileinfo.getLoaderErrorInfo(); - if (ldrErrInfo.loaderErrorCode != 0) - { - Json::Value loaderErrorNode; + if (ldrErrInfo.loaderErrorCode != 0) + { + Json::Value loaderErrorNode; - loaderErrorNode["code"] = ldrErrInfo.loaderErrorCode; - loaderErrorNode["code_text"] = ldrErrInfo.loaderError; - loaderErrorNode["description"] = ldrErrInfo.loaderErrorUserFriendly; + loaderErrorNode["code"] = ldrErrInfo.loaderErrorCode; + loaderErrorNode["code_text"] = ldrErrInfo.loaderError; + loaderErrorNode["description"] = ldrErrInfo.loaderErrorUserFriendly; - root["loaderError"] = loaderErrorNode; - } + root["loaderError"] = loaderErrorNode; + } } /** @@ -590,7 +590,7 @@ bool JsonPresentation::present() Value root, jEp; root["inputFile"] = fileinfo.getPathToFile(); presentErrors(root); - presentLoaderError(root); + presentLoaderError(root); presentSimple(BasicJsonGetter(fileinfo), root); if(presentSimple(EntryPointJsonGetter(fileinfo), jEp)) { diff --git a/src/loader/loader/image.cpp b/src/loader/loader/image.cpp index f7768a976..f58449fd9 100644 --- a/src/loader/loader/image.cpp +++ b/src/loader/loader/image.cpp @@ -421,17 +421,12 @@ const std::string& Image::getStatusMessage() const void Image::setStatusMessage(const std::string& message) { - _statusMessage = message; + _statusMessage = message; } const retdec::fileformat::LoaderErrorInfo & Image::getLoaderErrorInfo() const { - return _ldrErrInfo; -} - -void Image::setLoaderErrorInfo(const retdec::fileformat::LoaderErrorInfo & ldrErrInfo) -{ - _ldrErrInfo = ldrErrInfo; + return getFileFormat()->getLoaderErrorInfo(); } Segment* Image::insertSegment(std::unique_ptr segment) diff --git a/src/loader/loader/pe/pe_image.cpp b/src/loader/loader/pe/pe_image.cpp index 40d3cc7a5..c197f0d53 100644 --- a/src/loader/loader/pe/pe_image.cpp +++ b/src/loader/loader/pe/pe_image.cpp @@ -35,20 +35,13 @@ PeImage::~PeImage() */ bool PeImage::load() { - const retdec::fileformat::PeFormat* peFormat = static_cast(getFileFormat()); - retdec::fileformat::LoaderErrorInfo ldrErrInfo; + const retdec::fileformat::PeFormat* peFormat = static_cast(getFileFormat()); // Load image base address from fileformat and store it into loader image unsigned long long imageBase; peFormat->getImageBaseAddress(imageBase); setBaseAddress(imageBase); - // Propagate the loader error info - if (peFormat->getLoaderErrorInfo(ldrErrInfo) != 0) - { - setLoaderErrorInfo(ldrErrInfo); - } - const auto& sections = peFormat->getSections(); for (const auto& section : sections) { From 6cb9ace8b732716ffed8b3d10fc611b76e2bff40 Mon Sep 17 00:00:00 2001 From: Zezula Ladislav Date: Thu, 19 Apr 2018 13:06:33 +0200 Subject: [PATCH 04/13] 4spaces->1tab --- .../file_information/file_information.h | 10 +++++----- .../file_information_types/loader_info.cpp | 4 ++-- .../file_information_types/loader_info.h | 10 +++++----- .../simple_getter/basic_plain_getter.cpp | 18 +++++++++--------- .../file_presentation/json_presentation.h | 2 +- 5 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/fileinfo/file_information/file_information.h b/src/fileinfo/file_information/file_information.h index b32aede78..fc740f10f 100644 --- a/src/fileinfo/file_information/file_information.h +++ b/src/fileinfo/file_information/file_information.h @@ -37,7 +37,7 @@ class FileInformation std::string endianness; ///< endianness std::string manifest; ///< XML manifest std::string compactManifest; ///< compact version of XML manifest - FileHeader header; ///< file header + FileHeader header; ///< file header RichHeader richHeader; ///< rich header PdbInfo pdbInfo; ///< information about related PDB file ImportTable importTable; ///< information about imports @@ -400,8 +400,8 @@ class FileInformation std::string getNumberOfLoadedSegmentsStr(std::ios_base &(* format)(std::ios_base &)) const; const LoadedSegment& getLoadedSegment(std::size_t index) const; const std::string& getLoaderStatusMessage() const; - const retdec::fileformat::LoaderErrorInfo & getLoaderErrorInfo() const; - /// @} + const retdec::fileformat::LoaderErrorInfo & getLoaderErrorInfo() const; + /// @} /// @name Getters of @a dotnetInfo /// @{ @@ -493,8 +493,8 @@ class FileInformation void setSignatureVerified(bool verified); void setLoadedBaseAddress(unsigned long long baseAddress); void setLoaderStatusMessage(const std::string& statusMessage); - void setLoaderErrorInfo(const retdec::fileformat::LoaderErrorInfo & ldrErrInfo); - void setDotnetUsed(bool set); + void setLoaderErrorInfo(const retdec::fileformat::LoaderErrorInfo & ldrErrInfo); + void setDotnetUsed(bool set); void setDotnetRuntimeVersion(std::uint64_t majorVersion, std::uint64_t minorVersion); void setDotnetMetadataHeaderAddress(std::uint64_t address); void setDotnetMetadataStreamInfo(std::uint64_t streamOffset, std::uint64_t streamSize); diff --git a/src/fileinfo/file_information/file_information_types/loader_info.cpp b/src/fileinfo/file_information/file_information_types/loader_info.cpp index 7881e97fa..f00db0b66 100644 --- a/src/fileinfo/file_information/file_information_types/loader_info.cpp +++ b/src/fileinfo/file_information/file_information_types/loader_info.cpp @@ -88,7 +88,7 @@ const std::string& LoaderInfo::getStatusMessage() const const retdec::fileformat::LoaderErrorInfo & LoaderInfo::getLoaderErrorInfo() const { - return _ldrErrInfo; + return _ldrErrInfo; } void LoaderInfo::setBaseAddress(unsigned long long baseAddress) @@ -103,7 +103,7 @@ void LoaderInfo::setStatusMessage(const std::string& statusMessage) void LoaderInfo::setLoaderErrorInfo(const retdec::fileformat::LoaderErrorInfo & ldrErrInfo) { - _ldrErrInfo = ldrErrInfo; + _ldrErrInfo = ldrErrInfo; } void LoaderInfo::addLoadedSegment(const LoadedSegment& segment) diff --git a/src/fileinfo/file_information/file_information_types/loader_info.h b/src/fileinfo/file_information/file_information_types/loader_info.h index 7f9274cda..5894a108a 100644 --- a/src/fileinfo/file_information/file_information_types/loader_info.h +++ b/src/fileinfo/file_information/file_information_types/loader_info.h @@ -37,7 +37,7 @@ class LoaderInfo unsigned long long _baseAddress; std::vector _loadedSegments; std::string _statusMessage; - retdec::fileformat::LoaderErrorInfo _ldrErrInfo; + retdec::fileformat::LoaderErrorInfo _ldrErrInfo; public: LoaderInfo(); @@ -50,15 +50,15 @@ class LoaderInfo unsigned long long getNumberOfLoadedSegments() const; const LoadedSegment& getLoadedSegment(unsigned long long index) const; const std::string& getStatusMessage() const; - const retdec::fileformat::LoaderErrorInfo & getLoaderErrorInfo() const; - /// @} + const retdec::fileformat::LoaderErrorInfo & getLoaderErrorInfo() const; + /// @} /// @name Setters /// @{ void setBaseAddress(unsigned long long baseAddress); void setStatusMessage(const std::string& statusMessage); - void setLoaderErrorInfo(const retdec::fileformat::LoaderErrorInfo & ldrErrInfo); - /// @} + void setLoaderErrorInfo(const retdec::fileformat::LoaderErrorInfo & ldrErrInfo); + /// @} /// @name Other methods /// @{ diff --git a/src/fileinfo/file_presentation/getters/simple_getter/basic_plain_getter.cpp b/src/fileinfo/file_presentation/getters/simple_getter/basic_plain_getter.cpp index 5cce3a734..990fcad3e 100644 --- a/src/fileinfo/file_presentation/getters/simple_getter/basic_plain_getter.cpp +++ b/src/fileinfo/file_presentation/getters/simple_getter/basic_plain_getter.cpp @@ -32,7 +32,7 @@ BasicPlainGetter::~BasicPlainGetter() std::size_t BasicPlainGetter::loadInformation(std::vector &desc, std::vector &info) const { - const char * loaderErrorUserFriendly = fileinfo.getLoaderErrorInfo().loaderErrorUserFriendly; + const char * loaderErrorUserFriendly = fileinfo.getLoaderErrorInfo().loaderErrorUserFriendly; desc.clear(); info.clear(); @@ -44,11 +44,11 @@ std::size_t BasicPlainGetter::loadInformation(std::vector &desc, st desc.push_back("File class : "); desc.push_back("File type : "); - // Save the title for loader error (if there was a loader error detected) - if(loaderErrorUserFriendly != nullptr) - desc.push_back("Loader error : "); + // Save the title for loader error (if there was a loader error detected) + if(loaderErrorUserFriendly != nullptr) + desc.push_back("Loader error : "); - desc.push_back("Architecture : "); + desc.push_back("Architecture : "); desc.push_back("Endianness : "); desc.push_back("Image base address : "); desc.push_back("Entry point address : "); @@ -64,11 +64,11 @@ std::size_t BasicPlainGetter::loadInformation(std::vector &desc, st info.push_back(fileinfo.getFileClass()); info.push_back(fileinfo.getFileType()); - // Save the text loader error - if(loaderErrorUserFriendly != nullptr) - info.push_back(loaderErrorUserFriendly); + // Save the text loader error + if(loaderErrorUserFriendly != nullptr) + info.push_back(loaderErrorUserFriendly); - info.push_back(fileinfo.getTargetArchitecture()); + info.push_back(fileinfo.getTargetArchitecture()); info.push_back(fileinfo.getEndianness()); info.push_back(fileinfo.getImageBaseStr(hexWithPrefix)); info.push_back(fileinfo.getEpAddressStr(hexWithPrefix)); diff --git a/src/fileinfo/file_presentation/json_presentation.h b/src/fileinfo/file_presentation/json_presentation.h index fda391089..2adb75979 100644 --- a/src/fileinfo/file_presentation/json_presentation.h +++ b/src/fileinfo/file_presentation/json_presentation.h @@ -23,7 +23,7 @@ class JsonPresentation : public FilePresentation /// @name Auxiliary presentation methods /// @{ void presentErrors(Json::Value &root) const; - void presentLoaderError(Json::Value &root) const; + void presentLoaderError(Json::Value &root) const; void presentCompiler(Json::Value &root) const; void presentLanguages(Json::Value &root) const; void presentRichHeader(Json::Value &root) const; From 45aac501bd7881d0efab2adf8f311bf0071118aa Mon Sep 17 00:00:00 2001 From: Zezula Ladislav Date: Mon, 23 Apr 2018 14:34:01 +0200 Subject: [PATCH 05/13] Final branch of pelib included Re-ran regression tests for fileinfo --- deps/pelib/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/pelib/CMakeLists.txt b/deps/pelib/CMakeLists.txt index a1adaf3b9..0f319ea6a 100644 --- a/deps/pelib/CMakeLists.txt +++ b/deps/pelib/CMakeLists.txt @@ -8,7 +8,7 @@ if(CMAKE_CXX_COMPILER) endif() ExternalProject_Add(pelib-project - URL https://github.com/avast-tl/pelib/archive/05b28f32cd3955b71c618a16911467ce5321ff8f.zip + URL https://github.com/avast-tl/pelib/archive/19f9a34c0dd10657303e15f7a9d03de9d177e6be.zip # URL https://github.com/avast-tl/pelib/archive/e93eaa7c150f4608a5d02a67f5edc9e54456fe24.zip # URL_HASH SHA256=2ffd7e89451c980a1af6d24d4f6dfbb69a660b06ad5de44c481f6431e21de394 DOWNLOAD_NAME pelib.zip From 440dddeba61f4b5a11490845001573d1ffd7c936 Mon Sep 17 00:00:00 2001 From: Zezula Ladislav Date: Tue, 24 Apr 2018 07:51:09 +0200 Subject: [PATCH 06/13] Cosmetic changes --- deps/pelib/CMakeLists.txt | 2 -- src/fileinfo/file_information/file_information.h | 4 ++-- .../file_information/file_information_types/loader_info.h | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/deps/pelib/CMakeLists.txt b/deps/pelib/CMakeLists.txt index 0f319ea6a..fff1bafbb 100644 --- a/deps/pelib/CMakeLists.txt +++ b/deps/pelib/CMakeLists.txt @@ -9,8 +9,6 @@ endif() ExternalProject_Add(pelib-project URL https://github.com/avast-tl/pelib/archive/19f9a34c0dd10657303e15f7a9d03de9d177e6be.zip -# URL https://github.com/avast-tl/pelib/archive/e93eaa7c150f4608a5d02a67f5edc9e54456fe24.zip -# URL_HASH SHA256=2ffd7e89451c980a1af6d24d4f6dfbb69a660b06ad5de44c481f6431e21de394 DOWNLOAD_NAME pelib.zip CMAKE_ARGS # This does not work on MSVC, but may be useful on Linux. diff --git a/src/fileinfo/file_information/file_information.h b/src/fileinfo/file_information/file_information.h index fc740f10f..be76cf0b1 100644 --- a/src/fileinfo/file_information/file_information.h +++ b/src/fileinfo/file_information/file_information.h @@ -37,7 +37,7 @@ class FileInformation std::string endianness; ///< endianness std::string manifest; ///< XML manifest std::string compactManifest; ///< compact version of XML manifest - FileHeader header; ///< file header + FileHeader header; ///< file header RichHeader richHeader; ///< rich header PdbInfo pdbInfo; ///< information about related PDB file ImportTable importTable; ///< information about imports @@ -400,7 +400,7 @@ class FileInformation std::string getNumberOfLoadedSegmentsStr(std::ios_base &(* format)(std::ios_base &)) const; const LoadedSegment& getLoadedSegment(std::size_t index) const; const std::string& getLoaderStatusMessage() const; - const retdec::fileformat::LoaderErrorInfo & getLoaderErrorInfo() const; + const retdec::fileformat::LoaderErrorInfo & getLoaderErrorInfo() const; /// @} /// @name Getters of @a dotnetInfo diff --git a/src/fileinfo/file_information/file_information_types/loader_info.h b/src/fileinfo/file_information/file_information_types/loader_info.h index 5894a108a..ce4c74de6 100644 --- a/src/fileinfo/file_information/file_information_types/loader_info.h +++ b/src/fileinfo/file_information/file_information_types/loader_info.h @@ -39,7 +39,7 @@ class LoaderInfo std::string _statusMessage; retdec::fileformat::LoaderErrorInfo _ldrErrInfo; -public: + public: LoaderInfo(); ~LoaderInfo(); From 8669c5a40b438d86f6174e69f13b9ecdc81b356a Mon Sep 17 00:00:00 2001 From: Zezula Ladislav Date: Wed, 25 Apr 2018 12:07:23 +0200 Subject: [PATCH 07/13] Loader error is properly propagated even if Image class is not created --- deps/pelib/CMakeLists.txt | 3 ++- src/fileinfo/file_detector/file_detector.cpp | 14 ++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/deps/pelib/CMakeLists.txt b/deps/pelib/CMakeLists.txt index fff1bafbb..c242b8063 100644 --- a/deps/pelib/CMakeLists.txt +++ b/deps/pelib/CMakeLists.txt @@ -8,7 +8,8 @@ if(CMAKE_CXX_COMPILER) endif() ExternalProject_Add(pelib-project - URL https://github.com/avast-tl/pelib/archive/19f9a34c0dd10657303e15f7a9d03de9d177e6be.zip + URL https://github.com/avast-tl/pelib/archive/574de5912f7e07e981ef079639fb003aaa7490b5.zip +# URL https://github.com/avast-tl/pelib/archive/19f9a34c0dd10657303e15f7a9d03de9d177e6be.zip DOWNLOAD_NAME pelib.zip CMAKE_ARGS # This does not work on MSVC, but may be useful on Linux. diff --git a/src/fileinfo/file_detector/file_detector.cpp b/src/fileinfo/file_detector/file_detector.cpp index e9b2d0899..2e59feded 100644 --- a/src/fileinfo/file_detector/file_detector.cpp +++ b/src/fileinfo/file_detector/file_detector.cpp @@ -245,8 +245,16 @@ void FileDetector::getCertificates() /** * Get loader information */ + void FileDetector::getLoaderInfo() { + // Propagate loader error no matter if the Image pointer will be created or not + auto ldrErrInfo = getFileParser()->getLoaderErrorInfo(); + if (ldrErrInfo.loaderErrorCode != 0) + { + fileInfo.setLoaderErrorInfo(ldrErrInfo); + } + std::unique_ptr image = retdec::loader::createImage(fileParser); if(!image) { @@ -266,12 +274,6 @@ void FileDetector::getLoaderInfo() { fileInfo.setLoaderStatusMessage(image->getStatusMessage()); } - - auto ldrErrInfo = image->getLoaderErrorInfo(); - if (ldrErrInfo.loaderErrorCode != 0) - { - fileInfo.setLoaderErrorInfo(ldrErrInfo); - } } /** From ba7787d4ded107aa4409fa9adc69da1e4060cf77 Mon Sep 17 00:00:00 2001 From: Zezula Ladislav Date: Thu, 26 Apr 2018 14:51:24 +0200 Subject: [PATCH 08/13] Fixed loading delayed imports by ordinal --- deps/pelib/CMakeLists.txt | 3 +-- include/retdec/fileformat/file_format/pe/pe_template.h | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/deps/pelib/CMakeLists.txt b/deps/pelib/CMakeLists.txt index c242b8063..32a9325e3 100644 --- a/deps/pelib/CMakeLists.txt +++ b/deps/pelib/CMakeLists.txt @@ -8,8 +8,7 @@ if(CMAKE_CXX_COMPILER) endif() ExternalProject_Add(pelib-project - URL https://github.com/avast-tl/pelib/archive/574de5912f7e07e981ef079639fb003aaa7490b5.zip -# URL https://github.com/avast-tl/pelib/archive/19f9a34c0dd10657303e15f7a9d03de9d177e6be.zip + URL https://github.com/avast-tl/pelib/archive/master.zip DOWNLOAD_NAME pelib.zip CMAKE_ARGS # This does not work on MSVC, but may be useful on Linux. diff --git a/include/retdec/fileformat/file_format/pe/pe_template.h b/include/retdec/fileformat/file_format/pe/pe_template.h index 77137ee04..4c35a65bb 100644 --- a/include/retdec/fileformat/file_format/pe/pe_template.h +++ b/include/retdec/fileformat/file_format/pe/pe_template.h @@ -579,7 +579,7 @@ template bool peDelayImport(const PeLib::PeHeaderT &peHeader, import.setAddress(peImageBase(peHeader) + function->address.Value); import.setLibraryIndex(fileIndex); import.invalidateOrdinalNumber(); - if(library->ordinalNumbersAreValid()) + if(library->ordinalNumbersAreValid() && function->hint != 0) { import.setOrdinalNumber(function->hint); } From 0e05056668a60611270546265ee2c5b0fdaadc69 Mon Sep 17 00:00:00 2001 From: Zezula Ladislav Date: Thu, 26 Apr 2018 15:02:24 +0200 Subject: [PATCH 09/13] Fixed whitespaces --- src/fileinfo/file_information/file_information.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fileinfo/file_information/file_information.h b/src/fileinfo/file_information/file_information.h index be76cf0b1..40892bf54 100644 --- a/src/fileinfo/file_information/file_information.h +++ b/src/fileinfo/file_information/file_information.h @@ -493,7 +493,7 @@ class FileInformation void setSignatureVerified(bool verified); void setLoadedBaseAddress(unsigned long long baseAddress); void setLoaderStatusMessage(const std::string& statusMessage); - void setLoaderErrorInfo(const retdec::fileformat::LoaderErrorInfo & ldrErrInfo); + void setLoaderErrorInfo(const retdec::fileformat::LoaderErrorInfo & ldrErrInfo); void setDotnetUsed(bool set); void setDotnetRuntimeVersion(std::uint64_t majorVersion, std::uint64_t minorVersion); void setDotnetMetadataHeaderAddress(std::uint64_t address); From cab945158749486bd6a92ced84237678963a1291 Mon Sep 17 00:00:00 2001 From: Zezula Ladislav Date: Mon, 30 Apr 2018 11:09:21 +0200 Subject: [PATCH 10/13] Fixed version of PELIB Fixed spaces --- deps/pelib/CMakeLists.txt | 3 ++- include/retdec/fileformat/file_format/file_format.h | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/deps/pelib/CMakeLists.txt b/deps/pelib/CMakeLists.txt index 32a9325e3..ec912e039 100644 --- a/deps/pelib/CMakeLists.txt +++ b/deps/pelib/CMakeLists.txt @@ -8,7 +8,8 @@ if(CMAKE_CXX_COMPILER) endif() ExternalProject_Add(pelib-project - URL https://github.com/avast-tl/pelib/archive/master.zip + URL https://github.com/avast-tl/pelib/archive/e653527f4b2b6130fb00225bb6d0392e49ee7080.zip + URL_HASH SHA256=fc8d6207e2046bfa51ba588b14fdfa22c756ce35338e6b8036889a7110465cf1 DOWNLOAD_NAME pelib.zip CMAKE_ARGS # This does not work on MSVC, but may be useful on Linux. diff --git a/include/retdec/fileformat/file_format/file_format.h b/include/retdec/fileformat/file_format/file_format.h index f7b936db7..7b4259a44 100644 --- a/include/retdec/fileformat/file_format/file_format.h +++ b/include/retdec/fileformat/file_format/file_format.h @@ -30,7 +30,7 @@ struct LoaderErrorInfo LoaderErrorInfo() : loaderErrorCode(0), loaderError(nullptr), loaderErrorUserFriendly(nullptr) {} - std::uint32_t loaderErrorCode; // Loader error code, cast to uint32_t + std::uint32_t loaderErrorCode; // Loader error code, cast to uint32_t const char * loaderError; const char * loaderErrorUserFriendly; }; @@ -81,11 +81,11 @@ class FileFormat : public retdec::utils::ByteValueStorage, private retdec::utils PdbInfo *pdbInfo; ///< information about related PDB debug file CertificateTable *certificateTable; ///< table of certificates Format fileFormat; ///< format of input file - LoaderErrorInfo _ldrErrInfo; ///< loader error (e.g. Windows loader error for PE files) + LoaderErrorInfo _ldrErrInfo; ///< loader error (e.g. Windows loader error for PE files) bool stateIsValid; ///< internal state of instance std::vector> secHashInfo; ///< information for calculation of section table hash - retdec::utils::Maybe signatureVerified; ///< indicates whether the signature is present and also verified - retdec::utils::RangeContainer nonDecodableRanges; ///< Address ranges which should not be decoded for instructions. + retdec::utils::Maybe signatureVerified; ///< indicates whether the signature is present and also verified + retdec::utils::RangeContainer nonDecodableRanges; ///< Address ranges which should not be decoded for instructions. /// @name Clear methods /// @{ From 93fb2dfc612a38322621ef0ab20151a12e1380e6 Mon Sep 17 00:00:00 2001 From: Zezula Ladislav Date: Thu, 3 May 2018 10:13:58 +0200 Subject: [PATCH 11/13] Added SHA256 URL for the final commit --- deps/pelib/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deps/pelib/CMakeLists.txt b/deps/pelib/CMakeLists.txt index ec912e039..dbd1baa07 100644 --- a/deps/pelib/CMakeLists.txt +++ b/deps/pelib/CMakeLists.txt @@ -8,8 +8,8 @@ if(CMAKE_CXX_COMPILER) endif() ExternalProject_Add(pelib-project - URL https://github.com/avast-tl/pelib/archive/e653527f4b2b6130fb00225bb6d0392e49ee7080.zip - URL_HASH SHA256=fc8d6207e2046bfa51ba588b14fdfa22c756ce35338e6b8036889a7110465cf1 + URL https://github.com/avast-tl/pelib/archive/8ee59d45ee11124174301111367cd5eaeb0a7733.zip + URL_HASH SHA256=197322958879dc96f87a55a2d7bb9118611657f44a3686082b5b6b5df2fd51f0 DOWNLOAD_NAME pelib.zip CMAKE_ARGS # This does not work on MSVC, but may be useful on Linux. From 67e62a2fbab214ad1f2f7eaf06115c0333d2fd13 Mon Sep 17 00:00:00 2001 From: Zezula Ladislav Date: Thu, 3 May 2018 12:42:09 +0200 Subject: [PATCH 12/13] Fixed URL hash for PELIB --- deps/pelib/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deps/pelib/CMakeLists.txt b/deps/pelib/CMakeLists.txt index dbd1baa07..e6dfae89b 100644 --- a/deps/pelib/CMakeLists.txt +++ b/deps/pelib/CMakeLists.txt @@ -9,7 +9,7 @@ endif() ExternalProject_Add(pelib-project URL https://github.com/avast-tl/pelib/archive/8ee59d45ee11124174301111367cd5eaeb0a7733.zip - URL_HASH SHA256=197322958879dc96f87a55a2d7bb9118611657f44a3686082b5b6b5df2fd51f0 + URL_HASH SHA256=309d29f9e729d76de5ab4f2a6fb37a999257d3e3aa88ff99cb1195c2c6be8da0 DOWNLOAD_NAME pelib.zip CMAKE_ARGS # This does not work on MSVC, but may be useful on Linux. From 8cf198fe8906383a91d1b1d87e1316c8317c0b49 Mon Sep 17 00:00:00 2001 From: Zezula Ladislav Date: Thu, 3 May 2018 13:19:06 +0200 Subject: [PATCH 13/13] Updated PELIB commit to reflect latest changes --- deps/pelib/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deps/pelib/CMakeLists.txt b/deps/pelib/CMakeLists.txt index e6dfae89b..a8bf5b4d6 100644 --- a/deps/pelib/CMakeLists.txt +++ b/deps/pelib/CMakeLists.txt @@ -8,8 +8,8 @@ if(CMAKE_CXX_COMPILER) endif() ExternalProject_Add(pelib-project - URL https://github.com/avast-tl/pelib/archive/8ee59d45ee11124174301111367cd5eaeb0a7733.zip - URL_HASH SHA256=309d29f9e729d76de5ab4f2a6fb37a999257d3e3aa88ff99cb1195c2c6be8da0 + URL https://github.com/avast-tl/pelib/archive/9ccd3943c1a0917ffdaff5ab983fa7cdbb6dc5a2.zip + URL_HASH SHA256=a502c9023a52b3f248b331ce3a12a04c1b668a1d077dc69e03ea86aa9b0543df DOWNLOAD_NAME pelib.zip CMAKE_ARGS # This does not work on MSVC, but may be useful on Linux.