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

Anomalies scanner #570

Merged
merged 15 commits into from
Jul 1, 2019
4 changes: 4 additions & 0 deletions include/retdec/fileformat/file_format/file_format.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <initializer_list>
#include <map>
#include <set>
#include <utility>
#include <vector>

#include "retdec/utils/byte_value_storage.h"
Expand Down Expand Up @@ -91,6 +92,7 @@ class FileFormat : public retdec::utils::ByteValueStorage, private retdec::utils
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
retdec::utils::RangeContainer<std::uint64_t> nonDecodableRanges; ///< Address ranges which should not be decoded for instructions.
std::vector<std::pair<std::string, std::string>> anomalies; ///< file format anomalies

/// @name Clear methods
/// @{
Expand Down Expand Up @@ -212,6 +214,7 @@ class FileFormat : public retdec::utils::ByteValueStorage, private retdec::utils
bool getHexBytesFromEnd(std::string &result, unsigned long long numberOfBytes) const;
bool getString(std::string &result, unsigned long long offset, unsigned long long numberOfBytes) const;
bool getStringFromEnd(std::string &result, unsigned long long numberOfBytes) const;
bool isObjectStretchedOverSections(std::size_t addr, std::size_t size) const;
const Section* getEpSection();
const Section* getSection(const std::string &secName) const;
const Section* getSection(unsigned long long secIndex) const;
Expand Down Expand Up @@ -265,6 +268,7 @@ class FileFormat : public retdec::utils::ByteValueStorage, private retdec::utils
const std::vector<String>& getStrings() const;
const std::vector<ElfNoteSecSeg>& getElfNoteSecSegs() const;
const std::set<std::uint64_t>& getUnknownRelocations() const;
const std::vector<std::pair<std::string,std::string>> &getAnomalies() const;
/// @}

/// @name Address interpretation methods
Expand Down
13 changes: 13 additions & 0 deletions include/retdec/fileformat/file_format/pe/pe_format.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,14 @@ class PeFormat : public FileFormat
bool parseVisualBasicComRegistrationInfo(std::size_t structureOffset,
std::size_t comRegDataOffset);
/// @}
/// @name Auxiliary scanning methods
/// @{
void scanForSectionAnomalies();
void scanForResourceAnomalies();
void scanForImportAnomalies();
void scanForExportAnomalies();
void scanForOptHeaderAnomalies();
/// @}
protected:
PeLib::PeFile *file; ///< PeLib representation of PE file
PeLib::PeHeaderT<32> *peHeader32; ///< header of 32-bit PE file
Expand Down Expand Up @@ -207,6 +215,11 @@ class PeFormat : public FileFormat
const std::string& getTypeRefhashSha256() const;
const VisualBasicInfo* getVisualBasicInfo() const;
/// @}

/// @name Scanning methods
/// @{
void scanForAnomalies();
/// @}
};

} // namespace fileformat
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class PeFormatParser
virtual unsigned long long getFileFlags() const = 0;
virtual unsigned long long getTimeStamp() const = 0;
virtual unsigned long long getOptionalHeaderSize() const = 0;
virtual bool isSizeOfHeaderMultipleOfFileAlignment() const = 0;
virtual unsigned long long getFileAlignment() const = 0;
virtual unsigned long long getSectionAlignment() const = 0;
virtual unsigned long long getSizeOfImage() const = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class PeFormatParser32 : public PeFormatParser
virtual unsigned long long getFileFlags() const override;
virtual unsigned long long getTimeStamp() const override;
virtual unsigned long long getOptionalHeaderSize() const override;
virtual bool isSizeOfHeaderMultipleOfFileAlignment() const override;
virtual unsigned long long getFileAlignment() const override;
virtual unsigned long long getSectionAlignment() const override;
virtual unsigned long long getSizeOfImage() const override;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class PeFormatParser64 : public PeFormatParser
virtual unsigned long long getFileFlags() const override;
virtual unsigned long long getTimeStamp() const override;
virtual unsigned long long getOptionalHeaderSize() const override;
virtual bool isSizeOfHeaderMultipleOfFileAlignment() const override;
virtual unsigned long long getFileAlignment() const override;
virtual unsigned long long getSectionAlignment() const override;
virtual unsigned long long getSizeOfImage() const override;
Expand Down
17 changes: 15 additions & 2 deletions include/retdec/fileformat/file_format/pe/pe_template.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

