From b54bece30db45abb029d32eebf4e7e14cadf5977 Mon Sep 17 00:00:00 2001 From: Romain Thomas Date: Sat, 8 Apr 2023 14:46:31 +0200 Subject: [PATCH] Resolve #291 --- api/python/src/MachO/objects/pyBinary.cpp | 6 ++++++ doc/sphinx/changelog.rst | 1 + include/LIEF/MachO/Binary.hpp | 9 +++++++++ include/LIEF/iterators.hpp | 4 ++-- src/MachO/Binary.cpp | 12 ++++++++++++ tests/macho/test_generic.py | 7 +++++++ 6 files changed, 37 insertions(+), 2 deletions(-) diff --git a/api/python/src/MachO/objects/pyBinary.cpp b/api/python/src/MachO/objects/pyBinary.cpp index bf6ff6a3..30369ecf 100644 --- a/api/python/src/MachO/objects/pyBinary.cpp +++ b/api/python/src/MachO/objects/pyBinary.cpp @@ -53,6 +53,7 @@ void create(py::module& m) { init_ref_iterator(bin, "it_segments"); init_ref_iterator(bin, "it_libraries"); init_ref_iterator(bin, "it_relocations"); + init_ref_iterator(bin, "it_rpaths"); py::class_(bin, "range_t") .def_readwrite("start", &Binary::range_t::start) @@ -253,6 +254,11 @@ void create(py::module& m) { "Return the binary's " RST_CLASS_REF(lief.MachO.RPathCommand) " if any, or None", py::return_value_policy::reference) + .def_property_readonly("rpaths", + static_cast>(&Binary::rpaths), + "Return an iterator over the binary's " RST_CLASS_REF(lief.MachO.RPathCommand) "", + py::return_value_policy::reference_internal) + .def_property_readonly("has_symbol_command", &Binary::has_symbol_command, "``True`` if the binary has a " RST_CLASS_REF(lief.MachO.SymbolCommand) " command.") diff --git a/doc/sphinx/changelog.rst b/doc/sphinx/changelog.rst index b090985c..1c04ff3f 100644 --- a/doc/sphinx/changelog.rst +++ b/doc/sphinx/changelog.rst @@ -60,6 +60,7 @@ Changelog :MachO: + * Add :attr:`~lief.MachO.Binary.rpaths` iterator (:issue:`291`) * Add support for parsing Mach-O in memory * Fix a memory issue (found by :github_user:`bladchan` via :issue:`806`) * [CVE-2022-40923] Fix parsing issue (:issue:`784` found by :github_user:`bladchan`) diff --git a/include/LIEF/MachO/Binary.hpp b/include/LIEF/MachO/Binary.hpp index 330268ba..0ab79f8f 100644 --- a/include/LIEF/MachO/Binary.hpp +++ b/include/LIEF/MachO/Binary.hpp @@ -164,6 +164,11 @@ class LIEF_API Binary : public LIEF::Binary { //! Iterator which outputs const Relocation& using it_const_relocations = const_ref_iterator; + //! Iterator which outputs RPathCommand& + using it_rpaths = filter_iterator; + + //! Iterator which outputs const RPathCommand& + using it_const_rpaths = const_filter_iterator; public: Binary(const Binary&) = delete; @@ -514,6 +519,10 @@ class LIEF_API Binary : public LIEF::Binary { RPathCommand* rpath(); const RPathCommand* rpath() const; + //! Iterator over **all** the MachO::RPathCommand commands. + it_rpaths rpaths(); + it_const_rpaths rpaths() const; + //! ``true`` if the binary has a MachO::SymbolCommand command. bool has_symbol_command() const; diff --git a/include/LIEF/iterators.hpp b/include/LIEF/iterators.hpp index 247d18a3..cff103d7 100644 --- a/include/LIEF/iterators.hpp +++ b/include/LIEF/iterators.hpp @@ -229,7 +229,7 @@ class ref_iterator { typename std::enable_if::value, add_const_t>::type operator*() const { assert(*it_ && "integrity error: nullptr"); - return const_cast>(**it_); + return const_cast>(static_cast(**it_)); } template @@ -395,7 +395,7 @@ class filter_iterator { typename std::enable_if::value, add_const_t>::type operator*() const { assert(*it_ && "integrity error: nullptr"); - return const_cast>(**it_); + return const_cast>(static_cast(**it_)); } template diff --git a/src/MachO/Binary.cpp b/src/MachO/Binary.cpp index e96acca3..43c9ee6b 100644 --- a/src/MachO/Binary.cpp +++ b/src/MachO/Binary.cpp @@ -2276,6 +2276,18 @@ const RPathCommand* Binary::rpath() const { return command(); } +Binary::it_rpaths Binary::rpaths() { + return {commands_, [] (const std::unique_ptr& cmd) { + return RPathCommand::classof(cmd.get()); + }}; +} + +Binary::it_const_rpaths Binary::rpaths() const { + return {commands_, [] (const std::unique_ptr& cmd) { + return RPathCommand::classof(cmd.get()); + }}; +} + // SymbolCommand command // +++++++++++++++++++++ bool Binary::has_symbol_command() const { diff --git a/tests/macho/test_generic.py b/tests/macho/test_generic.py index 32b0a96a..660daf34 100644 --- a/tests/macho/test_generic.py +++ b/tests/macho/test_generic.py @@ -48,6 +48,13 @@ def test_rpath_cmd(): rpathmacho = lief.parse(get_sample('MachO/MachO64_x86-64_binary_rpathtest.bin')) assert rpathmacho.rpath.path == "@executable_path/../lib" +def test_rpaths(): + macho = lief.parse(get_sample('MachO/rpath_291.bin')) + assert len(macho.rpaths) == 2 + + assert macho.rpaths[0].path == "/tmp" + assert macho.rpaths[1].path == "/var" + def test_relocations(): helloworld = lief.parse(get_sample('MachO/MachO64_x86-64_object_HelloWorld64.o'))