Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Add object (ELF::DynamicEntryFlags) for ELF's DT_FLAGS and DT_FLAGS_1
  • Loading branch information
romainthomas committed Aug 1, 2017
1 parent c82b1fb commit 754b8af
Show file tree
Hide file tree
Showing 28 changed files with 634 additions and 45 deletions.
1 change: 1 addition & 0 deletions api/python/ELF/CMakeLists.txt
Expand Up @@ -11,6 +11,7 @@ set(LIEF_PYTHON_ELF_SRC
"${CMAKE_CURRENT_LIST_DIR}/objects/pyHeader.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pySymbolVersionAux.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyDynamicEntryArray.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyDynamicEntryFlags.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pySegment.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pySection.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyDynamicEntryRpath.cpp"
Expand Down
93 changes: 93 additions & 0 deletions api/python/ELF/objects/pyDynamicEntryFlags.cpp
@@ -0,0 +1,93 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 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 "pyELF.hpp"

#include "LIEF/visitors/Hash.hpp"

#include "LIEF/ELF/DynamicEntryFlags.hpp"
#include "LIEF/ELF/DynamicEntry.hpp"

#include <string>
#include <sstream>

template<class T>
using getter_t = T (DynamicEntryFlags::*)(void) const;

template<class T>
using setter_t = void (DynamicEntryFlags::*)(T);

void init_ELF_DynamicEntryFlags_class(py::module& m) {

py::class_<DynamicEntryFlags, DynamicEntry>(m, "DynamicEntryFlags")
.def(py::init<>())
.def_property_readonly("flags",
&DynamicEntryFlags::flags,
"Return list of " RST_CLASS_REF(lief.ELF.DYNAMIC_FLAGS) " or " RST_CLASS_REF(lief.ELF.DYNAMIC_FLAGS_1) " (integer)",
py::return_value_policy::move)

.def("add",
static_cast<void (DynamicEntryFlags::*)(DYNAMIC_FLAGS)>(&DynamicEntryFlags::add),
"Add the given " RST_CLASS_REF(lief.ELF.DYNAMIC_FLAGS) "",
"flag"_a)

.def("add",
static_cast<void (DynamicEntryFlags::*)(DYNAMIC_FLAGS_1)>(&DynamicEntryFlags::add),
"Add the given " RST_CLASS_REF(lief.ELF.DYNAMIC_FLAGS_1) "",
"flag"_a)

.def("remove",
static_cast<void (DynamicEntryFlags::*)(DYNAMIC_FLAGS)>(&DynamicEntryFlags::remove),
"Remove the given " RST_CLASS_REF(lief.ELF.DYNAMIC_FLAGS) "",
"flag"_a)

.def("remove",
static_cast<void (DynamicEntryFlags::*)(DYNAMIC_FLAGS_1)>(&DynamicEntryFlags::remove),
"Remove the given " RST_CLASS_REF(lief.ELF.DYNAMIC_FLAGS_1) "",
"flag"_a)


.def("__eq__", &DynamicEntryFlags::operator==)
.def("__ne__", &DynamicEntryFlags::operator!=)
.def("__hash__",
[] (const DynamicEntryFlags& entry) {
return LIEF::Hash::hash(entry);
})

.def(py::self += DYNAMIC_FLAGS())
.def(py::self += DYNAMIC_FLAGS_1())


.def(py::self -= DYNAMIC_FLAGS())
.def(py::self -= DYNAMIC_FLAGS_1())

.def("__contains__",
static_cast<bool (DynamicEntryFlags::*)(DYNAMIC_FLAGS) const>(&DynamicEntryFlags::has),
"Check if the given " RST_CLASS_REF(lief.ELF.DYNAMIC_FLAGS) " is present")

.def("__contains__",
static_cast<bool (DynamicEntryFlags::*)(DYNAMIC_FLAGS_1) const>(&DynamicEntryFlags::has),
"Check if the given " RST_CLASS_REF(lief.ELF.DYNAMIC_FLAGS_1) " is present")


.def("__str__",
[] (const DynamicEntryFlags& entry)
{
std::ostringstream stream;
stream << entry;
std::string str = stream.str();
return str;
});
}
1 change: 1 addition & 0 deletions api/python/ELF/pyELF.cpp
Expand Up @@ -43,6 +43,7 @@ void init_ELF_module(py::module& m) {
init_ELF_DynamicEntryArray_class(LIEF_ELF_module);
init_ELF_DynamicEntryRpath_class(LIEF_ELF_module);
init_ELF_DynamicEntryRunPath_class(LIEF_ELF_module);
init_ELF_DynamicEntryFlags_class(LIEF_ELF_module);
init_ELF_GnuHash_class(LIEF_ELF_module);
init_ELF_SysvHash_class(LIEF_ELF_module);
init_ELF_Builder_class(LIEF_ELF_module);
Expand Down
1 change: 1 addition & 0 deletions api/python/ELF/pyELF.hpp
Expand Up @@ -41,6 +41,7 @@ void init_ELF_DynamicSharedObject_class(py::module&);
void init_ELF_DynamicEntryArray_class(py::module&);
void init_ELF_DynamicEntryRpath_class(py::module&);
void init_ELF_DynamicEntryRunPath_class(py::module&);
void init_ELF_DynamicEntryFlags_class(py::module&);
void init_ELF_GnuHash_class(py::module&);
void init_ELF_SysvHash_class(py::module&);
void init_ELF_Builder_class(py::module&);
Expand Down
31 changes: 30 additions & 1 deletion api/python/ELF/pyELFStructures.cpp
Expand Up @@ -433,7 +433,7 @@ void init_ELF_Structures_enum(py::module& m) {
.value(PY_ENUM(DYNAMIC_TAGS::DT_FINI_ARRAYSZ))
.value(PY_ENUM(DYNAMIC_TAGS::DT_RUNPATH))
.value(PY_ENUM(DYNAMIC_TAGS::DT_FLAGS))
.value(PY_ENUM(DYNAMIC_TAGS::DT_ENCODING))
//.value(PY_ENUM(DYNAMIC_TAGS::DT_ENCODING))
.value(PY_ENUM(DYNAMIC_TAGS::DT_PREINIT_ARRAY))
.value(PY_ENUM(DYNAMIC_TAGS::DT_PREINIT_ARRAYSZ))
.value(PY_ENUM(DYNAMIC_TAGS::DT_LOOS))
Expand Down Expand Up @@ -1027,4 +1027,33 @@ void init_ELF_Structures_enum(py::module& m) {
.value(PY_ENUM(DYNAMIC_FLAGS::DF_STATIC_TLS))
.export_values();

py::enum_<DYNAMIC_FLAGS_1>(m, "DYNAMIC_FLAGS_1")
.value(PY_ENUM(DYNAMIC_FLAGS_1::DF_1_NOW))
.value(PY_ENUM(DYNAMIC_FLAGS_1::DF_1_GLOBAL))
.value(PY_ENUM(DYNAMIC_FLAGS_1::DF_1_GROUP))
.value(PY_ENUM(DYNAMIC_FLAGS_1::DF_1_NODELETE))
.value(PY_ENUM(DYNAMIC_FLAGS_1::DF_1_LOADFLTR))
.value(PY_ENUM(DYNAMIC_FLAGS_1::DF_1_INITFIRST))
.value(PY_ENUM(DYNAMIC_FLAGS_1::DF_1_NOOPEN))
.value(PY_ENUM(DYNAMIC_FLAGS_1::DF_1_ORIGIN))
.value(PY_ENUM(DYNAMIC_FLAGS_1::DF_1_DIRECT))
.value(PY_ENUM(DYNAMIC_FLAGS_1::DF_1_TRANS))
.value(PY_ENUM(DYNAMIC_FLAGS_1::DF_1_INTERPOSE))
.value(PY_ENUM(DYNAMIC_FLAGS_1::DF_1_NODEFLIB))
.value(PY_ENUM(DYNAMIC_FLAGS_1::DF_1_NODUMP))
.value(PY_ENUM(DYNAMIC_FLAGS_1::DF_1_CONFALT))
.value(PY_ENUM(DYNAMIC_FLAGS_1::DF_1_ENDFILTEE))
.value(PY_ENUM(DYNAMIC_FLAGS_1::DF_1_DISPRELDNE))
.value(PY_ENUM(DYNAMIC_FLAGS_1::DF_1_DISPRELPND))
.value(PY_ENUM(DYNAMIC_FLAGS_1::DF_1_NODIRECT))
.value(PY_ENUM(DYNAMIC_FLAGS_1::DF_1_IGNMULDEF))
.value(PY_ENUM(DYNAMIC_FLAGS_1::DF_1_NOKSYMS))
.value(PY_ENUM(DYNAMIC_FLAGS_1::DF_1_NOHDR))
.value(PY_ENUM(DYNAMIC_FLAGS_1::DF_1_EDITED))
.value(PY_ENUM(DYNAMIC_FLAGS_1::DF_1_NORELOC))
.value(PY_ENUM(DYNAMIC_FLAGS_1::DF_1_SYMINTPOSE))
.value(PY_ENUM(DYNAMIC_FLAGS_1::DF_1_GLOBAUDIT))
.value(PY_ENUM(DYNAMIC_FLAGS_1::DF_1_SINGLETON))
.export_values();

}
1 change: 1 addition & 0 deletions api/python/pyJson.cpp
Expand Up @@ -33,6 +33,7 @@ void init_json_functions(py::module& m) {
m.def("to_json", &LIEF::to_json_str<LIEF::ELF::DynamicEntryRpath, LIEF::ELF::JsonVisitor>);
m.def("to_json", &LIEF::to_json_str<LIEF::ELF::DynamicEntryRunPath, LIEF::ELF::JsonVisitor>);
m.def("to_json", &LIEF::to_json_str<LIEF::ELF::DynamicSharedObject, LIEF::ELF::JsonVisitor>);
m.def("to_json", &LIEF::to_json_str<LIEF::ELF::DynamicEntryFlags, LIEF::ELF::JsonVisitor>);
m.def("to_json", &LIEF::to_json_str<LIEF::ELF::Symbol, LIEF::ELF::JsonVisitor>);
m.def("to_json", &LIEF::to_json_str<LIEF::ELF::Relocation, LIEF::ELF::JsonVisitor>);
m.def("to_json", &LIEF::to_json_str<LIEF::ELF::SymbolVersion, LIEF::ELF::JsonVisitor>);
Expand Down
1 change: 1 addition & 0 deletions api/python/pyLIEF.hpp
Expand Up @@ -18,6 +18,7 @@

#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/operators.h>
#include <functional>

#include "encoding.hpp"
Expand Down
8 changes: 8 additions & 0 deletions doc/sphinx/api/c/elf.rst
Expand Up @@ -94,6 +94,14 @@ Elf_DynamicEntry_RunPath_t
.. doxygenstruct:: Elf_DynamicEntry_RunPath_t
:project: lief

----------

Elf_DynamicEntry_Flags_t
~~~~~~~~~~~~~~~~~~~~~~~~~~

.. doxygenstruct:: Elf_DynamicEntry_Flags_t
:project: lief


Utilities
*********
Expand Down
15 changes: 15 additions & 0 deletions doc/sphinx/api/cpp/elf.rst
Expand Up @@ -92,6 +92,14 @@ Dynamic Entry Array

----------

Dynamic Entry Flags
*******************

.. doxygenclass:: LIEF::ELF::DynamicEntryFlags
:project: lief

----------

Relocations
***********

Expand Down Expand Up @@ -293,6 +301,13 @@ Dynamic flags

----------

Dynamic flags 1
~~~~~~~~~~~~~~~
.. doxygenenum:: LIEF::ELF::DYNAMIC_FLAGS_1
:project: lief

----------

Dynamic symbols counting
~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down
22 changes: 22 additions & 0 deletions doc/sphinx/api/python/elf.rst
Expand Up @@ -110,6 +110,17 @@ Dynamic Entry Array

----------

Dynamic Entry Flags
*******************

.. autoclass:: lief.ELF.DynamicEntryFlags
:members:
:inherited-members:
:undoc-members:


----------

Relocations
***********

Expand Down Expand Up @@ -351,6 +362,17 @@ Dynamic flags
----------


Dynamic flags 1
~~~~~~~~~~~~~~~

.. autoclass:: lief.ELF.DYNAMIC_FLAGS_1
:members:
:inherited-members:
:undoc-members:

----------


Symbol types
~~~~~~~~~~~~

Expand Down
41 changes: 25 additions & 16 deletions examples/python/elf_reader.py
Expand Up @@ -152,24 +152,33 @@ def print_segments(binary):

@exceptions_handler(Exception)
def print_dynamic_entries(binary):
dynamicEntries = binary.dynamic_entries
dynamic_entries = binary.dynamic_entries
# Dynamic entries
if len(dynamicEntries) > 0:
print("== Dynamic entries ==\n")
f_title = "|{:<12} | {:<10}| {:<20}|"
f_value = "|{:<12} | 0x{:<8x}| {:<20}|"
print(f_title.format("Tag", "Value", "Info"))
for dynEntry in dynamicEntries:
if dynEntry.tag == ELF.DYNAMIC_TAGS.NULL:
continue
if dynEntry.tag in [ELF.DYNAMIC_TAGS.SONAME, ELF.DYNAMIC_TAGS.NEEDED, ELF.DYNAMIC_TAGS.RUNPATH, ELF.DYNAMIC_TAGS.RPATH]:
print(f_value.format(str(dynEntry.tag).split(".")[-1], dynEntry.value, dynEntry.name))
elif dynEntry.tag in [ELF.DYNAMIC_TAGS.INIT_ARRAY,ELF.DYNAMIC_TAGS.FINI_ARRAY]:
print(f_value.format(str(dynEntry.tag).split(".")[-1], dynEntry.value, ", ".join(map(hex, dynEntry.array))))
else:
print(f_value.format(str(dynEntry.tag).split(".")[-1], dynEntry.value, ""))
if len(dynamic_entries) == 0:
return

print("")
print("== Dynamic entries ==\n")
f_title = "|{:<16} | {:<10}| {:<20}|"
f_value = "|{:<16} | 0x{:<8x}| {:<20}|"
print(f_title.format("Tag", "Value", "Info"))
for entry in dynamic_entries:
if entry.tag == ELF.DYNAMIC_TAGS.NULL:
continue

if entry.tag in [ELF.DYNAMIC_TAGS.SONAME, ELF.DYNAMIC_TAGS.NEEDED, ELF.DYNAMIC_TAGS.RUNPATH, ELF.DYNAMIC_TAGS.RPATH]:
print(f_value.format(str(entry.tag).split(".")[-1], entry.value, entry.name))
elif type(entry) is ELF.DynamicEntryArray: # [ELF.DYNAMIC_TAGS.INIT_ARRAY,ELF.DYNAMIC_TAGS.FINI_ARRAY]:
print(f_value.format(str(entry.tag).split(".")[-1], entry.value, ", ".join(map(hex, entry.array))))
elif entry.tag == ELF.DYNAMIC_TAGS.FLAGS:
flags_str = " - ".join([str(ELF.DYNAMIC_FLAGS(s)).split(".")[-1] for s in entry.flags])
print(f_value.format(str(entry.tag).split(".")[-1], entry.value, flags_str))
elif entry.tag == ELF.DYNAMIC_TAGS.FLAGS_1:
flags_str = " - ".join([str(ELF.DYNAMIC_FLAGS_1(s)).split(".")[-1] for s in entry.flags])
print(f_value.format(str(entry.tag).split(".")[-1], entry.value, flags_str))
else:
print(f_value.format(str(entry.tag).split(".")[-1], entry.value, ""))

print("")


@exceptions_handler(Exception)
Expand Down
1 change: 1 addition & 0 deletions include/LIEF/ELF/Binary.hpp
Expand Up @@ -35,6 +35,7 @@
#include "LIEF/ELF/DynamicEntryRpath.hpp"
#include "LIEF/ELF/DynamicEntryRunPath.hpp"
#include "LIEF/ELF/DynamicEntryArray.hpp"
#include "LIEF/ELF/DynamicEntryFlags.hpp"
#include "LIEF/ELF/Symbol.hpp"
#include "LIEF/ELF/Relocation.hpp"
#include "LIEF/ELF/SymbolVersion.hpp"
Expand Down
72 changes: 72 additions & 0 deletions include/LIEF/ELF/DynamicEntryFlags.hpp
@@ -0,0 +1,72 @@
/* Copyright 2017 R. Thomas
* Copyright 2017 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_ELF_DYNAMIC_ENTRY_FLAGS_H_
#define LIEF_ELF_DYNAMIC_ENTRY_FLAGS_H_

#include <string>

#include "LIEF/visibility.h"

#include "LIEF/ELF/type_traits.hpp"
#include "LIEF/ELF/DynamicEntry.hpp"

namespace LIEF {
namespace ELF {
class DLL_PUBLIC DynamicEntryFlags : public DynamicEntry {

public:
using DynamicEntry::DynamicEntry;
DynamicEntryFlags(void);

DynamicEntryFlags& operator=(const DynamicEntryFlags&);
DynamicEntryFlags(const DynamicEntryFlags&);

//! @brief If the current entry has the given DYNAMIC_FLAGS
bool has(DYNAMIC_FLAGS f) const;

//! @brief If the current entry has the given DYNAMIC_FLAGS_1
bool has(DYNAMIC_FLAGS_1 f) const;

//! @brief Return flags as a list of integers
dynamic_flags_list_t flags(void) const;

//! @brief Add the given DYNAMIC_FLAGS
void add(DYNAMIC_FLAGS f);

//! @brief Add the given DYNAMIC_FLAGS_1
void add(DYNAMIC_FLAGS_1 f);

//! @brief Remove the given DYNAMIC_FLAGS
void remove(DYNAMIC_FLAGS f);

//! @brief Remove the given DYNAMIC_FLAGS_1
void remove(DYNAMIC_FLAGS_1 f);

DynamicEntryFlags& operator+=(DYNAMIC_FLAGS f);
DynamicEntryFlags& operator+=(DYNAMIC_FLAGS_1 f);

DynamicEntryFlags& operator-=(DYNAMIC_FLAGS f);
DynamicEntryFlags& operator-=(DYNAMIC_FLAGS_1 f);

//! @brief Method so that the ``visitor`` can visit us
virtual void accept(Visitor& visitor) const override;

virtual std::ostream& print(std::ostream& os) const override;
};
}
}

#endif
1 change: 1 addition & 0 deletions include/LIEF/ELF/EnumToString.hpp
Expand Up @@ -44,6 +44,7 @@ DLL_PUBLIC const char* to_string(RELOCATION_PURPOSES e);
DLL_PUBLIC const char* to_string(IDENTITY e);
DLL_PUBLIC const char* to_string(SYMBOL_SECTION_INDEX e);
DLL_PUBLIC const char* to_string(DYNAMIC_FLAGS e);
DLL_PUBLIC const char* to_string(DYNAMIC_FLAGS_1 e);

DLL_PUBLIC const char* to_string(PPC64_EFLAGS e);
DLL_PUBLIC const char* to_string(ARM_EFLAGS e);
Expand Down

0 comments on commit 754b8af

Please sign in to comment.