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

TLS parsing and presentation #523

Merged
merged 5 commits into from
May 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions deps/pelib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ else()
message(STATUS "PeLib: using remote PeLib revision.")

ExternalProject_Add(pelib-project
URL https://github.com/avast/pelib/archive/10bd64227023a2a37f075db3de9f4626dfbfb2b9.zip
URL_HASH SHA256=f6dec6a8cecdec6191412f5486ba26a3283b85a6419c9341a3c227e36fce5ce8
URL https://github.com/avast-tl/pelib/archive/2d03e34811e01c4ac1e403fd6cb9b323534aa803.zip
URL_HASH SHA256=d06ffb3bb561ece6e554dc58c4f10bfee8fbe21e23ccf79639a5b14743d64a0a
DOWNLOAD_NAME pelib.zip
CMAKE_ARGS
# This does not work on MSVC, but may be useful on Linux.
Expand Down
1 change: 1 addition & 0 deletions include/retdec/fileformat/fftypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "retdec/fileformat/types/strings/string.h"
#include "retdec/fileformat/types/symbol_table/macho_symbol.h"
#include "retdec/fileformat/types/symbol_table/symbol_table.h"
#include "retdec/fileformat/types/tls_info/tls_info.h"

namespace retdec {
namespace fileformat {
Expand Down
2 changes: 2 additions & 0 deletions include/retdec/fileformat/file_format/file_format.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ class FileFormat : public retdec::utils::ByteValueStorage, private retdec::utils
RichHeader *richHeader; ///< rich header
PdbInfo *pdbInfo; ///< information about related PDB debug file
CertificateTable *certificateTable; ///< table of certificates
TlsInfo *tlsInfo; ///< thread-local information
ElfCoreInfo *elfCoreInfo; ///< information about core file structures
Format fileFormat; ///< format of input file
LoaderErrorInfo _ldrErrInfo; ///< loader error (e.g. Windows loader error for PE files)
Expand Down Expand Up @@ -231,6 +232,7 @@ class FileFormat : public retdec::utils::ByteValueStorage, private retdec::utils
const RichHeader* getRichHeader() const;
const PdbInfo* getPdbInfo() const;
const CertificateTable* getCertificateTable() const;
const TlsInfo* getTlsInfo() const;
const ElfCoreInfo* getElfCoreInfo() const;
const Symbol* getSymbol(const std::string &name) const;
const Symbol* getSymbol(unsigned long long address) const;
Expand Down
1 change: 1 addition & 0 deletions include/retdec/fileformat/file_format/pe/pe_format.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ class PeFormat : public FileFormat
void loadResourceNodes(std::vector<const PeLib::ResourceChild*> &nodes, const std::vector<std::size_t> &levels);
void loadResources();
void loadCertificates();
void loadTlsInformation();
/// @}

/// @name Signature verification methods
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,12 @@ class PeFormatParser
virtual bool getDebugEntryPointerToRawData(unsigned long long index, unsigned long long& pointerToRawData) const = 0;
virtual unsigned long long getResourceDirectoryOffset() const = 0;
virtual const PeLib::ResourceNode* getResourceTreeRoot() const = 0;
virtual unsigned long long getTlsStartAddressOfRawData() const = 0;
virtual unsigned long long getTlsEndAddressOfRawData() const = 0;
virtual unsigned long long getTlsAddressOfIndex() const = 0;
virtual unsigned long long getTlsAddressOfCallBacks() const = 0;
virtual unsigned long long getTlsSizeOfZeroFill() const = 0;
virtual unsigned long long getTlsCharacteristics() const = 0;
virtual std::unique_ptr<CLRHeader> getClrHeader() const = 0;
virtual unsigned long long getNumberOfRelocations() const = 0;
virtual unsigned long long getNumberOfRelocationData(unsigned long long index) const = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@ class PeFormatParser32 : public PeFormatParser
virtual bool getDebugEntryPointerToRawData(unsigned long long index, unsigned long long& pointerToRawData) const override;
virtual unsigned long long getResourceDirectoryOffset() const override;
virtual const PeLib::ResourceNode* getResourceTreeRoot() const override;
virtual unsigned long long getTlsStartAddressOfRawData() const override;
virtual unsigned long long getTlsEndAddressOfRawData() const override;
virtual unsigned long long getTlsAddressOfIndex() const override;
virtual unsigned long long getTlsAddressOfCallBacks() const override;
virtual unsigned long long getTlsSizeOfZeroFill() const override;
virtual unsigned long long getTlsCharacteristics() const override;
virtual std::unique_ptr<CLRHeader> getClrHeader() const override;
virtual unsigned long long getNumberOfRelocations() const override;
virtual unsigned long long getNumberOfRelocationData(unsigned long long index) const override;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,12 @@ class PeFormatParser64 : public PeFormatParser
virtual bool getDebugEntryPointerToRawData(unsigned long long index, unsigned long long& pointerToRawData) const override;
virtual unsigned long long getResourceDirectoryOffset() const override;
virtual const PeLib::ResourceNode* getResourceTreeRoot() const override;
virtual unsigned long long getTlsStartAddressOfRawData() const override;
virtual unsigned long long getTlsEndAddressOfRawData() const override;
virtual unsigned long long getTlsAddressOfIndex() const override;
virtual unsigned long long getTlsAddressOfCallBacks() const override;
virtual unsigned long long getTlsSizeOfZeroFill() const override;
virtual unsigned long long getTlsCharacteristics() const override;
virtual std::unique_ptr<CLRHeader> getClrHeader() const override;
virtual unsigned long long getNumberOfRelocations() const override;
virtual unsigned long long getNumberOfRelocationData(unsigned long long index) const override;
Expand Down
60 changes: 60 additions & 0 deletions include/retdec/fileformat/file_format/pe/pe_template.h
Original file line number Diff line number Diff line change
Expand Up @@ -706,6 +706,66 @@ template<int bits> const PeLib::ResourceNode* peResourceTreeRoot(const PeLib::Re
return resources.getRoot();
}

/**
* Get TLS directory startAddressOfRawData
* @param tls Parser of TLS directory
* @return StartAddressOfRawData of TLS directory
*/
template<int bits> unsigned long long peTlsStartAddressOfRawData(const PeLib::TlsDirectory<bits> &tls)
{
return tls.getStartAddressOfRawData();
}

/**
* Get TLS directory endAddressOfRawData
* @param tls Parser of TLS directory
* @return EndAddressOfRawData of TLS directory
*/
template<int bits> unsigned long long peTlsEndAddressOfRawData(const PeLib::TlsDirectory<bits> &tls)
{
return tls.getEndAddressOfRawData();
}

/**
* Get TLS directory addressOfIndex
* @param tls Parser of TLS directory
* @return AddressOfIndex of TLS directory
*/
template<int bits> unsigned long long peTlsAddressOfIndex(const PeLib::TlsDirectory<bits> &tls)
{
return tls.getAddressOfIndex();
}

/**
* Get TLS directory addressOfCallBacks
* @param tls Parser of TLS directory
* @return AddressOfCallBacks of TLS directory
*/
template<int bits> unsigned long long peTlsAddressOfCallBacks(const PeLib::TlsDirectory<bits> &tls)
{
return tls.getAddressOfCallBacks();
}

/**
* Get TLS directory sizeOfZeroFill
* @param tls Parser of TLS directory
* @return SizeOfZeroFill of TLS directory
*/
template<int bits> unsigned long long peTlsSizeOfZeroFill(const PeLib::TlsDirectory<bits> &tls)
{
return tls.getSizeOfZeroFill();
}

/**
* Get TLS directory characteristics
* @param tls Parser of TLS directory
* @return Characteristics of TLS directory
*/
template<int bits> unsigned long long peTlsCharacteristics(const PeLib::TlsDirectory<bits> &tls)
{
return tls.getCharacteristics();
}

/**
* Get CLR header
* @param comHeader Parser of PE COM/CLR directory
Expand Down
69 changes: 69 additions & 0 deletions include/retdec/fileformat/types/tls_info/tls_info.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/**
* @file include/retdec/fileformat/types/tls_info/tls_info.h
* @brief Class for information about thread-local storage.
* @copyright (c) 2017 Avast Software, licensed under the MIT license
*/

#ifndef RETDEC_FILEFORMAT_TYPES_TLS_INFO_TLS_INFO_H
#define RETDEC_FILEFORMAT_TYPES_TLS_INFO_TLS_INFO_H

#include <string>
#include <vector>

namespace retdec {
namespace fileformat {

/**
* Information about TLS
*/
class TlsInfo
{
private:
std::vector<std::uint64_t> callBacks; ///< addresses of callback functions
std::uint64_t rawDataStartAddr; ///< start address of raw data
std::uint64_t rawDataEndAddr; ///< end address of raw data
std::uint64_t indexAddr; ///< address of index
std::uint64_t callBacksAddr; ///< address of array of callbacks
std::uint32_t zeroFillSize; ///< size of zero fill
std::uint32_t characteristics; ///< characteristics
bool rawDataStartAddrValid; ///< member validity flag
bool rawDataEndAddrValid; ///< member validity flag
bool indexAddrValid; ///< member validity flag
bool callBacksAddrValid; ///< member validity flag
bool zeroFillSizeValid; ///< member validity flag
bool characteristicsValid; ///< member validity flag
public:
TlsInfo();
~TlsInfo();

/// @name Getters
/// @{
bool getRawDataStartAddr(std::uint64_t &res) const;
bool getRawDataEndAddr(std::uint64_t &res) const;
bool getIndexAddr(std::uint64_t &res) const;
bool getCallBacksAddr(std::uint64_t &res) const;
bool getZeroFillSize(std::uint32_t &res) const;
bool getCharacteristics(std::uint32_t &res) const;
const std::vector<std::uint64_t> &getCallBacks() const;
/// @}

/// @name Setters
/// @{
void setRawDataStartAddr(std::uint64_t sAddr);
void setRawDataEndAddr(std::uint64_t eAddr);
void setIndexAddr(std::uint64_t iAddr);
void setCallBacksAddr(std::uint64_t cbAddr);
void setZeroFillSize(std::uint32_t zFill);
void setCharacteristics(std::uint32_t chars);
/// @}

/// @name Other methods
/// @{
void addCallBack(std::uint64_t cb);
/// @}
};

} // namespace fileformat
} // namespace retdec

#endif
1 change: 1 addition & 0 deletions src/fileformat/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ set(FILEFORMAT_SOURCES
types/strings/string.cpp
types/note_section/elf_notes.cpp
types/note_section/elf_core.cpp
types/tls_info/tls_info.cpp
file_format/pe/pe_format_parser/pe_format_parser64.cpp
file_format/pe/pe_format_parser/pe_format_parser.cpp
file_format/pe/pe_format_parser/pe_format_parser32.cpp
Expand Down
14 changes: 13 additions & 1 deletion src/fileformat/file_format/file_format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ void FileFormat::init()
richHeader = nullptr;
pdbInfo = nullptr;
certificateTable = nullptr;
tlsInfo = nullptr;
elfCoreInfo = nullptr;
fileFormat = Format::UNDETECTABLE;
stateIsValid = readFile(fileStream, bytes) && stateIsValid;
Expand Down Expand Up @@ -232,6 +233,7 @@ void FileFormat::clear()
delete richHeader;
delete pdbInfo;
delete certificateTable;
delete tlsInfo;
delete elfCoreInfo;

for(auto *item : sections)
Expand Down Expand Up @@ -1551,13 +1553,23 @@ const PdbInfo* FileFormat::getPdbInfo() const

/**
* Get information about certificate table
* @return Pointer to certificate table of @c nullptr if file has no certificates
* @return Pointer to certificate table or @c nullptr if file has no certificates
*/
const CertificateTable* FileFormat::getCertificateTable() const
{
return certificateTable;
}

/**
* Get information about TLS
* @return Pointer to TLS information or @c nullptr if file has no certificates
*/
const TlsInfo* FileFormat::getTlsInfo() const
{
return tlsInfo;
}


/**
* Get information about ELF core file
* @return Pointer to ELF core info of @c nullptr if file has no certificates
Expand Down
44 changes: 44 additions & 0 deletions src/fileformat/file_format/pe/pe_format.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,7 @@ void PeFormat::initStructures()
file->readDelayImportDirectory();
file->readExportDirectory();
file->readDebugDirectory();
file->readTlsDirectory();
file->readResourceDirectory();
file->readSecurityDirectory();
file->readComHeaderDirectory();
Expand Down Expand Up @@ -427,6 +428,7 @@ void PeFormat::initStructures()
loadPdbInfo();
loadResources();
loadCertificates();
loadTlsInformation();
loadDotnetHeaders();
loadVisualBasicHeader();
computeSectionTableHashes();
Expand Down Expand Up @@ -1732,6 +1734,48 @@ void PeFormat::loadCertificates()
BIO_free(bio);
}

/**
* Load thread-local storage information
*/
void PeFormat::loadTlsInformation()
{
unsigned long long rva = 0, size = 0;
if (!getDataDirectoryRelative(PELIB_IMAGE_DIRECTORY_ENTRY_TLS, rva, size) || size == 0)
{
return;
}

tlsInfo = new TlsInfo();
tlsInfo->setRawDataStartAddr(formatParser->getTlsStartAddressOfRawData());
tlsInfo->setRawDataEndAddr(formatParser->getTlsEndAddressOfRawData());
tlsInfo->setIndexAddr(formatParser->getTlsAddressOfIndex());
tlsInfo->setZeroFillSize(formatParser->getTlsSizeOfZeroFill());
tlsInfo->setCharacteristics(formatParser->getTlsCharacteristics());

auto callBacksAddr = formatParser->getTlsAddressOfCallBacks();
tlsInfo->setCallBacksAddr(callBacksAddr);

const auto &allBytes = getBytes();
DynamicBuffer structContent(allBytes);

unsigned long long callBacksOffset;
if (getOffsetFromAddress(callBacksOffset, callBacksAddr))
{
while (allBytes.size() >= callBacksOffset + sizeof(std::uint32_t))
{
auto cbAddr = structContent.read<std::uint32_t>(callBacksOffset);
callBacksOffset += sizeof(std::uint32_t);

if (cbAddr == 0)
{
break;
}

tlsInfo->addCallBack(cbAddr);
}
}
}

/**
* Load .NET headers.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,36 @@ const PeLib::ResourceNode* PeFormatParser32::getResourceTreeRoot() const
return peResourceTreeRoot(peFile->resDir());
}

unsigned long long PeFormatParser32::getTlsStartAddressOfRawData() const
{
return peTlsStartAddressOfRawData(peFile->tlsDir());
}

unsigned long long PeFormatParser32::getTlsEndAddressOfRawData() const
{
return peTlsEndAddressOfRawData(peFile->tlsDir());
}

unsigned long long PeFormatParser32::getTlsAddressOfIndex() const
{
return peTlsAddressOfIndex(peFile->tlsDir());
}

unsigned long long PeFormatParser32::getTlsAddressOfCallBacks() const
{
return peTlsAddressOfCallBacks(peFile->tlsDir());
}

unsigned long long PeFormatParser32::getTlsSizeOfZeroFill() const
{
return peTlsSizeOfZeroFill(peFile->tlsDir());
}

unsigned long long PeFormatParser32::getTlsCharacteristics() const
{
return peTlsCharacteristics(peFile->tlsDir());
}

std::unique_ptr<CLRHeader> PeFormatParser32::getClrHeader() const
{
return peGetClrHeader(peFile->comDir());
Expand Down
Loading