From 8908fe4a4551de756b4f50eaca22328571e98fce Mon Sep 17 00:00:00 2001 From: Romain Thomas Date: Fri, 28 Apr 2023 06:14:35 +0200 Subject: [PATCH] Add interface to tweak the PE parser (resolve #839) This commit also removes the Binary's name attribute. --- api/c/ELF/Binary.cpp | 1 - api/c/MachO/Binary.cpp | 1 - api/c/PE/Binary.cpp | 1 - api/python/src/Abstract/objects/pyBinary.cpp | 5 -- api/python/src/Abstract/objects/pyParser.cpp | 10 ++-- api/python/src/ELF/objects/pyParser.cpp | 10 ++-- api/python/src/MachO/objects/pyBinary.cpp | 4 ++ api/python/src/MachO/objects/pyParser.cpp | 6 +- api/python/src/OAT/objects/pyParser.cpp | 10 ++-- api/python/src/PE/CMakeLists.txt | 1 + api/python/src/PE/objects/pyBinary.cpp | 4 +- api/python/src/PE/objects/pyParser.cpp | 14 ++--- api/python/src/PE/objects/pyParserConfig.cpp | 58 ++++++++++++++++++++ api/python/src/PE/pyPE.cpp | 1 + api/python/src/PE/pyPE.hpp | 1 + doc/sphinx/api/cpp/macho.rst | 4 +- doc/sphinx/api/cpp/pe.rst | 12 ++++ doc/sphinx/api/python/pe.rst | 5 ++ doc/sphinx/changelog.rst | 27 +++++++++ include/LIEF/Abstract/Binary.hpp | 15 ++--- include/LIEF/Abstract/Parser.hpp | 13 ++--- include/LIEF/ELF/Parser.hpp | 10 ++-- include/LIEF/MachO/Binary.hpp | 6 ++ include/LIEF/MachO/Parser.hpp | 4 +- include/LIEF/OAT/Parser.hpp | 6 +- include/LIEF/PE/Binary.hpp | 2 +- include/LIEF/PE/Parser.hpp | 13 +++-- include/LIEF/PE/ParserConfig.hpp | 39 +++++++++++++ src/Abstract/Binary.cpp | 20 ------- src/Abstract/Parser.cpp | 20 +++---- src/Abstract/json.cpp | 1 - src/ELF/Parser.cpp | 15 +++-- src/ELF/json.cpp | 1 - src/MachO/BinaryParser.cpp | 1 - src/MachO/BinaryParser.tcc | 2 +- src/MachO/Parser.cpp | 17 ++---- src/MachO/json.cpp | 1 - src/OAT/Parser.cpp | 13 ++--- src/PE/Binary.cpp | 3 +- src/PE/Parser.cpp | 23 ++++---- src/PE/Parser.tcc | 12 ++-- src/PE/json.cpp | 1 - tests/elf/test_equality.py | 5 +- tests/pe/test_imphash.py | 22 ++++---- tests/pe/test_parser.py | 18 +++++- 45 files changed, 292 insertions(+), 166 deletions(-) create mode 100644 api/python/src/PE/objects/pyParserConfig.cpp create mode 100644 include/LIEF/PE/ParserConfig.hpp diff --git a/api/c/ELF/Binary.cpp b/api/c/ELF/Binary.cpp index c128de0d45..f3220b8fb6 100644 --- a/api/c/ELF/Binary.cpp +++ b/api/c/ELF/Binary.cpp @@ -36,7 +36,6 @@ namespace LIEF { namespace ELF { void init_c_binary(Elf_Binary_t* c_binary, Binary* binary) { c_binary->handler = reinterpret_cast(binary); - c_binary->name = binary->name().c_str(); c_binary->type = static_cast(binary->type()); c_binary->interpreter = nullptr; if (binary->has_interpreter()) { diff --git a/api/c/MachO/Binary.cpp b/api/c/MachO/Binary.cpp index 9b7ef4d698..2934fc9ad8 100644 --- a/api/c/MachO/Binary.cpp +++ b/api/c/MachO/Binary.cpp @@ -32,7 +32,6 @@ namespace MachO { void init_c_binary(Macho_Binary_t* c_binary, Binary* binary) { c_binary->handler = reinterpret_cast(binary); - c_binary->name = binary->name().c_str(); c_binary->imagebase = binary->imagebase(); init_c_header(c_binary, binary); init_c_commands(c_binary, binary); diff --git a/api/c/PE/Binary.cpp b/api/c/PE/Binary.cpp index f5a1e0a6eb..2823d141a6 100644 --- a/api/c/PE/Binary.cpp +++ b/api/c/PE/Binary.cpp @@ -34,7 +34,6 @@ namespace LIEF { namespace PE { void init_c_binary(Pe_Binary_t* c_binary, Binary* binary) { - c_binary->name = binary->name().c_str(); c_binary->handler = reinterpret_cast(binary); init_c_dos_header(c_binary, binary); diff --git a/api/python/src/Abstract/objects/pyBinary.cpp b/api/python/src/Abstract/objects/pyBinary.cpp index 66708b1d4d..1c83272950 100644 --- a/api/python/src/Abstract/objects/pyBinary.cpp +++ b/api/python/src/Abstract/objects/pyBinary.cpp @@ -71,11 +71,6 @@ void create(py::module& m) { &Binary::has_nx, "Check if the binary has ``NX`` protection (non executable stack)") - .def_property("name", - static_cast>(&Binary::name), - static_cast>(&Binary::name), - "Binary's name") - .def_property_readonly("header", &Binary::header, "Binary's abstract header (" RST_CLASS_REF(lief.Header) ")") diff --git a/api/python/src/Abstract/objects/pyParser.cpp b/api/python/src/Abstract/objects/pyParser.cpp index b5f6011478..f9849ac8b0 100644 --- a/api/python/src/Abstract/objects/pyParser.cpp +++ b/api/python/src/Abstract/objects/pyParser.cpp @@ -28,7 +28,7 @@ template<> void create(py::module& m) { m.def("parse", - [] (py::bytes bytes, const std::string& name) { + [] (py::bytes bytes) { std::string raw_str = bytes; std::vector raw = { std::make_move_iterator(std::begin(raw_str)), @@ -38,7 +38,7 @@ void create(py::module& m) { std::exception_ptr ep; Py_BEGIN_ALLOW_THREADS try { - binary = Parser::parse(std::move(raw), name); + binary = Parser::parse(std::move(raw)); } catch (...) { ep = std::current_exception(); } @@ -55,7 +55,7 @@ void create(py::module& m) { depending on the given binary format. )delim", - "raw"_a, "name"_a = "", + "raw"_a, py::return_value_policy::take_ownership); m.def("parse", @@ -86,7 +86,7 @@ void create(py::module& m) { m.def("parse", - [] (py::object byteio, const std::string& name) -> py::object { + [] (py::object byteio) -> py::object { if (auto stream = PyIOStream::from_python(byteio)) { auto ptr = std::make_unique(std::move(*stream)); py::object binary; @@ -113,7 +113,7 @@ void create(py::module& m) { depending on the given binary format. )delim", - "io"_a, "name"_a = "", + "io"_a, py::return_value_policy::take_ownership); } } diff --git a/api/python/src/ELF/objects/pyParser.cpp b/api/python/src/ELF/objects/pyParser.cpp index 225168ad38..5604452a7b 100644 --- a/api/python/src/ELF/objects/pyParser.cpp +++ b/api/python/src/ELF/objects/pyParser.cpp @@ -43,7 +43,7 @@ void create(py::module& m) { py::return_value_policy::take_ownership); m.def("parse", - static_cast(*)(const std::vector&, const std::string&, DYNSYM_COUNT_METHODS)>(&Parser::parse), + static_cast(*)(const std::vector&, DYNSYM_COUNT_METHODS)>(&Parser::parse), R"delim( Parse the ELF binary from the given **list of bytes** and return a :class:`lief.ELF.Binary` object @@ -52,15 +52,15 @@ void create(py::module& m) { :attr:`lief.ELF.DYNSYM_COUNT_METHODS.COUNT_AUTO` )delim", - "raw"_a, "name"_a = "", "dynsym_count_method"_a = DYNSYM_COUNT_METHODS::COUNT_AUTO, + "raw"_a, "dynsym_count_method"_a = DYNSYM_COUNT_METHODS::COUNT_AUTO, py::return_value_policy::take_ownership); m.def("parse", - [] (py::object byteio, const std::string& name, DYNSYM_COUNT_METHODS count) -> py::object { + [] (py::object byteio, DYNSYM_COUNT_METHODS count) -> py::object { if (auto stream = PyIOStream::from_python(byteio)) { auto ptr = std::make_unique(std::move(*stream)); - return py::cast(ELF::Parser::parse(std::move(ptr), name, count)); + return py::cast(ELF::Parser::parse(std::move(ptr), count)); } logging::log(logging::LOG_ERR, "Can't create a LIEF stream interface over the provided io"); return py::none(); @@ -72,7 +72,7 @@ void create(py::module& m) { (:class:`lief.ELF.lief.ELF.DYNSYM_COUNT_METHODS`). By default, the value is set to :attr:`lief.ELF.lief.ELF.DYNSYM_COUNT_METHODS.COUNT_AUTO` )delim", - "io"_a, "name"_a = "", "dynsym_count_method"_a = DYNSYM_COUNT_METHODS::COUNT_AUTO, + "io"_a, "dynsym_count_method"_a = DYNSYM_COUNT_METHODS::COUNT_AUTO, py::return_value_policy::take_ownership); } } diff --git a/api/python/src/MachO/objects/pyBinary.cpp b/api/python/src/MachO/objects/pyBinary.cpp index 30369ecf7e..a57c5f2c2f 100644 --- a/api/python/src/MachO/objects/pyBinary.cpp +++ b/api/python/src/MachO/objects/pyBinary.cpp @@ -128,6 +128,10 @@ void create(py::module& m) { &Binary::has_filesets, "Return ``True`` if the binary has filesets") + .def_property_readonly("fileset_name", + &Binary::fileset_name, + "Name associated with the LC_FILESET_ENTRY binary") + .def_property_readonly("imagebase", &Binary::imagebase, R"delim( diff --git a/api/python/src/MachO/objects/pyParser.cpp b/api/python/src/MachO/objects/pyParser.cpp index 46d7fff847..cdfd454dc8 100644 --- a/api/python/src/MachO/objects/pyParser.cpp +++ b/api/python/src/MachO/objects/pyParser.cpp @@ -44,14 +44,13 @@ void create(py::module& m) { m.def("parse", - static_cast (*) (const std::vector&, const std::string&, const ParserConfig&)>(&LIEF::MachO::Parser::parse), + static_cast (*) (const std::vector&, const ParserConfig&)>(&LIEF::MachO::Parser::parse), R"delim( Parse the given binary (from raw bytes) and return a :class:`~lief.MachO.FatBinary` object One can configure the parsing with the ``config`` parameter. See :class:`~lief.MachO.ParserConfig` )delim", "raw"_a, - "name"_a = "", "config"_a = ParserConfig::quick(), py::return_value_policy::take_ownership); @@ -65,7 +64,7 @@ void create(py::module& m) { py::return_value_policy::take_ownership); m.def("parse", - [] (py::object byteio, std::string name, const ParserConfig& config) -> py::object { + [] (py::object byteio, const ParserConfig& config) -> py::object { if (auto stream = PyIOStream::from_python(byteio)) { auto ptr = std::make_unique(std::move(*stream)); return py::cast(MachO::Parser::parse(std::move(ptr), config)); @@ -79,7 +78,6 @@ void create(py::module& m) { One can configure the parsing with the ``config`` parameter. See :class:`~lief.MachO.ParserConfig` )delim", "io"_a, - "name"_a = "", "config"_a = ParserConfig::quick(), py::return_value_policy::take_ownership); } diff --git a/api/python/src/OAT/objects/pyParser.cpp b/api/python/src/OAT/objects/pyParser.cpp index 8ea7493453..29308eb875 100644 --- a/api/python/src/OAT/objects/pyParser.cpp +++ b/api/python/src/OAT/objects/pyParser.cpp @@ -39,14 +39,14 @@ void create(py::module& m) { py::return_value_policy::take_ownership); m.def("parse", - static_cast (*) (std::vector, const std::string&)>(&Parser::parse), + static_cast (*) (std::vector)>(&Parser::parse), "Parse the given raw data and return a " RST_CLASS_REF(lief.OAT.Binary) " object", - "raw"_a, "name"_a = "", + "raw"_a, py::return_value_policy::take_ownership); m.def("parse", - [] (py::object byteio, const std::string& name) { + [] (py::object byteio) { const auto& io = py::module::import("io"); const auto& RawIOBase = io.attr("RawIOBase"); const auto& BufferedIOBase = io.attr("BufferedIOBase"); @@ -76,9 +76,9 @@ void create(py::module& m) { std::make_move_iterator(std::begin(raw_str)), std::make_move_iterator(std::end(raw_str))}; - return LIEF::OAT::Parser::parse(std::move(raw), name); + return LIEF::OAT::Parser::parse(std::move(raw)); }, - "io"_a, "name"_a = "", + "io"_a, py::return_value_policy::take_ownership); } } diff --git a/api/python/src/PE/CMakeLists.txt b/api/python/src/PE/CMakeLists.txt index 15d8ee1ddc..1a8efb6ba6 100644 --- a/api/python/src/PE/CMakeLists.txt +++ b/api/python/src/PE/CMakeLists.txt @@ -38,6 +38,7 @@ set(LIEF_PYTHON_PE_SRC "${CMAKE_CURRENT_LIST_DIR}/objects/pyExportEntry.cpp" "${CMAKE_CURRENT_LIST_DIR}/objects/pyRelocation.cpp" "${CMAKE_CURRENT_LIST_DIR}/objects/pyParser.cpp" + "${CMAKE_CURRENT_LIST_DIR}/objects/pyParserConfig.cpp" "${CMAKE_CURRENT_LIST_DIR}/objects/pyImportEntry.cpp" "${CMAKE_CURRENT_LIST_DIR}/objects/pyDelayImport.cpp" "${CMAKE_CURRENT_LIST_DIR}/objects/pyDelayImportEntry.cpp" diff --git a/api/python/src/PE/objects/pyBinary.cpp b/api/python/src/PE/objects/pyBinary.cpp index b45377eeab..f9741180be 100644 --- a/api/python/src/PE/objects/pyBinary.cpp +++ b/api/python/src/PE/objects/pyBinary.cpp @@ -58,8 +58,8 @@ void create(py::module& m) { init_ref_iterator(bin, "it_const_signatures"); bin - .def(py::init(), - "name"_a, "type"_a) + .def(py::init(), + "type"_a) .def_property_readonly("sections", static_cast>(&Binary::sections), diff --git a/api/python/src/PE/objects/pyParser.cpp b/api/python/src/PE/objects/pyParser.cpp index d42b932c51..7922918cd4 100644 --- a/api/python/src/PE/objects/pyParser.cpp +++ b/api/python/src/PE/objects/pyParser.cpp @@ -28,29 +28,29 @@ template<> void create(py::module& m) { m.def("parse", - static_cast (*) (const std::string&)>(&Parser::parse), + static_cast (*) (const std::string&, const ParserConfig&)>(&Parser::parse), "Parse the PE binary from the given **file path** and return a " RST_CLASS_REF(lief.PE.Binary) " object", - "filename"_a, + "filename"_a, "config"_a = ParserConfig::all(), py::return_value_policy::take_ownership); m.def("parse", - static_cast (*) (std::vector, const std::string&)>(&Parser::parse), + static_cast (*) (std::vector, const ParserConfig&)>(&Parser::parse), "Parse the PE binary from the given **list of bytes** and return a :class:`lief.PE.Binary` object", - "raw"_a, "name"_a = "", + "raw"_a, "config"_a = ParserConfig::all(), py::return_value_policy::take_ownership); m.def("parse", - [] (py::object byteio, const std::string& name) -> py::object { + [] (py::object byteio, const ParserConfig&) -> py::object { if (auto stream = PyIOStream::from_python(byteio)) { auto ptr = std::make_unique(std::move(*stream)); - return py::cast(PE::Parser::parse(std::move(ptr), name)); + return py::cast(PE::Parser::parse(std::move(ptr))); } logging::log(logging::LOG_ERR, "Can't create a LIEF stream interface over the provided io"); return py::none(); }, "Parse the PE binary from the given Python IO interface and return a :class:`lief.PE.Binary` object", - "io"_a, "name"_a = "", + "io"_a, "config"_a = ParserConfig::all(), py::return_value_policy::take_ownership); } diff --git a/api/python/src/PE/objects/pyParserConfig.cpp b/api/python/src/PE/objects/pyParserConfig.cpp new file mode 100644 index 0000000000..bc3fcb680a --- /dev/null +++ b/api/python/src/PE/objects/pyParserConfig.cpp @@ -0,0 +1,58 @@ +/* Copyright 2017 - 2023 R. Thomas + * Copyright 2017 - 2023 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include + +#include "LIEF/PE/ParserConfig.hpp" + +#include "pyPE.hpp" + +namespace LIEF { +namespace PE { + +template<> +void create(py::module& m) { + + py::class_(m, "ParserConfig", + R"delim( + This class is used to tweak the PE Parser (:class:`~lief.PE.Parser`) + )delim") + + .def(py::init<>()) + .def_readwrite("parse_signature", &ParserConfig::parse_signature, + "Parse PE Authenticode signature") + + .def_readwrite("parse_exports", &ParserConfig::parse_exports, + "Parse PE Exports Directory") + + .def_readwrite("parse_imports", &ParserConfig::parse_imports, + "Parse PE Import Directory") + + .def_readwrite("parse_rsrc", &ParserConfig::parse_rsrc, + "Parse PE resources tree") + + .def_readwrite("parse_reloc", &ParserConfig::parse_reloc, + "Parse PE relocations") + + .def_property_readonly_static("all", + [] (py::object /* self */) { return ParserConfig::all(); }, + R"delim( + Return a parser configuration such as all the objects supported by LIEF are parsed + )delim"); + +} + +} +} diff --git a/api/python/src/PE/pyPE.cpp b/api/python/src/PE/pyPE.cpp index 7a2c1e00ae..dbb4dd81ad 100644 --- a/api/python/src/PE/pyPE.cpp +++ b/api/python/src/PE/pyPE.cpp @@ -39,6 +39,7 @@ void init_python_module(py::module& m) { } void init_objects(py::module& m) { + CREATE(ParserConfig, m); CREATE(Parser, m); CREATE(DosHeader, m); diff --git a/api/python/src/PE/pyPE.hpp b/api/python/src/PE/pyPE.hpp index 1f307b8a4f..89e735d979 100644 --- a/api/python/src/PE/pyPE.hpp +++ b/api/python/src/PE/pyPE.hpp @@ -44,6 +44,7 @@ void init_objects(py::module&); void init_enums(py::module&); void init_utils(py::module&); +SPECIALIZE_CREATE(ParserConfig); SPECIALIZE_CREATE(Parser); SPECIALIZE_CREATE(Binary); diff --git a/doc/sphinx/api/cpp/macho.rst b/doc/sphinx/api/cpp/macho.rst index 77b4aef3c7..97662fb2e7 100644 --- a/doc/sphinx/api/cpp/macho.rst +++ b/doc/sphinx/api/cpp/macho.rst @@ -1,8 +1,8 @@ MachO ----- -Parsers -******* +Parser +****** .. doxygenclass:: LIEF::MachO::Parser :project: lief diff --git a/doc/sphinx/api/cpp/pe.rst b/doc/sphinx/api/cpp/pe.rst index db4b9659cb..f6414c7bad 100644 --- a/doc/sphinx/api/cpp/pe.rst +++ b/doc/sphinx/api/cpp/pe.rst @@ -1,6 +1,18 @@ PE -- +Parser +****** + +.. doxygenclass:: LIEF::PE::Parser + :project: lief + +.. doxygenstruct:: LIEF::PE::ParserConfig + :project: lief + +---------- + + Binary ****** diff --git a/doc/sphinx/api/python/pe.rst b/doc/sphinx/api/python/pe.rst index 0f8775cdaf..487ac87ba2 100644 --- a/doc/sphinx/api/python/pe.rst +++ b/doc/sphinx/api/python/pe.rst @@ -6,6 +6,11 @@ Parser .. autofunction:: lief.PE.parse +.. autoclass:: lief.PE.ParserConfig + :members: + :inherited-members: + :undoc-members: + Binary ****** diff --git a/doc/sphinx/changelog.rst b/doc/sphinx/changelog.rst index 6fa5aff30b..d3cf853be1 100644 --- a/doc/sphinx/changelog.rst +++ b/doc/sphinx/changelog.rst @@ -8,6 +8,33 @@ Changelog * Fix relocation issue when using `-Wl,--emit-relocs` (c.f. :issue:`897` / :pr:`898` by :github_user:`adamjseitz`) +:MachO: + + * The *fileset name* is now stored in :attr:`lief.MachO.Binary.fileset_name` + (instead of `lief.MachO.Binary.name`) + +:PE: + + * Add a :class:`lief.PE.ParserConfig` interface that can be used to tweak + which parts of the PE format should be parsed (:issue:`839`). + + :Example: + + .. code-block:: python + + config = lief.PE.ParserConfig() + + # Skip parsing PE authenticode + config.parse_signature = False + + pe = lief.PE.parse("pe.exe", config) + +:General Design: + + * Remove the `lief.Binary.name` attribute + + + 0.13.0 - April 9, 2023 ---------------------- diff --git a/include/LIEF/Abstract/Binary.hpp b/include/LIEF/Abstract/Binary.hpp index 8fdc0a7f02..a58c364016 100644 --- a/include/LIEF/Abstract/Binary.hpp +++ b/include/LIEF/Abstract/Binary.hpp @@ -118,11 +118,10 @@ class LIEF_API Binary : public Object { //! Binary's entrypoint (if any) virtual uint64_t entrypoint() const = 0; - //! Binary's name - const std::string& name() const; - //! Binary's original size - uint64_t original_size() const; + uint64_t original_size() const { + return original_size_; + } //! Return the functions exported by the binary functions_t exported_functions() const; @@ -164,15 +163,14 @@ class LIEF_API Binary : public Object { get_content_from_virtual_address(uint64_t virtual_address, uint64_t size, VA_TYPES addr_type = VA_TYPES::AUTO) const = 0; - //! Change the binary's name - void name(const std::string& name); - //! @brief Change binary's original size. //! //! @warning //! This function should be used carefully as some optimizations //! can be performed with this value - void original_size(uint64_t size); + void original_size(uint64_t size) { + original_size_ = size; + } //! Check if the binary is position independent virtual bool is_pie() const = 0; @@ -202,7 +200,6 @@ class LIEF_API Binary : public Object { protected: EXE_FORMATS format_ = EXE_FORMATS::FORMAT_UNKNOWN; - std::string name_; uint64_t original_size_ = 0; diff --git a/include/LIEF/Abstract/Parser.hpp b/include/LIEF/Abstract/Parser.hpp index 9ce262dbe0..1c9d057b71 100644 --- a/include/LIEF/Abstract/Parser.hpp +++ b/include/LIEF/Abstract/Parser.hpp @@ -13,8 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#ifndef LIEF_ABSTRACT_BUILDER_H -#define LIEF_ABSTRACT_BUILDER_H +#ifndef LIEF_ABSTRACT_PARSER_H +#define LIEF_ABSTRACT_PARSER_H #include #include @@ -40,20 +40,19 @@ class LIEF_API Parser { //! //! @warning If the target file is a FAT Mach-O, it will return the **last** one //! @see LIEF::MachO::Parser::parse - static std::unique_ptr parse(const std::vector& raw, const std::string& name = ""); + static std::unique_ptr parse(const std::vector& raw); //! @brief Construct an LIEF::Binary from the given stream //! //! @warning If the target file is a FAT Mach-O, it will return the **last** one //! @see LIEF::MachO::Parser::parse - static std::unique_ptr parse(std::unique_ptr stream, const std::string& name = ""); + static std::unique_ptr parse(std::unique_ptr stream); protected: Parser(const std::string& file); - uint64_t binary_size_ = 0; - std::string binary_name_; + uint64_t binary_size_ = 0; - ~Parser(); + virtual ~Parser(); Parser(); }; } diff --git a/include/LIEF/ELF/Parser.hpp b/include/LIEF/ELF/Parser.hpp index 05f585ec0e..cec7b5e4e5 100644 --- a/include/LIEF/ELF/Parser.hpp +++ b/include/LIEF/ELF/Parser.hpp @@ -69,12 +69,11 @@ class LIEF_API Parser : public LIEF::Parser { //! For weird binaries (e.g. sectionless) you can choose which method use to count dynamic symbols //! //! @param[in] data Raw ELF - //! @param[in] name Binary name (optional) //! @param[in] count_mtd Method used to count dynamic symbols. // Default: LIEF::ELF::DYNSYM_COUNT_METHODS::COUNT_AUTO //! //! @return LIEF::ELF::Binary - static std::unique_ptr parse(const std::vector& data, const std::string& name = "", + static std::unique_ptr parse(const std::vector& data, DYNSYM_COUNT_METHODS count_mtd = DYNSYM_COUNT_METHODS::COUNT_AUTO); //! Parse the ELF binary from the given stream and return a LIEF::ELF::Binary object @@ -82,12 +81,11 @@ class LIEF_API Parser : public LIEF::Parser { //! For weird binaries (e.g. sectionless) you can choose which method use to count dynamic symbols //! //! @param[in] stream The stream which wraps the ELF binary - //! @param[in] name Binary name (optional) //! @param[in] count_mtd Method used to count dynamic symbols. // Default: LIEF::ELF::DYNSYM_COUNT_METHODS::COUNT_AUTO //! //! @return LIEF::ELF::Binary - static std::unique_ptr parse(std::unique_ptr stream, const std::string& name = "", + static std::unique_ptr parse(std::unique_ptr stream, DYNSYM_COUNT_METHODS count_mtd = DYNSYM_COUNT_METHODS::COUNT_AUTO); Parser& operator=(const Parser&) = delete; @@ -104,9 +102,9 @@ class LIEF_API Parser : public LIEF::Parser { Parser(const std::vector& data, DYNSYM_COUNT_METHODS count_mtd = DYNSYM_COUNT_METHODS::COUNT_AUTO); - ~Parser(); + ~Parser() override; - ok_error_t init(const std::string& name = ""); + ok_error_t init(); bool should_swap() const; diff --git a/include/LIEF/MachO/Binary.hpp b/include/LIEF/MachO/Binary.hpp index 0ab79f8f1b..10486b6855 100644 --- a/include/LIEF/MachO/Binary.hpp +++ b/include/LIEF/MachO/Binary.hpp @@ -657,6 +657,11 @@ class LIEF_API Binary : public LIEF::Binary { //! ``true`` if the binary has a LOAD_COMMAND_TYPES::LC_FILESET_ENTRY command bool has_filesets() const; + //! Name associated with the LC_FILESET_ENTRY binary + const std::string& fileset_name() const { + return fileset_name_; + } + ~Binary() override; //! Shift the content located right after the Load commands table. @@ -739,6 +744,7 @@ class LIEF_API Binary : public LIEF::Binary { uint64_t fat_offset_ = 0; uint64_t fileset_offset_ = 0; uint64_t in_memory_base_addr_ = 0; + std::string fileset_name_; }; } // namespace MachO diff --git a/include/LIEF/MachO/Parser.hpp b/include/LIEF/MachO/Parser.hpp index dc5237c8ba..4fcaa7710a 100644 --- a/include/LIEF/MachO/Parser.hpp +++ b/include/LIEF/MachO/Parser.hpp @@ -45,7 +45,7 @@ class LIEF_API Parser : public LIEF::Parser { Parser& operator=(const Parser& copy) = delete; Parser(const Parser& copy) = delete; - ~Parser(); + ~Parser() override; //! Parse a Mach-O file from the path provided by the ``filename`` //! parameter @@ -65,10 +65,8 @@ class LIEF_API Parser : public LIEF::Parser { //! of the parser //! //! @param[in] data Mach-O file as a vector of bytes - //! @param[in] name A name for the Mach-O file //! @param[in] conf Parser configuration (Defaut: ParserConfig::deep) static std::unique_ptr parse(const std::vector& data, - const std::string& name = "", const ParserConfig& conf = ParserConfig::deep()); diff --git a/include/LIEF/OAT/Parser.hpp b/include/LIEF/OAT/Parser.hpp index 467f322323..6f977fda14 100644 --- a/include/LIEF/OAT/Parser.hpp +++ b/include/LIEF/OAT/Parser.hpp @@ -41,7 +41,7 @@ class LIEF_API Parser : public LIEF::ELF::Parser { static std::unique_ptr parse(const std::string& oat_file); static std::unique_ptr parse(const std::string& oat_file, const std::string& vdex_file); - static std::unique_ptr parse(std::vector data, const std::string& name = ""); + static std::unique_ptr parse(std::vector data); Parser& operator=(const Parser& copy) = delete; Parser(const Parser& copy) = delete; @@ -50,7 +50,7 @@ class LIEF_API Parser : public LIEF::ELF::Parser { Parser(); Parser(const std::string& oat_file); Parser(std::vector data); - ~Parser(); + ~Parser() override; inline Binary& oat_binary() { // The type of the parent binary_ is guaranteed by the constructor @@ -81,7 +81,7 @@ class LIEF_API Parser : public LIEF::ELF::Parser { template void parse_oat_methods(uint64_t methods_offsets, Class& clazz, const DEX::Class& dex_class); - void init(const std::string& name = ""); + void init(); std::unique_ptr vdex_file_; diff --git a/include/LIEF/PE/Binary.hpp b/include/LIEF/PE/Binary.hpp index c0335f47d2..a9c1094f27 100644 --- a/include/LIEF/PE/Binary.hpp +++ b/include/LIEF/PE/Binary.hpp @@ -135,7 +135,7 @@ class LIEF_API Binary : public LIEF::Binary { //! Iterator that outputs const Signature& using it_const_signatures = const_ref_iterator; - Binary(const std::string& name, PE_TYPE type); + Binary(PE_TYPE type); ~Binary() override; diff --git a/include/LIEF/PE/Parser.hpp b/include/LIEF/PE/Parser.hpp index a202de6ea7..30508eae82 100644 --- a/include/LIEF/PE/Parser.hpp +++ b/include/LIEF/PE/Parser.hpp @@ -26,6 +26,7 @@ #include "LIEF/Abstract/Parser.hpp" #include "LIEF/PE/enums.hpp" +#include "LIEF/PE/ParserConfig.hpp" namespace LIEF { class BinaryStream; @@ -73,13 +74,16 @@ class LIEF_API Parser : public LIEF::Parser { public: //! Parse a PE binary from the given filename - static std::unique_ptr parse(const std::string& filename); + static std::unique_ptr parse(const std::string& filename, + const ParserConfig& conf = ParserConfig::all()); //! Parse a PE binary from a data buffer - static std::unique_ptr parse(std::vector data, const std::string& name = ""); + static std::unique_ptr parse(std::vector data, + const ParserConfig& conf = ParserConfig::all()); //! Parse a PE binary from the given BinaryStream - static std::unique_ptr parse(std::unique_ptr stream, const std::string& name = ""); + static std::unique_ptr parse(std::unique_ptr stream, + const ParserConfig& conf = ParserConfig::all()); Parser& operator=(const Parser& copy) = delete; Parser(const Parser& copy) = delete; @@ -92,7 +96,7 @@ class LIEF_API Parser : public LIEF::Parser { ~Parser(); Parser(); - void init(const std::string& name = ""); + void init(const ParserConfig& config); template ok_error_t parse(); @@ -148,6 +152,7 @@ class LIEF_API Parser : public LIEF::Parser { std::unique_ptr binary_; std::set resource_visited_; std::unique_ptr stream_; + ParserConfig config_; }; diff --git a/include/LIEF/PE/ParserConfig.hpp b/include/LIEF/PE/ParserConfig.hpp new file mode 100644 index 0000000000..36df03b353 --- /dev/null +++ b/include/LIEF/PE/ParserConfig.hpp @@ -0,0 +1,39 @@ +/* Copyright 2017 - 2023 R. Thomas + * Copyright 2017 - 2023 Quarkslab + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef LIEF_PE_PARSER_CONFIG_H +#define LIEF_PE_PARSER_CONFIG_H +#include "LIEF/visibility.h" + +namespace LIEF { +namespace PE { + +//! This structure is used to tweak the PE Parser (PE::Parser) +struct LIEF_API ParserConfig { + static ParserConfig all() { + static ParserConfig DEFAULT; + return DEFAULT; + } + + bool parse_signature = true; ///< Parse PE Authenticode signature + bool parse_exports = true; ///< Parse PE Exports Directory + bool parse_imports = true; ///< Parse PE Import Directory + bool parse_rsrc = true; ///< Parse PE resources tree + bool parse_reloc = true; ///< Parse PE relocations +}; + +} +} +#endif diff --git a/src/Abstract/Binary.cpp b/src/Abstract/Binary.cpp index 2964e27cb3..507afbcf0b 100644 --- a/src/Abstract/Binary.cpp +++ b/src/Abstract/Binary.cpp @@ -121,26 +121,6 @@ void Binary::accept(Visitor& visitor) const { visitor.visit(*this); } -const std::string& Binary::name() const { - return name_; -} - - -uint64_t Binary::original_size() const { - return original_size_; -} - - -void Binary::name(const std::string& name) { - name_ = name; -} - - -void Binary::original_size(uint64_t size) { - original_size_ = size; -} - - std::ostream& Binary::print(std::ostream& os) const { return os; } diff --git a/src/Abstract/Parser.cpp b/src/Abstract/Parser.cpp index cce8264bba..ad384d6865 100644 --- a/src/Abstract/Parser.cpp +++ b/src/Abstract/Parser.cpp @@ -89,31 +89,31 @@ std::unique_ptr Parser::parse(const std::string& filename) { return nullptr; } -std::unique_ptr Parser::parse(const std::vector& raw, const std::string& name) { +std::unique_ptr Parser::parse(const std::vector& raw) { #if defined(LIEF_OAT_SUPPORT) if (OAT::is_oat(raw)) { - return OAT::Parser::parse(raw, name); + return OAT::Parser::parse(raw); } #endif #if defined(LIEF_ELF_SUPPORT) if (ELF::is_elf(raw)) { - return ELF::Parser::parse(raw, name); + return ELF::Parser::parse(raw); } #endif #if defined(LIEF_PE_SUPPORT) if (PE::is_pe(raw)) { - return PE::Parser::parse(raw, name); + return PE::Parser::parse(raw); } #endif #if defined(LIEF_MACHO_SUPPORT) if (MachO::is_macho(raw)) { // For fat binary we take the last one... - std::unique_ptr fat = MachO::Parser::parse(raw, name); + std::unique_ptr fat = MachO::Parser::parse(raw); if (fat != nullptr) { return fat->pop_back(); } @@ -126,18 +126,18 @@ std::unique_ptr Parser::parse(const std::vector& raw, const std } -std::unique_ptr Parser::parse(std::unique_ptr stream, const std::string& name) { +std::unique_ptr Parser::parse(std::unique_ptr stream) { #if defined(LIEF_ELF_SUPPORT) if (ELF::is_elf(*stream)) { - return ELF::Parser::parse(std::move(stream), name); + return ELF::Parser::parse(std::move(stream)); } #endif #if defined(LIEF_PE_SUPPORT) if (PE::is_pe(*stream)) { - return PE::Parser::parse(std::move(stream), name); + return PE::Parser::parse(std::move(stream)); } #endif @@ -156,9 +156,7 @@ std::unique_ptr Parser::parse(std::unique_ptr stream, cons return nullptr; } -Parser::Parser(const std::string& filename) : - binary_name_{filename} -{ +Parser::Parser(const std::string& filename) { std::ifstream file(filename, std::ios::in | std::ios::binary); if (!file) { diff --git a/src/Abstract/json.cpp b/src/Abstract/json.cpp index 96c875ef5f..1ee8f9f7cf 100644 --- a/src/Abstract/json.cpp +++ b/src/Abstract/json.cpp @@ -67,7 +67,6 @@ void AbstractJsonVisitor::visit(const Binary& binary) { } - node_["name"] = binary.name(); node_["entrypoint"] = binary.entrypoint(); node_["format"] = to_string(binary.format()); node_["original_size"] = binary.original_size(); diff --git a/src/ELF/Parser.cpp b/src/ELF/Parser.cpp index a698379935..dd622f8968 100644 --- a/src/ELF/Parser.cpp +++ b/src/ELF/Parser.cpp @@ -290,8 +290,7 @@ ELF_CLASS determine_elf_class(BinaryStream& stream) { } -ok_error_t Parser::init(const std::string& name) { - LIEF_DEBUG("Parsing binary: {}", name); +ok_error_t Parser::init() { if (stream_ == nullptr) { LIEF_ERR("Stream not properly initialized"); @@ -299,7 +298,7 @@ ok_error_t Parser::init(const std::string& name) { } binary_->original_size_ = binary_size_; - binary_->name(name); + auto res = DataHandler::Handler::from_stream(stream_); if (!res) { LIEF_ERR("The provided stream is not supported by the ELF DataHandler"); @@ -338,29 +337,29 @@ std::unique_ptr Parser::parse(const std::string& filename, DYNSYM_COUNT_ } Parser parser{filename, count_mtd}; - parser.init(filename); + parser.init(); return std::move(parser.binary_); } std::unique_ptr Parser::parse(const std::vector& data, - const std::string& name, DYNSYM_COUNT_METHODS count_mtd) { + DYNSYM_COUNT_METHODS count_mtd) { if (!is_elf(data)) { return nullptr; } Parser parser{data, count_mtd}; - parser.init(name); + parser.init(); return std::move(parser.binary_); } std::unique_ptr Parser::parse(std::unique_ptr stream, - const std::string& name, DYNSYM_COUNT_METHODS count_mtd) { + DYNSYM_COUNT_METHODS count_mtd) { if (!is_elf(*stream)) { return nullptr; } Parser parser{std::move(stream), count_mtd}; - parser.init(name); + parser.init(); return std::move(parser.binary_); } diff --git a/src/ELF/json.cpp b/src/ELF/json.cpp index e536ec3458..d2e00aa83d 100644 --- a/src/ELF/json.cpp +++ b/src/ELF/json.cpp @@ -120,7 +120,6 @@ void JsonVisitor::visit(const Binary& binary) { notes.emplace_back(visitor.get()); } - node_["name"] = binary.name(); node_["entrypoint"] = binary.entrypoint(); node_["imagebase"] = binary.imagebase(); node_["virtual_size"] = binary.virtual_size(); diff --git a/src/MachO/BinaryParser.cpp b/src/MachO/BinaryParser.cpp index 3b4247b57e..4c63f22d99 100644 --- a/src/MachO/BinaryParser.cpp +++ b/src/MachO/BinaryParser.cpp @@ -62,7 +62,6 @@ std::unique_ptr BinaryParser::parse(const std::string& file, const Parse parser.config_ = conf; parser.stream_ = std::make_unique(std::move(*stream)); parser.binary_ = std::unique_ptr(new Binary{}); - parser.binary_->name_ = file; parser.binary_->fat_offset_ = 0; if(!parser.init_and_parse()) { diff --git a/src/MachO/BinaryParser.tcc b/src/MachO/BinaryParser.tcc index 5d46c5f63a..b638b886a4 100644 --- a/src/MachO/BinaryParser.tcc +++ b/src/MachO/BinaryParser.tcc @@ -939,7 +939,7 @@ ok_error_t BinaryParser::parse_load_commands() { if (bp.binary_ != nullptr) { std::unique_ptr filset_bin = std::move(bp.binary_); - filset_bin->name_ = *entry_name; + filset_bin->fileset_name_ = *entry_name; binary_->filesets_.push_back(std::move(filset_bin)); } break; diff --git a/src/MachO/Parser.cpp b/src/MachO/Parser.cpp index 5e5882bad2..0a4bb0afa4 100644 --- a/src/MachO/Parser.cpp +++ b/src/MachO/Parser.cpp @@ -54,7 +54,8 @@ Parser::Parser(const std::string& file, const ParserConfig& conf) : } -std::unique_ptr Parser::parse(const std::string& filename, const ParserConfig& conf) { +std::unique_ptr Parser::parse(const std::string& filename, + const ParserConfig& conf) { if (!is_macho(filename)) { LIEF_ERR("{} is not a MachO file", filename); return nullptr; @@ -62,9 +63,6 @@ std::unique_ptr Parser::parse(const std::string& filename, const Pars Parser parser{filename, conf}; parser.build(); - for (std::unique_ptr& binary : parser.binaries_) { - binary->name(filename); - } return std::unique_ptr(new FatBinary{std::move(parser.binaries_)}); } @@ -76,7 +74,7 @@ Parser::Parser(std::vector data, const ParserConfig& conf) : std::unique_ptr Parser::parse(const std::vector& data, - const std::string& name, const ParserConfig& conf) { + const ParserConfig& conf) { if (!is_macho(data)) { LIEF_ERR("The provided data seem not being related to a MachO binary"); return nullptr; @@ -84,14 +82,11 @@ std::unique_ptr Parser::parse(const std::vector& data, Parser parser{data, conf}; parser.build(); - - for (std::unique_ptr& binary : parser.binaries_) { - binary->name(name); - } return std::unique_ptr(new FatBinary{std::move(parser.binaries_)}); } -std::unique_ptr Parser::parse(std::unique_ptr stream, const ParserConfig& conf) { +std::unique_ptr Parser::parse(std::unique_ptr stream, + const ParserConfig& conf) { { ScopedStream scoped(*stream, 0); if (!is_macho(*stream)) { @@ -140,8 +135,6 @@ std::unique_ptr Parser::parse_from_memory(uintptr_t address, const Pa return parse_from_memory(address, MAX_SIZE, conf); } - - ok_error_t Parser::build_fat() { static constexpr size_t MAX_FAT_ARCH = 10; stream_->setpos(0); diff --git a/src/MachO/json.cpp b/src/MachO/json.cpp index 4d90ab469c..d5d45e82c1 100644 --- a/src/MachO/json.cpp +++ b/src/MachO/json.cpp @@ -149,7 +149,6 @@ void JsonVisitor::visit(const SegmentCommand& segment) { } visit(*segment.as()); - node_["name"] = segment.name(); node_["virtual_address"] = segment.virtual_address(); node_["virtual_size"] = segment.virtual_size(); node_["file_size"] = segment.file_size(); diff --git a/src/OAT/Parser.cpp b/src/OAT/Parser.cpp index 4496edbb27..9b93bebfd3 100644 --- a/src/OAT/Parser.cpp +++ b/src/OAT/Parser.cpp @@ -43,7 +43,7 @@ std::unique_ptr Parser::parse(const std::string& oat_file) { } Parser parser{oat_file}; - parser.init(oat_file); + parser.init(); std::unique_ptr oat_binary{static_cast(parser.binary_.release())}; return oat_binary; @@ -65,15 +65,15 @@ std::unique_ptr Parser::parse(const std::string& oat_file, const std::st } else { LIEF_WARN("Can't parse the VDEX file '{}'", vdex_file); } - parser.init(oat_file); + parser.init(); std::unique_ptr oat_binary{static_cast(parser.binary_.release())}; return oat_binary; } -std::unique_ptr Parser::parse(std::vector data, const std::string& name) { +std::unique_ptr Parser::parse(std::vector data) { Parser parser{std::move(data)}; - parser.init(name); + parser.init(); std::unique_ptr oat_binary{static_cast(parser.binary_.release())}; return oat_binary; } @@ -103,9 +103,8 @@ void Parser::set_vdex(std::unique_ptr file) { } -void Parser::init(const std::string& name) { - LIEF_DEBUG("Parsing {}", name); - ELF::Parser::init(name); +void Parser::init() { + ELF::Parser::init(); oat_version_t version = OAT::version(oat_binary()); Binary& oat_bin = oat_binary(); oat_bin.vdex_ = std::move(vdex_file_); diff --git a/src/PE/Binary.cpp b/src/PE/Binary.cpp index 1918f06226..302496a0e1 100644 --- a/src/PE/Binary.cpp +++ b/src/PE/Binary.cpp @@ -61,11 +61,10 @@ PE_TYPE Binary::type() const { return type_; } -Binary::Binary(const std::string& name, PE_TYPE type) : +Binary::Binary(PE_TYPE type) : type_{type} { format_ = LIEF::EXE_FORMATS::FORMAT_PE; - name_ = name; Header& hdr = header(); size_t sizeof_headers = dos_header().addressof_new_exeheader() + sizeof(details::pe_header) + diff --git a/src/PE/Parser.cpp b/src/PE/Parser.cpp index fabc0da441..3eb00fabcd 100644 --- a/src/PE/Parser.cpp +++ b/src/PE/Parser.cpp @@ -62,7 +62,6 @@ constexpr size_t Parser::MAX_DATA_SIZE; Parser::~Parser() = default; Parser::Parser() = default; - Parser::Parser(const std::string& file) : LIEF::Parser{file} { @@ -78,11 +77,12 @@ Parser::Parser(std::vector data) : {} -Parser::Parser(std::unique_ptr stream) : stream_{std::move(stream)} +Parser::Parser(std::unique_ptr stream) + : stream_{std::move(stream)} {} -void Parser::init(const std::string& name) { +void Parser::init(const ParserConfig& config) { stream_->setpos(0); auto type = get_type_from_stream(*stream_); if (!type) { @@ -91,8 +91,8 @@ void Parser::init(const std::string& name) { } type_ = type.value(); binary_ = std::unique_ptr(new Binary{}); - binary_->name(name); binary_->type_ = type_; + config_ = config; if (type_ == PE_TYPE::PE32) { parse(); @@ -1100,32 +1100,35 @@ result Parser::checksum() { // // Return the Binary constructed // -std::unique_ptr Parser::parse(const std::string& filename) { +std::unique_ptr Parser::parse(const std::string& filename, + const ParserConfig& conf) { if (!is_pe(filename)) { return nullptr; } Parser parser{filename}; - parser.init(filename); + parser.init(conf); return std::move(parser.binary_); } -std::unique_ptr Parser::parse(std::vector data, const std::string& name) { +std::unique_ptr Parser::parse(std::vector data, + const ParserConfig& conf) { if (!is_pe(data)) { return nullptr; } Parser parser{std::move(data)}; - parser.init(name); + parser.init(conf); return std::move(parser.binary_); } -std::unique_ptr Parser::parse(std::unique_ptr stream, const std::string& name) { +std::unique_ptr Parser::parse(std::unique_ptr stream, + const ParserConfig& conf) { if (!is_pe(*stream)) { return nullptr; } Parser parser{std::move(stream)}; - parser.init(name); + parser.init(conf); return std::move(parser.binary_); } diff --git a/src/PE/Parser.tcc b/src/PE/Parser.tcc index d9dbf81a68..b65a6d641b 100644 --- a/src/PE/Parser.tcc +++ b/src/PE/Parser.tcc @@ -153,7 +153,7 @@ ok_error_t Parser::parse_data_directories() { // Import Table DataDirectory& import_data_dir = binary_->data_directory(DATA_DIRECTORY::IMPORT_TABLE); - if (import_data_dir.RVA() > 0) { + if (import_data_dir.RVA() > 0 && config_.parse_imports) { LIEF_DEBUG("Processing Import Table"); if (import_data_dir.has_section()) { import_data_dir.section()->add_type(PE_SECTION_TYPES::IMPORT); @@ -162,13 +162,15 @@ ok_error_t Parser::parse_data_directories() { } // Exports - if (binary_->data_directory(DATA_DIRECTORY::EXPORT_TABLE).RVA() > 0) { + if (binary_->data_directory(DATA_DIRECTORY::EXPORT_TABLE).RVA() > 0 && + config_.parse_exports) { LIEF_DEBUG("[+] Processing Exports"); parse_exports(); } // Signature - if (binary_->data_directory(DATA_DIRECTORY::CERTIFICATE_TABLE).RVA() > 0) { + if (binary_->data_directory(DATA_DIRECTORY::CERTIFICATE_TABLE).RVA() > 0 && + config_.parse_signature) { parse_signature(); } @@ -196,7 +198,7 @@ ok_error_t Parser::parse_data_directories() { { DataDirectory& reloc_data_dir = binary_->data_directory(DATA_DIRECTORY::BASE_RELOCATION_TABLE); - if (reloc_data_dir.RVA() > 0) { + if (reloc_data_dir.RVA() > 0 && config_.parse_reloc) { LIEF_DEBUG("Processing Relocations"); if (reloc_data_dir.has_section()) { reloc_data_dir.section()->add_type(PE_SECTION_TYPES::RELOCATION); @@ -217,7 +219,7 @@ ok_error_t Parser::parse_data_directories() { } { DataDirectory& res_data_dir = binary_->data_directory(DATA_DIRECTORY::RESOURCE_TABLE); - if (res_data_dir.RVA() > 0) { + if (res_data_dir.RVA() > 0 && config_.parse_rsrc) { LIEF_DEBUG("Processing Resources"); if (res_data_dir.has_section()) { res_data_dir.section()->add_type(PE_SECTION_TYPES::RESOURCE); diff --git a/src/PE/json.cpp b/src/PE/json.cpp index 614bbfbf44..4b314cd1ee 100644 --- a/src/PE/json.cpp +++ b/src/PE/json.cpp @@ -46,7 +46,6 @@ std::string escape_non_ascii(const std::string& s) { } void JsonVisitor::visit(const Binary& binary) { - node_["name"] = binary.name(); node_["entrypoint"] = binary.entrypoint(); node_["virtual_size"] = binary.virtual_size(); diff --git a/tests/elf/test_equality.py b/tests/elf/test_equality.py index 01015b32b9..22f0d91a4f 100644 --- a/tests/elf/test_equality.py +++ b/tests/elf/test_equality.py @@ -10,8 +10,9 @@ "ELF/ELF32_x86_binary_all.bin" ]) def test_equal(tmp_path: Path, elf): - inelf = lief.parse(get_sample(elf)) - output = tmp_path / Path(inelf.name).name + infile = get_sample(elf) + inelf = lief.parse(infile) + output = tmp_path / Path(infile).name inelf.write(output.as_posix()) newelf = lief.parse(output.as_posix()) diff --git a/tests/pe/test_imphash.py b/tests/pe/test_imphash.py index 06b5a728aa..72fb3ee0fe 100644 --- a/tests/pe/test_imphash.py +++ b/tests/pe/test_imphash.py @@ -10,7 +10,7 @@ def test_without_imports(): """ By convention if a binary hasn't import, imphash is '0' """ - binary = lief.PE.Binary("test_imphash", lief.PE.PE_TYPE.PE32) + binary = lief.PE.Binary(lief.PE.PE_TYPE.PE32) assert int(lief.PE.get_imphash(binary), 16) == 0 @@ -18,8 +18,8 @@ def test_casse(): """ Test that casse doesn't change the hash """ - binary_lhs = lief.PE.Binary("test_imphash_lhs", lief.PE.PE_TYPE.PE32) - binary_rhs = lief.PE.Binary("test_imphash_rhs", lief.PE.PE_TYPE.PE32) + binary_lhs = lief.PE.Binary(lief.PE.PE_TYPE.PE32) + binary_rhs = lief.PE.Binary(lief.PE.PE_TYPE.PE32) kernel32_lhs = binary_lhs.add_library("KERNEL32.dll") kernel32_lhs.add_entry("CreateMutexA") @@ -34,8 +34,8 @@ def test_order(): """ Test that import order doesn't change the hash """ - binary_lhs = lief.PE.Binary("test_imphash_lhs", lief.PE.PE_TYPE.PE32) - binary_rhs = lief.PE.Binary("test_imphash_rhs", lief.PE.PE_TYPE.PE32) + binary_lhs = lief.PE.Binary(lief.PE.PE_TYPE.PE32) + binary_rhs = lief.PE.Binary(lief.PE.PE_TYPE.PE32) fonctions = ["GetStringTypeW", "LCMapStringW", "GetCommandLineA", "TerminateProcess"] kernel32_lhs = binary_lhs.add_library("kernel32.dll") @@ -54,8 +54,8 @@ def test_ordinal(): """ Test import by ordinal """ - binary_lhs = lief.PE.Binary("test_imphash_lhs", lief.PE.PE_TYPE.PE32) - binary_rhs = lief.PE.Binary("test_imphash_lhs", lief.PE.PE_TYPE.PE32) + binary_lhs = lief.PE.Binary(lief.PE.PE_TYPE.PE32) + binary_rhs = lief.PE.Binary(lief.PE.PE_TYPE.PE32) fonctions = [ "GetStringTypeW", @@ -82,8 +82,8 @@ def test_order_2(): """ Test that import order doesn't change the hash (More complex) """ - binary_lhs = lief.PE.Binary("test_imphash_lhs", lief.PE.PE_TYPE.PE32) - binary_rhs = lief.PE.Binary("test_imphash_rhs", lief.PE.PE_TYPE.PE32) + binary_lhs = lief.PE.Binary(lief.PE.PE_TYPE.PE32) + binary_rhs = lief.PE.Binary(lief.PE.PE_TYPE.PE32) libraries = { @@ -133,8 +133,8 @@ def test_different(): Check that different imports have different hashes """ - binary_lhs = lief.PE.Binary("test_imphash_lhs", lief.PE.PE_TYPE.PE32) - binary_rhs = lief.PE.Binary("test_imphash_rhs", lief.PE.PE_TYPE.PE32) + binary_lhs = lief.PE.Binary(lief.PE.PE_TYPE.PE32) + binary_rhs = lief.PE.Binary(lief.PE.PE_TYPE.PE32) libraries = { diff --git a/tests/pe/test_parser.py b/tests/pe/test_parser.py index 9f6c8c65ad..3031dcbfba 100644 --- a/tests/pe/test_parser.py +++ b/tests/pe/test_parser.py @@ -420,7 +420,6 @@ def test_relocations(): def test_symbols(): - symbols = winhello64.symbols assert len(symbols) == 1097 @@ -434,3 +433,20 @@ def test_symbols(): def test_checksum(): assert atapi.optional_header.computed_checksum == atapi.optional_header.checksum assert winhello64.optional_header.computed_checksum == winhello64.optional_header.checksum + + +def test_config(): + + config = lief.PE.ParserConfig() + config.parse_signature = False + config.parse_imports = False + config.parse_rsrc = False + config.parse_reloc = False + + fpath = get_sample("PE/PE32_x86-64_binary_avast-free-antivirus-setup-online.exe") + avast = lief.PE.parse(fpath, config) + + assert len(avast.imports) == 0 + assert len(avast.relocations) == 0 + assert len(avast.signatures) == 0 + assert avast.resources is None