Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Enable ELF notes modifications
  • Loading branch information
romainthomas committed Oct 2, 2017
1 parent 735f58d commit 3be9dd0
Show file tree
Hide file tree
Showing 15 changed files with 539 additions and 35 deletions.
4 changes: 3 additions & 1 deletion .appveyor.yml
Expand Up @@ -107,7 +107,9 @@ build_script:
- cmake --build . --config Release --target ALL_BUILD -- /v:m /logger:%MSBuildLogger%

test_script:
- cmake --build . --config Release --target RUN_TESTS -- /v:m /logger:%MSBuildLogger%
- cmake --build . --config Release --target lief_samples -- /v:m /logger:%MSBuildLogger%
- cmake .
- cmake --build . --config Release --target check-lief -- /v:m /logger:%MSBuildLogger%

after_build:
- cmake --build . --config Release --target package -- /v:m /logger:%MSBuildLogger%
Expand Down
53 changes: 51 additions & 2 deletions api/python/ELF/objects/pyBinary.cpp
Expand Up @@ -213,6 +213,12 @@ void init_ELF_Binary_class(py::module& m) {
"type"_a,
py::return_value_policy::reference)

.def("get",
static_cast<no_const_func<Note&, NOTE_TYPES>>(&Binary::get),
"Return **first** binary's " RST_CLASS_REF(lief.ELF.Note) " given its " RST_CLASS_REF(lief.ELF.NOTE_TYPES) "",
"type"_a,
py::return_value_policy::reference)

