mirror of
https://github.com/QuasarApp/LIEF.git
synced 2025-05-11 11:09:32 +00:00
Add API to remove dynamic entries (ELF)
API Changes (Python / C++): * lief.ELF.Binary.remove(DynamicEntry / DYNAMIC_TAGS) - Added * lief.ELF.Binary.remove_library
This commit is contained in:
parent
7dce0f30ac
commit
1e410e6c95
api/python/ELF/objects
include/LIEF/ELF
src/ELF
tests/elf
@ -292,6 +292,16 @@ void init_ELF_Binary_class(py::module& m) {
|
||||
"segment"_a, "size"_a,
|
||||
py::return_value_policy::reference)
|
||||
|
||||
.def("remove",
|
||||
static_cast<void (Binary::*)(const DynamicEntry&)>(&Binary::remove),
|
||||
"Remove the given " RST_CLASS_REF(lief.ELF.DynamicEntry) " from the dynamic table",
|
||||
"dynamic_entry"_a)
|
||||
|
||||
.def("remove",
|
||||
static_cast<void (Binary::*)(DYNAMIC_TAGS)>(&Binary::remove),
|
||||
"Remove **all** " RST_CLASS_REF(lief.ELF.DynamicEntry) " with the given " RST_CLASS_REF(lief.ELF.DYNAMIC_TAGS) "",
|
||||
"tag"_a)
|
||||
|
||||
.def_property_readonly("has_notes",
|
||||
&Binary::has_notes,
|
||||
"``True`` if the binary contains notes")
|
||||
@ -338,6 +348,11 @@ void init_ELF_Binary_class(py::module& m) {
|
||||
"Check if the given library name exists in the current binary",
|
||||
"library_name"_a)
|
||||
|
||||
.def("remove_library",
|
||||
&Binary::remove_library,
|
||||
"Remove the given library",
|
||||
"library_name"_a)
|
||||
|
||||
.def("get_library",
|
||||
static_cast<no_const_func<DynamicEntryLibrary&, const std::string&>>(&Binary::get_library),
|
||||
"Return the " RST_CLASS_REF(lief.ELF.DynamicEntryLibrary) " with the given ``name``",
|
||||
@ -350,6 +365,9 @@ void init_ELF_Binary_class(py::module& m) {
|
||||
|
||||
.def(py::self += DynamicEntry())
|
||||
|
||||
.def(py::self -= DynamicEntry())
|
||||
.def(py::self -= DYNAMIC_TAGS())
|
||||
|
||||
.def("__getitem__",
|
||||
static_cast<Segment& (Binary::*)(SEGMENT_TYPES)>(&Binary::operator[]),
|
||||
"",
|
||||
|
@ -101,8 +101,15 @@ class DLL_PUBLIC Binary : public LIEF::Binary {
|
||||
it_dynamic_entries dynamic_entries(void);
|
||||
it_const_dynamic_entries dynamic_entries(void) const;
|
||||
|
||||
//! @brief Add the given dynamic entry and return the entry added
|
||||
DynamicEntry& add(const DynamicEntry& entry);
|
||||
|
||||
//! @brief Remove the given dynamic entry
|
||||
void remove(const DynamicEntry& entry);
|
||||
|
||||
//! @brief Remove **all** dynamic entries with the given tag
|
||||
void remove(DYNAMIC_TAGS tag);
|
||||
|
||||
//! @brief Return binary's dynamic symbols
|
||||
it_symbols dynamic_symbols(void);
|
||||
it_const_symbols dynamic_symbols(void) const;
|
||||
@ -257,6 +264,9 @@ class DLL_PUBLIC Binary : public LIEF::Binary {
|
||||
//! @brief Add a library as dependency
|
||||
DynamicEntryLibrary& add_library(const std::string& library_name);
|
||||
|
||||
//! @brief Remove the given library
|
||||
void remove_library(const std::string& library_name);
|
||||
|
||||
//! @brief Get the library object (DynamicEntryLibrary) from the given name
|
||||
DynamicEntryLibrary& get_library(const std::string& library_name);
|
||||
|
||||
@ -404,6 +414,9 @@ class DLL_PUBLIC Binary : public LIEF::Binary {
|
||||
Binary& operator+=(const Section& section);
|
||||
Binary& operator+=(const Segment& segment);
|
||||
|
||||
Binary& operator-=(const DynamicEntry& entry);
|
||||
Binary& operator-=(DYNAMIC_TAGS tag);
|
||||
|
||||
Segment& operator[](SEGMENT_TYPES type);
|
||||
const Segment& operator[](SEGMENT_TYPES type) const;
|
||||
|
||||
|
@ -137,11 +137,11 @@ std::vector<std::string> Binary::get_abstract_imported_libraries(void) const {
|
||||
// ===============
|
||||
|
||||
it_dynamic_entries Binary::dynamic_entries(void) {
|
||||
return it_dynamic_entries{std::ref(this->dynamic_entries_)};
|
||||
return this->dynamic_entries_;
|
||||
}
|
||||
|
||||
it_const_dynamic_entries Binary::dynamic_entries(void) const {
|
||||
return it_const_dynamic_entries{std::cref(this->dynamic_entries_)};
|
||||
return this->dynamic_entries_;
|
||||
}
|
||||
|
||||
|
||||
@ -211,6 +211,38 @@ DynamicEntry& Binary::add(const DynamicEntry& entry) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
void Binary::remove(const DynamicEntry& entry) {
|
||||
auto&& it_entry = std::find_if(
|
||||
std::begin(this->dynamic_entries_),
|
||||
std::end(this->dynamic_entries_),
|
||||
[&entry] (const DynamicEntry* e) {
|
||||
return *e == entry;
|
||||
});
|
||||
|
||||
if (it_entry == std::end(this->dynamic_entries_)) {
|
||||
std::stringstream ss;
|
||||
ss << entry;
|
||||
throw not_found("Can't find '" + ss.str() + "' in the dynamic table!");
|
||||
}
|
||||
|
||||
delete *it_entry;
|
||||
this->dynamic_entries_.erase(it_entry);
|
||||
}
|
||||
|
||||
|
||||
void Binary::remove(DYNAMIC_TAGS tag) {
|
||||
for (auto&& it = std::begin(this->dynamic_entries_);
|
||||
it != std::end(this->dynamic_entries_);) {
|
||||
if ((*it)->tag() == tag) {
|
||||
delete *it;
|
||||
it = this->dynamic_entries_.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Symbols
|
||||
// =======
|
||||
|
||||
@ -1606,6 +1638,11 @@ DynamicEntryLibrary& Binary::add_library(const std::string& library_name) {
|
||||
}
|
||||
|
||||
|
||||
void Binary::remove_library(const std::string& library_name) {
|
||||
this->remove(this->get_library(library_name));
|
||||
}
|
||||
|
||||
|
||||
DynamicEntryLibrary& Binary::get_library(const std::string& library_name) {
|
||||
return const_cast<DynamicEntryLibrary&>(static_cast<const Binary*>(this)->get_library(library_name));
|
||||
}
|
||||
@ -1636,7 +1673,8 @@ bool Binary::has_library(const std::string& name) const {
|
||||
return it_needed != std::end(this->dynamic_entries_);
|
||||
}
|
||||
|
||||
|
||||
// Operator+=
|
||||
// ==========
|
||||
Binary& Binary::operator+=(const DynamicEntry& entry) {
|
||||
this->add(entry);
|
||||
return *this;
|
||||
@ -1652,7 +1690,20 @@ Binary& Binary::operator+=(const Segment& segment) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Operator -=
|
||||
// ===========
|
||||
Binary& Binary::operator-=(const DynamicEntry& entry) {
|
||||
this->remove(entry);
|
||||
return *this;
|
||||
}
|
||||
|
||||
Binary& Binary::operator-=(DYNAMIC_TAGS tag) {
|
||||
this->remove(tag);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Operator[]
|
||||
// ==========
|
||||
Segment& Binary::operator[](SEGMENT_TYPES type) {
|
||||
return this->get(type);
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ void DynamicEntry::array(const std::vector<uint64_t>&) {
|
||||
}
|
||||
|
||||
void DynamicEntry::accept(Visitor& visitor) const {
|
||||
visitor.visit(*this); // Double dispatch to avoid down-casting
|
||||
visitor(*this); // Double dispatch to avoid down-casting
|
||||
visitor.visit(this->value());
|
||||
visitor.visit(this->tag());
|
||||
}
|
||||
|
@ -123,12 +123,41 @@ class LibAddSample(object):
|
||||
if os.path.isdir(self.directory):
|
||||
shutil.rmtree(self.directory)
|
||||
|
||||
def __del__(self):
|
||||
self.remove()
|
||||
|
||||
|
||||
class TestDynamic(TestCase):
|
||||
def setUp(self):
|
||||
self.logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def test_remove_library(self):
|
||||
sample = LibAddSample()
|
||||
libadd = lief.parse(sample.libadd)
|
||||
binadd = lief.parse(sample.binadd)
|
||||
|
||||
libadd_needed = binadd.get_library("libadd.so")
|
||||
binadd -= libadd_needed
|
||||
self.assertFalse(binadd.has_library("libadd.so"))
|
||||
|
||||
|
||||
def test_remove_tag(self):
|
||||
sample = LibAddSample()
|
||||
libadd = lief.parse(sample.libadd)
|
||||
binadd = lief.parse(sample.binadd)
|
||||
self.logger.debug("BEFORE")
|
||||
list(map(lambda e : self.logger.debug(e), binadd.dynamic_entries))
|
||||
self.logger.debug("")
|
||||
binadd -= lief.ELF.DYNAMIC_TAGS.NEEDED
|
||||
|
||||
self.logger.debug("AFTER")
|
||||
list(map(lambda e : self.logger.debug(e), binadd.dynamic_entries))
|
||||
self.logger.debug("")
|
||||
|
||||
self.assertTrue(all(e.tag != lief.ELF.DYNAMIC_TAGS.NEEDED for e in binadd.dynamic_entries))
|
||||
|
||||
|
||||
@unittest.skipUnless(sys.platform.startswith("linux"), "requires Linux")
|
||||
def test_change_libname(self):
|
||||
sample = LibAddSample()
|
||||
|
Loading…
x
Reference in New Issue
Block a user