Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Corruption check is complete #281

Merged
merged 14 commits into from
May 9, 2018
5 changes: 3 additions & 2 deletions deps/pelib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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/19f9a34c0dd10657303e15f7a9d03de9d177e6be.zip
# URL https://github.com/avast-tl/pelib/archive/e93eaa7c150f4608a5d02a67f5edc9e54456fe24.zip
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, remove these lines which are commented out. Also please add URL_HASH with the hash of the new archive so CMake can check whether it downloaded correct archive.

# URL_HASH SHA256=2ffd7e89451c980a1af6d24d4f6dfbb69a660b06ad5de44c481f6431e21de394
DOWNLOAD_NAME pelib.zip
CMAKE_ARGS
# This does not work on MSVC, but may be useful on Linux.
Expand Down
17 changes: 17 additions & 0 deletions include/retdec/fileformat/file_format/file_format.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,20 @@
namespace retdec {
namespace fileformat {

/**
* LoaderErrorInfo - common structure that contains loader error code, error message and user-friendly error message
*/

struct LoaderErrorInfo
{
LoaderErrorInfo() : loaderErrorCode(0), loaderError(nullptr), loaderErrorUserFriendly(nullptr)
{}

std::uint32_t loaderErrorCode; // Loader error code, cast to uint32_t
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are tabs in-between name of the attribute and comment. Please use spaces here. We use tabs only for indentation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in commit cab9451

const char * loaderError;
const char * loaderErrorUserFriendly;
};

/**
* FileFormat - abstract class for parsing files
*/
Expand Down Expand Up @@ -67,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)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are tabs in-between name of the attribute and comment. Please use spaces here. We use tabs only for indentation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in commit cab9451

bool stateIsValid; ///< internal state of instance
std::vector<std::pair<std::size_t, std::size_t>> secHashInfo; ///< information for calculation of section table hash
retdec::utils::Maybe<bool> signatureVerified; ///< indicates whether the signature is present and also verified
Expand Down Expand Up @@ -128,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
/// @{
Expand Down
2 changes: 2 additions & 0 deletions include/retdec/fileformat/file_format/pe/pe_format.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class PeFormat : public FileFormat

/// @name Initialization methods
/// @{
void initLoaderErrorInfo();
void initStructures();
/// @}

Expand Down Expand Up @@ -147,6 +148,7 @@ class PeFormat : public FileFormat
std::size_t getSizeOfHeapCommit() const;
std::size_t getNumberOfDataDirectories() const;
std::size_t getDeclaredNumberOfDataDirectories() const;

int getPeClass() const;
bool isDotNet() const;
bool isPackedDotNet() const;
Expand Down
1 change: 1 addition & 0 deletions include/retdec/loader/loader/image.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ class Image : public retdec::utils::ByteValueStorage
std::pair<const std::uint8_t*, std::uint64_t> getRawSegmentData(std::uint64_t address) const;

const std::string& getStatusMessage() const;
const retdec::fileformat::LoaderErrorInfo & getLoaderErrorInfo() const;

protected:
Segment* insertSegment(std::unique_ptr<Segment> segment);
Expand Down
24 changes: 16 additions & 8 deletions include/retdec/utils/conversion.h
Original file line number Diff line number Diff line change
Expand Up @@ -205,16 +205,24 @@ template<typename N> void bytesToHexString(const N *data, std::size_t dataSize,
size = (size == 0 || offset + size > dataSize) ? dataSize - offset : size;
}

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];
}
}

/**
Expand Down
13 changes: 11 additions & 2 deletions src/fileformat/file_format/file_format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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();
Expand Down Expand Up @@ -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
Expand Down
16 changes: 16 additions & 0 deletions src/fileformat/file_format/pe/pe_format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::uint32_t>(ldrError);
_ldrErrInfo.loaderError = getLoaderErrorString(ldrError, false);
_ldrErrInfo.loaderErrorUserFriendly = getLoaderErrorString(ldrError, true);
}

/**
* Init internal structures
*/
Expand Down Expand Up @@ -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)))
{
Expand Down
6 changes: 6 additions & 0 deletions src/fileinfo/file_detector/file_detector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,12 @@ void FileDetector::getLoaderInfo()
{
fileInfo.setLoaderStatusMessage(image->getStatusMessage());
}

auto ldrErrInfo = image->getLoaderErrorInfo();
if (ldrErrInfo.loaderErrorCode != 0)
{
fileInfo.setLoaderErrorInfo(ldrErrInfo);
}
}

