Merge branch 'pr/241'

This commit is contained in:
Romain Thomas 2018-11-29 09:18:06 +01:00
commit 3271d1011b
14 changed files with 77 additions and 36 deletions

View File

@ -135,6 +135,9 @@ void create<Binary>(py::module& m) {
.def_property_readonly("has_signature", &Binary::has_signature,
"``True`` if the binary is signed (" RST_CLASS_REF(lief.PE.Signature) ")")
.def_property_readonly("is_reproducible_build", &Binary::is_reproducible_build,
"``True`` if the binary was compiled with a reproducible build directive (" RST_CLASS_REF(lief.PE.Debug) ")")
.def_property_readonly("functions",
&Binary::functions,
"**All** " RST_CLASS_REF(lief.Function) " found in the binary")
@ -153,10 +156,9 @@ void create<Binary>(py::module& m) {
"Return the " RST_CLASS_REF(lief.PE.Signature) " object",
py::return_value_policy::reference)
.def_property_readonly("debug",
static_cast<Debug& (Binary::*)(void)>(&Binary::debug),
"Return the " RST_CLASS_REF(lief.PE.Debug) " object",
static_cast<debug_entries_t& (Binary::*)(void)>(&Binary::debug),
"Return the " RST_CLASS_REF(lief.PE.Debug) "",
py::return_value_policy::reference)
.def_property_readonly("load_configuration",

View File

@ -253,7 +253,12 @@ void init_enums(py::module& m) {
.value(PY_ENUM(LIEF::PE::DEBUG_TYPES::IMAGE_DEBUG_TYPE_OMAP_TO_SRC))
.value(PY_ENUM(LIEF::PE::DEBUG_TYPES::IMAGE_DEBUG_TYPE_OMAP_FROM_SRC))
.value(PY_ENUM(LIEF::PE::DEBUG_TYPES::IMAGE_DEBUG_TYPE_BORLAND))
.value(PY_ENUM(LIEF::PE::DEBUG_TYPES::IMAGE_DEBUG_TYPE_CLSID));
.value(PY_ENUM(LIEF::PE::DEBUG_TYPES::IMAGE_DEBUG_TYPE_CLSID))
.value(PY_ENUM(LIEF::PE::DEBUG_TYPES::IMAGE_DEBUG_TYPE_VC_FEATURE))
.value(PY_ENUM(LIEF::PE::DEBUG_TYPES::IMAGE_DEBUG_TYPE_POGO))
.value(PY_ENUM(LIEF::PE::DEBUG_TYPES::IMAGE_DEBUG_TYPE_ILTCG))
.value(PY_ENUM(LIEF::PE::DEBUG_TYPES::IMAGE_DEBUG_TYPE_MPX))
.value(PY_ENUM(LIEF::PE::DEBUG_TYPES::IMAGE_DEBUG_TYPE_REPRO));
LIEF::enum_<LIEF::PE::RESOURCE_TYPES>(m, "RESOURCE_TYPES")

View File

@ -89,7 +89,9 @@ int main(int argc, char **argv) {
if (binary->has_debug()) {
std::cout << "== Debug ==" << std::endl;
std::cout << binary->debug() << std::endl;
for (const Debug& debug : binary->debug()) {
std::cout << debug << std::endl;
}
}

View File

@ -144,6 +144,11 @@ class LIEF_API Binary : public LIEF::Binary {
//! @brief Check if the current binary has a load configuration
bool has_configuration(void) const;
//! @brief Check if the current binary has been built has reproducible, replacing timestamps by a compile hash.
//!
//! @see Debug
bool is_reproducible_build(void) const;
//! @brief Return the Signature object if the bianry is signed
const Signature& signature(void) const;
@ -237,9 +242,9 @@ class LIEF_API Binary : public LIEF::Binary {
bool has(DATA_DIRECTORY index) const;
//! @brief Return the Debug object
Debug& debug(void);
const Debug& debug(void) const;
//! @brief Return the debug_entries_t object
debug_entries_t& debug(void);
const debug_entries_t& debug(void) const;
//! @brief Retrun the LoadConfiguration object
const LoadConfiguration& load_configuration(void) const;
@ -431,6 +436,7 @@ class LIEF_API Binary : public LIEF::Binary {
bool has_relocations_;
bool has_debug_;
bool has_configuration_;
bool is_reproducible_build_;
Signature signature_;
TLS tls_;
@ -442,7 +448,7 @@ class LIEF_API Binary : public LIEF::Binary {
ResourceNode* resources_;
imports_t imports_;
Export export_;
Debug debug_;
debug_entries_t debug_;
std::vector<uint8_t> overlay_;
std::vector<uint8_t> dos_stub_;

View File

@ -85,7 +85,7 @@ class LIEF_API Parser : public LIEF::Parser {
void parse_export_table(void);
void parse_debug(void);
void parse_debug_code_view(void);
void parse_debug_code_view(Debug& debug_info);
template<typename PE_T>
void parse_tls(void);

View File

@ -266,6 +266,7 @@ enum _LIEF_EN(DEBUG_TYPES) {
_LIEF_EI(IMAGE_DEBUG_TYPE_OMAP_TO_SRC) = 7, ///< The mapping from an RVA in image to an RVA in source image.
_LIEF_EI(IMAGE_DEBUG_TYPE_OMAP_FROM_SRC) = 8, ///< The mapping from an RVA in source image to an RVA in image.
_LIEF_EI(IMAGE_DEBUG_TYPE_BORLAND) = 9, ///< Reserved for Borland.
_LIEF_EI(IMAGE_DEBUG_TYPE_RESERVED10) = 10, ///< Reserved for future use.
_LIEF_EI(IMAGE_DEBUG_TYPE_CLSID) = 11,
_LIEF_EI(IMAGE_DEBUG_TYPE_VC_FEATURE) = 12,
_LIEF_EI(IMAGE_DEBUG_TYPE_POGO) = 13,

View File

@ -65,6 +65,10 @@ using export_entries_t = std::vector<ExportEntry>;
using it_export_entries = ref_iterator<export_entries_t&>;
using it_const_export_entries = const_ref_iterator<const export_entries_t&>;
using debug_entries_t = std::vector<Debug>;
using it_debug_entries = ref_iterator<debug_entries_t&>;
using it_const_debug_entries = const_ref_iterator<const debug_entries_t&>;
using symbols_t = std::vector<Symbol>;
using it_symbols = ref_iterator<symbols_t&>;
using it_const_symbols = const_ref_iterator<const symbols_t&>;

View File

@ -242,6 +242,7 @@
#undef IMAGE_DEBUG_TYPE_OMAP_TO_SRC
#undef IMAGE_DEBUG_TYPE_OMAP_FROM_SRC
#undef IMAGE_DEBUG_TYPE_BORLAND
#undef IMAGE_DEBUG_TYPE_RESERVED10
#undef IMAGE_DEBUG_TYPE_CLSID
#undef IMAGE_DEBUG_TYPE_VC_FEATURE
#undef IMAGE_DEBUG_TYPE_POGO

View File

@ -92,6 +92,7 @@ Binary::Binary(void) :
has_relocations_{false},
has_debug_{false},
has_configuration_{false},
is_reproducible_build_{false},
tls_{},
sections_{},
data_directories_{},
@ -358,6 +359,9 @@ bool Binary::has_debug(void) const {
return this->has_debug_;
}
bool Binary::is_reproducible_build(void) const {
return this->is_reproducible_build_;
}
bool Binary::has_configuration(void) const {
return this->has_configuration_ and this->load_configuration_ != nullptr;
@ -978,12 +982,12 @@ it_const_data_directories Binary::data_directories(void) const {
}
Debug& Binary::debug(void) {
return const_cast<Debug&>(static_cast<const Binary*>(this)->debug());
debug_entries_t& Binary::debug(void) {
return const_cast<debug_entries_t&>(static_cast<const Binary*>(this)->debug());
}
const Debug& Binary::debug(void) const {
const debug_entries_t& Binary::debug(void) const {
return this->debug_;
}
@ -1410,7 +1414,9 @@ std::ostream& Binary::print(std::ostream& os) const {
if (this->has_debug()) {
os << "Debug" << std::endl;
os << "=====" << std::endl;
os << this->debug() << std::endl;
for (const Debug& debug : this->debug()) {
os << debug << std::endl;
}
os << std::endl;
}

View File

@ -385,7 +385,7 @@ const char* to_string(RELOCATIONS_BASE_TYPES e) {
const char* to_string(DEBUG_TYPES e) {
CONST_MAP(DEBUG_TYPES, const char*, 16) enumStrings {
CONST_MAP(DEBUG_TYPES, const char*, 17) enumStrings {
{ DEBUG_TYPES::IMAGE_DEBUG_TYPE_UNKNOWN, "UNKNOWN" },
{ DEBUG_TYPES::IMAGE_DEBUG_TYPE_COFF, "COFF" },
{ DEBUG_TYPES::IMAGE_DEBUG_TYPE_CODEVIEW, "CODEVIEW" },
@ -396,6 +396,7 @@ const char* to_string(DEBUG_TYPES e) {
{ DEBUG_TYPES::IMAGE_DEBUG_TYPE_OMAP_TO_SRC, "SRC" },
{ DEBUG_TYPES::IMAGE_DEBUG_TYPE_OMAP_FROM_SRC, "SRC" },
{ DEBUG_TYPES::IMAGE_DEBUG_TYPE_BORLAND, "BORLAND" },
{ DEBUG_TYPES::IMAGE_DEBUG_TYPE_RESERVED10, "RESERVED" },
{ DEBUG_TYPES::IMAGE_DEBUG_TYPE_CLSID, "CLSID" },
{ DEBUG_TYPES::IMAGE_DEBUG_TYPE_VC_FEATURE, "VC_FEATURE" },
{ DEBUG_TYPES::IMAGE_DEBUG_TYPE_POGO, "POGO" },

View File

@ -565,28 +565,37 @@ void Parser::parse_debug(void) {
uint32_t debugRVA = this->binary_->data_directory(DATA_DIRECTORY::DEBUG).RVA();
uint32_t debugoffset = this->binary_->rva_to_offset(debugRVA);
//uint32_t debugsize = this->binary_->dataDirectories_[DATA_DIRECTORY::DEBUG]->size();
uint32_t debugsize = this->binary_->data_directory(DATA_DIRECTORY::DEBUG).size();
const pe_debug& debug_struct = this->stream_->peek<pe_debug>(debugoffset);
for (size_t i = 0; (i + 1) * sizeof(pe_debug) <= debugsize; i++) {
this->binary_->debug_ = &debug_struct;
const pe_debug& debug_struct = this->stream_->peek<pe_debug>(debugoffset + i * sizeof(pe_debug));
this->binary_->debug_.push_back(&debug_struct);
DEBUG_TYPES type = this->binary_->debug().type();
DEBUG_TYPES type = this->binary_->debug().back().type();
switch (type) {
case DEBUG_TYPES::IMAGE_DEBUG_TYPE_CODEVIEW:
{
this->parse_debug_code_view();
}
default:
{
}
switch (type) {
case DEBUG_TYPES::IMAGE_DEBUG_TYPE_CODEVIEW:
{
this->parse_debug_code_view(this->binary_->debug().back());
break;
}
case DEBUG_TYPES::IMAGE_DEBUG_TYPE_REPRO:
{
this->binary_->is_reproducible_build_ = true;
break;
}
default:
{}
}
}
}
void Parser::parse_debug_code_view() {
void Parser::parse_debug_code_view(Debug& debug_info) {
VLOG(VDEBUG) << "Parsing Debug Code View";
Debug& debug_info = this->binary_->debug();
//Debug& debug_info = this->binary_->debug();
const uint32_t debug_off = debug_info.pointerto_rawdata();
if (not this->stream_->can_read<uint32_t>(debug_off)) {

View File

@ -39,7 +39,7 @@ void Hash::visit(const Binary& binary) {
process(std::begin(binary.symbols()), std::end(binary.symbols()));
if (binary.has_debug()) {
process(binary.debug());
process(std::begin(binary.debug()), std::end(binary.debug()));
}
if (binary.has_exports()) {

View File

@ -108,9 +108,13 @@ void JsonVisitor::visit(const Binary& binary) {
// Debug
if (binary.has_debug()) {
JsonVisitor visitor;
visitor(binary.debug());
this->node_["debug"] = visitor.get();
std::vector<json> debug_entries;
for (const Debug& debug : binary.debug()) {
JsonVisitor visitor;
visitor(debug);
debug_entries.emplace_back(visitor.get());
}
this->node_["debug"] = debug_entries;
}
// Imports

View File

@ -41,10 +41,10 @@ class TestPe(TestCase):
self.assertTrue(sample.has_debug)
debug = sample.debug
self.assertTrue(debug.has_code_view)
debug_code_view = list(filter(lambda deb: deb.has_code_view, sample.debug))
self.assertTrue(len(debug_code_view) == 1)
debug = debug_code_view[0]
code_view = debug.code_view
self.assertEqual(code_view.cv_signature, lief.PE.CODE_VIEW_SIGNATURES.PDB_70)