.def("has",
static_cast<bool (Binary::*)(DYNAMIC_TAGS) const>(&Binary::has),
"Check if the " RST_CLASS_REF(lief.ELF.DynamicEntry) " associated with the given " RST_CLASS_REF(lief.ELF.DYNAMIC_TAGS) " exists",
Expand All @@ -223,6 +229,11 @@ void init_ELF_Binary_class(py::module& m) {
"Check if a " RST_CLASS_REF(lief.ELF.Segment) " of *type* (" RST_CLASS_REF(lief.ELF.SEGMENT_TYPES) ") exists",
"type"_a)

.def("has",
static_cast<bool (Binary::*)(NOTE_TYPES) const>(&Binary::has),
"Check if a " RST_CLASS_REF(lief.ELF.Note) " of *type* (" RST_CLASS_REF(lief.ELF.NOTE_TYPES) ") exists",
"type"_a)

.def("patch_pltgot",
static_cast<void (Binary::*) (const std::string&, uint64_t)>(&Binary::patch_pltgot),
"Patch the imported symbol's name with the ``address``",
Expand Down Expand Up @@ -274,6 +285,12 @@ void init_ELF_Binary_class(py::module& m) {
"segment"_a, "base"_a = 0,
py::return_value_policy::reference)

.def("add",
static_cast<Note& (Binary::*)(const Note&)>(&Binary::add),
"Add a new " RST_CLASS_REF(lief.ELF.Note) " in the binary",
"note"_a,
py::return_value_policy::reference)

.def("replace",
static_cast<Segment& (Binary::*)(const Segment&, const Segment&, uint64_t)>(&Binary::replace),
"Replace the segment given in 2nd parameter with the segment given in the first one and return the updated segment",
Expand Down Expand Up @@ -302,6 +319,22 @@ void init_ELF_Binary_class(py::module& m) {
"Remove **all** " RST_CLASS_REF(lief.ELF.DynamicEntry) " with the given " RST_CLASS_REF(lief.ELF.DYNAMIC_TAGS) "",
"tag"_a)

.def("remove",
static_cast<void (Binary::*)(const Section&, bool)>(&Binary::remove),
"Remove the given " RST_CLASS_REF(lief.ELF.Section) ". ``clear`` specify whether or not "
"we must fill its content with ``0`` before removing",
"section"_a, "clear"_a = false)

.def("remove",
static_cast<void (Binary::*)(const Note&)>(&Binary::remove),
"Remove the given " RST_CLASS_REF(lief.ELF.Note) "",
"note"_a)

.def("remove",
static_cast<void (Binary::*)(NOTE_TYPES)>(&Binary::remove),
"Remove **all** " RST_CLASS_REF(lief.ELF.Note) " with the given " RST_CLASS_REF(lief.ELF.NOTE_TYPES) "",
"type"_a)

.def_property_readonly("has_notes",
&Binary::has_notes,
"``True`` if the binary contains notes")
Expand Down Expand Up @@ -353,26 +386,38 @@ void init_ELF_Binary_class(py::module& m) {
"Remove the given library",
"library_name"_a)

.def("remove_section",
&Binary::remove_section,
"Remove the given section from its name",
"library_name"_a, "clear"_a = false)

.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``",
"library_name"_a,
py::return_value_policy::reference)

.def(py::self += Segment())

.def(py::self += Section())

.def(py::self += DynamicEntry())
.def(py::self += Note())

.def(py::self -= DynamicEntry())
.def(py::self -= DYNAMIC_TAGS())

.def(py::self -= Note())
.def(py::self -= NOTE_TYPES())

.def("__getitem__",
static_cast<Segment& (Binary::*)(SEGMENT_TYPES)>(&Binary::operator[]),
"",
py::return_value_policy::reference)

.def("__getitem__",
static_cast<Note& (Binary::*)(NOTE_TYPES)>(&Binary::operator[]),
"",
py::return_value_policy::reference)

.def("__getitem__",
static_cast<DynamicEntry& (Binary::*)(DYNAMIC_TAGS)>(&Binary::operator[]),
"",
Expand All @@ -386,6 +431,10 @@ void init_ELF_Binary_class(py::module& m) {
static_cast<bool (Binary::*)(DYNAMIC_TAGS) const>(&Binary::has),
"Check if the " RST_CLASS_REF(lief.ELF.DynamicEntry) " associated with the given " RST_CLASS_REF(lief.ELF.DYNAMIC_TAGS) " exists")

.def("__contains__",
static_cast<bool (Binary::*)(NOTE_TYPES) const>(&Binary::has),
"Check if the " RST_CLASS_REF(lief.ELF.Note) " associated with the given " RST_CLASS_REF(lief.ELF.NOTE_TYPES) " exists")

.def("__str__",
[] (const Binary& binary)
{
Expand Down
8 changes: 6 additions & 2 deletions api/python/ELF/objects/pyNote.cpp
Expand Up @@ -30,8 +30,12 @@ using setter_t = void (Note::*)(T);
void init_ELF_Note_class(py::module& m) {

py::class_<Note>(m, "Note")
.def(py::init<>())
.def(py::init<const std::string&, uint32_t, const std::vector<uint8_t>&>())
.def(py::init<>(),
"Default ctor")

.def(py::init<const std::string&, NOTE_TYPES, const std::vector<uint8_t>&>(),
"Ctor from ``name``, ``type`` and ``description``",
"name"_a, "type"_a, "description"_a)

.def_property("name",
static_cast<getter_t<const std::string&>>(&Note::name),
Expand Down
39 changes: 33 additions & 6 deletions include/LIEF/ELF/Binary.hpp
Expand Up @@ -104,12 +104,24 @@ class DLL_PUBLIC Binary : public LIEF::Binary {
//! @brief Add the given dynamic entry and return the entry added
DynamicEntry& add(const DynamicEntry& entry);

//! @brief Add the given note and return the entry added
Note& add(const Note& note);

//! @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 Remove the given section
void remove(const Section& section, bool clear = false);

//! @brief Remove the given note
void remove(const Note& note);

//! @brief Remove **all** notes with the given type
void remove(NOTE_TYPES tag);

//! @brief Return binary's dynamic symbols
it_symbols dynamic_symbols(void);
it_const_symbols dynamic_symbols(void) const;
Expand Down Expand Up @@ -324,7 +336,7 @@ class DLL_PUBLIC Binary : public LIEF::Binary {
//!
//! We clear data used by this section and it's removed from
//! section table
void remove_section(const std::string& name);
void remove_section(const std::string& name, bool clear = false);

//! @brief Reconstruct the binary object and write it in `filename`
//! @param filename Path to write the reconstructed binary
Expand Down Expand Up @@ -365,21 +377,29 @@ class DLL_PUBLIC Binary : public LIEF::Binary {
const Segment& segment_from_offset(uint64_t offset) const;
Segment& segment_from_offset(uint64_t offset);

//! @brief Return the ELF::DynamicEntry associated with the given tag
//! @brief Return the **first** ELF::DynamicEntry associated with the given tag
const DynamicEntry& get(DYNAMIC_TAGS tag) const;
DynamicEntry& get(DYNAMIC_TAGS tag);

//! @brief Return the ELF::DynamicEntry associated with the given tag
const Segment& get(SEGMENT_TYPES tag) const;
Segment& get(SEGMENT_TYPES tag);
//! @brief Return the **first** ELF::Segment associated with the given type
const Segment& get(SEGMENT_TYPES type) const;
Segment& get(SEGMENT_TYPES type);

//! @brief Return the **first** ELF::Note associated with the given type
const Note& get(NOTE_TYPES type) const;
Note& get(NOTE_TYPES type);

//! @brief Check if an ELF::DynamicEntry associated with the given tag
//! exists.
bool has(DYNAMIC_TAGS tag) const;

//! @brief Check if ELF::Segment associated with the given type
//! exists.
bool has(SEGMENT_TYPES tag) const;
bool has(SEGMENT_TYPES type) const;

//! @brief Check if a ELF::Note associated with the given type
//! exists.
bool has(NOTE_TYPES type) const;

//! @brief Return the content located at virtual address
virtual std::vector<uint8_t> get_content_from_virtual_address(uint64_t virtual_address, uint64_t size) const override;
Expand Down Expand Up @@ -413,16 +433,23 @@ class DLL_PUBLIC Binary : public LIEF::Binary {
Binary& operator+=(const DynamicEntry& entry);
Binary& operator+=(const Section& section);
Binary& operator+=(const Segment& segment);
Binary& operator+=(const Note& note);

Binary& operator-=(const DynamicEntry& entry);
Binary& operator-=(DYNAMIC_TAGS tag);

Binary& operator-=(const Note& note);
Binary& operator-=(NOTE_TYPES type);

Segment& operator[](SEGMENT_TYPES type);
const Segment& operator[](SEGMENT_TYPES type) const;

DynamicEntry& operator[](DYNAMIC_TAGS tag);
const DynamicEntry& operator[](DYNAMIC_TAGS tag) const;

Note& operator[](NOTE_TYPES type);
const Note& operator[](NOTE_TYPES type) const;

private:
Binary(void);

Expand Down
7 changes: 7 additions & 0 deletions include/LIEF/ELF/Builder.hpp
Expand Up @@ -100,6 +100,13 @@ class DLL_PUBLIC Builder {
template<typename ELF_T>
void build_interpreter(void);

template<typename ELF_T>
void build_notes(void);

void build(NOTE_TYPES type, const std::string& section_name);

size_t note_offset(const Note& note);

bool empties_gnuhash_;

template<typename ELF_T>
Expand Down
4 changes: 4 additions & 0 deletions include/LIEF/ELF/Note.hpp
Expand Up @@ -38,6 +38,7 @@ class DLL_PUBLIC Note : public Visitable {
public:
Note(void);
Note(const std::string& name, uint32_t type, const std::vector<uint8_t>& description);
Note(const std::string& name, NOTE_TYPES type, const std::vector<uint8_t>& description);
Note& operator=(const Note& copy);
Note(const Note& copy);
virtual ~Note(void);
Expand All @@ -61,6 +62,9 @@ class DLL_PUBLIC Note : public Visitable {
void type(uint32_t type);
void description(const std::vector<uint8_t>& description);

//! @brief Sizeof the **raw** note
uint64_t size(void) const;

bool operator==(const Note& rhs) const;
bool operator!=(const Note& rhs) const;

Expand Down
2 changes: 2 additions & 0 deletions include/LIEF/ELF/Section.hpp
Expand Up @@ -39,6 +39,8 @@ class Parser;
class Binary;
class Builder;

DLL_PUBLIC Section operator"" _section(const char* name);

//! @brief Class wich represent sections
class DLL_PUBLIC Section : public LIEF::Section {

Expand Down

0 comments on commit 3be9dd0

Please sign in to comment.