/**
Expand Down
18 changes: 18 additions & 0 deletions src/fileinfo/file_information/file_information.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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/
Expand Down Expand Up @@ -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.
Expand Down
8 changes: 5 additions & 3 deletions src/fileinfo/file_information/file_information.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spaces.

RichHeader richHeader; ///< rich header
PdbInfo pdbInfo; ///< information about related PDB file
ImportTable importTable; ///< information about imports
Expand All @@ -55,7 +55,7 @@ class FileInformation
std::vector<Pattern> malwarePatterns; ///< detected malware patterns
std::vector<Pattern> otherPatterns; ///< other detected patterns
Strings strings; ///< detected strings
retdec::utils::Maybe<bool> signatureVerified; ///< indicates whether the signature is present and if it is verified
retdec::utils::Maybe<bool> signatureVerified; ///< indicates whether the signature is present and if it is verified
DotnetInfo dotnetInfo; ///< .NET information
public:
retdec::cpdetect::ToolInformation toolInfo; ///< detected tools
Expand Down Expand Up @@ -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;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spaces.

/// @}

/// @name Getters of @a dotnetInfo
/// @{
Expand Down Expand Up @@ -492,6 +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);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spaces.

void setDotnetUsed(bool set);
void setDotnetRuntimeVersion(std::uint64_t majorVersion, std::uint64_t minorVersion);
void setDotnetMetadataHeaderAddress(std::uint64_t address);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down Expand Up @@ -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;
Expand All @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ class LoaderInfo
unsigned long long _baseAddress;
std::vector<LoadedSegment> _loadedSegments;
std::string _statusMessage;
public:
retdec::fileformat::LoaderErrorInfo _ldrErrInfo;

public:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing 1 TAB.

LoaderInfo();
~LoaderInfo();

Expand All @@ -48,12 +50,14 @@ 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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ BasicPlainGetter::~BasicPlainGetter()

std::size_t BasicPlainGetter::loadInformation(std::vector<std::string> &desc, std::vector<std::string> &info) const
{
const char * loaderErrorUserFriendly = fileinfo.getLoaderErrorInfo().loaderErrorUserFriendly;

desc.clear();
info.clear();

Expand All @@ -41,6 +43,11 @@ std::size_t BasicPlainGetter::loadInformation(std::vector<std::string> &desc, st
desc.push_back("File format : ");
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 : ");

desc.push_back("Architecture : ");
desc.push_back("Endianness : ");
desc.push_back("Image base address : ");
Expand All @@ -56,6 +63,11 @@ std::size_t BasicPlainGetter::loadInformation(std::vector<std::string> &desc, st
info.push_back(fileinfo.getFileFormat());
info.push_back(fileinfo.getFileClass());
info.push_back(fileinfo.getFileType());

// 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));
Expand Down
21 changes: 21 additions & 0 deletions src/fileinfo/file_presentation/json_presentation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
auto 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
Expand Down Expand Up @@ -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))
{
Expand Down
1 change: 1 addition & 0 deletions src/fileinfo/file_presentation/json_presentation.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
5 changes: 5 additions & 0 deletions src/loader/loader/image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,11 @@ void Image::setStatusMessage(const std::string& message)
_statusMessage = message;
}

const retdec::fileformat::LoaderErrorInfo & Image::getLoaderErrorInfo() const
{
return getFileFormat()->getLoaderErrorInfo();
}

Segment* Image::insertSegment(std::unique_ptr<Segment> segment)
{
_segments.push_back(std::move(segment));
Expand Down