#include <memory>

#include "retdec/utils/alignment.h"
#include "retdec/utils/range.h"
#include "retdec/utils/string.h"
#include "retdec/fileformat/file_format/pe/pe_template_aux.h"
Expand Down Expand Up @@ -171,6 +172,18 @@ template<int bits> unsigned long long peSizeOfOptionalHeader(const PeLib::PeHead
return peHeader.getSizeOfOptionalHeader();
}

/**
* Find out if optional header SizeOfHeaders is rounded up to multiple of FileAlignment
* @param peHeader Parser of PE header
* @return @c true if SizeOfHeaders is rounded up to multiple of FileAlignment, @c false otherwise
*/
template<int bits> unsigned long long peIsSizeOfHeaderMultipleOfFileAlignment(
const PeLib::PeHeaderT<bits> &peHeader)
{
std::uint64_t remainder;
return retdec::utils::isAligned(peHeader.getSizeOfHeaders(), peHeader.getFileAlignment(), remainder);
}

/**
* Get file alignment
* @param peHeader Parser of PE header
Expand Down Expand Up @@ -322,9 +335,9 @@ template<int bits> unsigned long long peNumberOfDelayImportedLibraries(const PeL
}

/**
* Get number of data directories
* Find out if is DLL
* @param peHeader Parser of PE header
* @return Number of data directories
* @return @c true if is DLL, @c false otherwise
*/
template<int bits> bool peIsDll(const PeLib::PeHeaderT<bits> &peHeader)
{
Expand Down
1 change: 1 addition & 0 deletions src/fileformat/file_format/coff/coff_format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -791,5 +791,6 @@ bool CoffFormat::is32BitArchitecture() const
return (getFileFlags() & IMAGE_FILE_32BIT_MACHINE) || getWordLength() == 32;
}


} // namespace fileformat
} // namespace retdec
37 changes: 37 additions & 0 deletions src/fileformat/file_format/file_format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1299,6 +1299,33 @@ bool FileFormat::getStringFromEnd(std::string &result, unsigned long long number
return getString(result, getLoadedFileLength() - numberOfBytes, numberOfBytes);
}

/**
* Find out if object is stretched over multiple sections
* @param addr Addres of object
* @param size Object size
* @return @c true if object is stretched over multiple sections, @c false otherwise
*/
bool FileFormat::isObjectStretchedOverSections(std::size_t addr, std::size_t size) const
{
for (const auto sec : sections)
{
if (!sec)
{
continue;
}

std::size_t secStart = sec->getOffset();
std::size_t secEnd = secStart + sec->getSizeInFile();
std::size_t addrEnd = addr + size;
if (secStart <= addr && addr < secEnd)
{
return (addrEnd > secEnd);
}
}

return false;
}

/**
* Get information about section containing entry point
* @return Pointer to EP section if file has entry point and EP section was detected, @c nullptr otherwise
Expand Down Expand Up @@ -1905,6 +1932,16 @@ const std::set<std::uint64_t> &FileFormat::getUnknownRelocations() const
return unknownRelocs;
}

/**
* Get all anomalies
* @return Reference to anomalies
*/
const std::vector<std::pair<std::string,std::string>> &FileFormat::getAnomalies() const
{
return anomalies;
}


/**
* Get integer (@a x bytes) located at provided address using the specified endian or default file endian
* @param address Address to get integer from
Expand Down
Loading