mirror of
https://github.com/QuasarApp/LIEF.git
synced 2025-05-11 03:09:32 +00:00
Add object (ELF::DynamicEntryFlags) for ELF's DT_FLAGS and DT_FLAGS_1
This commit is contained in:
parent
c82b1fb658
commit
754b8afa2b
api/python
doc/sphinx/api
examples/python
include/LIEF
src
tests/elf
@ -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"
|
||||
|
93
api/python/ELF/objects/pyDynamicEntryFlags.cpp
Normal file
93
api/python/ELF/objects/pyDynamicEntryFlags.cpp
Normal file
@ -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;
|
||||
});
|
||||
}
|
@ -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);
|
||||
|
@ -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&);
|
||||
|
@ -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))
|
||||
@ -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();
|
||||
|
||||
}
|
||||
|
@ -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>);
|
||||
|
@ -18,6 +18,7 @@
|
||||
|
||||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/operators.h>
|
||||
#include <functional>
|
||||
|
||||
#include "encoding.hpp"
|
||||
|
@ -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
|
||||
*********
|
||||
|
@ -92,6 +92,14 @@ Dynamic Entry Array
|
||||
|
||||
----------
|
||||
|
||||
Dynamic Entry Flags
|
||||
*******************
|
||||
|
||||
.. doxygenclass:: LIEF::ELF::DynamicEntryFlags
|
||||
:project: lief
|
||||
|
||||
----------
|
||||
|
||||
Relocations
|
||||
***********
|
||||
|
||||
@ -293,6 +301,13 @@ Dynamic flags
|
||||
|
||||
----------
|
||||
|
||||
Dynamic flags 1
|
||||
~~~~~~~~~~~~~~~
|
||||
.. doxygenenum:: LIEF::ELF::DYNAMIC_FLAGS_1
|
||||
:project: lief
|
||||
|
||||
----------
|
||||
|
||||
Dynamic symbols counting
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
@ -110,6 +110,17 @@ Dynamic Entry Array
|
||||
|
||||
----------
|
||||
|
||||
Dynamic Entry Flags
|
||||
*******************
|
||||
|
||||
.. autoclass:: lief.ELF.DynamicEntryFlags
|
||||
:members:
|
||||
:inherited-members:
|
||||
:undoc-members:
|
||||
|
||||
|
||||
----------
|
||||
|
||||
Relocations
|
||||
***********
|
||||
|
||||
@ -351,6 +362,17 @@ Dynamic flags
|
||||
----------
|
||||
|
||||
|
||||
Dynamic flags 1
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
.. autoclass:: lief.ELF.DYNAMIC_FLAGS_1
|
||||
:members:
|
||||
:inherited-members:
|
||||
:undoc-members:
|
||||
|
||||
----------
|
||||
|
||||
|
||||
Symbol types
|
||||
~~~~~~~~~~~~
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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"
|
||||
|
72
include/LIEF/ELF/DynamicEntryFlags.hpp
Normal file
72
include/LIEF/ELF/DynamicEntryFlags.hpp
Normal file
@ -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
|
@ -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);
|
||||
|
@ -98,6 +98,45 @@ static const HEXAGON_EFLAGS hexagon_eflags_array[] = {
|
||||
HEXAGON_EFLAGS::EF_HEXAGON_ISA_V5,
|
||||
};
|
||||
|
||||
static const DYNAMIC_FLAGS dynamic_flags_array[] = {
|
||||
DYNAMIC_FLAGS::DF_ORIGIN,
|
||||
DYNAMIC_FLAGS::DF_SYMBOLIC,
|
||||
DYNAMIC_FLAGS::DF_TEXTREL,
|
||||
DYNAMIC_FLAGS::DF_BIND_NOW,
|
||||
DYNAMIC_FLAGS::DF_STATIC_TLS,
|
||||
};
|
||||
|
||||
|
||||
static const DYNAMIC_FLAGS_1 dynamic_flags_1_array[] = {
|
||||
DYNAMIC_FLAGS_1::DF_1_NOW,
|
||||
DYNAMIC_FLAGS_1::DF_1_GLOBAL,
|
||||
DYNAMIC_FLAGS_1::DF_1_GROUP,
|
||||
DYNAMIC_FLAGS_1::DF_1_NODELETE,
|
||||
DYNAMIC_FLAGS_1::DF_1_LOADFLTR,
|
||||
DYNAMIC_FLAGS_1::DF_1_INITFIRST,
|
||||
DYNAMIC_FLAGS_1::DF_1_NOOPEN,
|
||||
DYNAMIC_FLAGS_1::DF_1_ORIGIN,
|
||||
DYNAMIC_FLAGS_1::DF_1_DIRECT,
|
||||
DYNAMIC_FLAGS_1::DF_1_TRANS,
|
||||
DYNAMIC_FLAGS_1::DF_1_INTERPOSE,
|
||||
DYNAMIC_FLAGS_1::DF_1_NODEFLIB,
|
||||
DYNAMIC_FLAGS_1::DF_1_NODUMP,
|
||||
DYNAMIC_FLAGS_1::DF_1_CONFALT,
|
||||
DYNAMIC_FLAGS_1::DF_1_ENDFILTEE,
|
||||
DYNAMIC_FLAGS_1::DF_1_DISPRELDNE,
|
||||
DYNAMIC_FLAGS_1::DF_1_DISPRELPND,
|
||||
DYNAMIC_FLAGS_1::DF_1_NODIRECT,
|
||||
DYNAMIC_FLAGS_1::DF_1_IGNMULDEF,
|
||||
DYNAMIC_FLAGS_1::DF_1_NOKSYMS,
|
||||
DYNAMIC_FLAGS_1::DF_1_NOHDR,
|
||||
DYNAMIC_FLAGS_1::DF_1_EDITED,
|
||||
DYNAMIC_FLAGS_1::DF_1_NORELOC,
|
||||
DYNAMIC_FLAGS_1::DF_1_SYMINTPOSE,
|
||||
DYNAMIC_FLAGS_1::DF_1_GLOBAUDIT,
|
||||
DYNAMIC_FLAGS_1::DF_1_SINGLETON,
|
||||
};
|
||||
|
||||
|
||||
|
||||
class ELF32 {
|
||||
public:
|
||||
|
@ -803,16 +803,15 @@ enum DYNAMIC_TAGS {
|
||||
DT_MIPS_RWPLT = 0x70000034 /**< Points to the base of a writable PLT. */
|
||||
};
|
||||
|
||||
/** DT_FLAGS values. */
|
||||
/** DT_FLAGS and DT_FLAGS_1 values. */
|
||||
enum DYNAMIC_FLAGS {
|
||||
DF_ORIGIN = 0x01, /**< The object may reference $ORIGIN. */
|
||||
DF_SYMBOLIC = 0x02, /**< Search the shared lib before searching the exe. */
|
||||
DF_TEXTREL = 0x04, /**< Relocations may modify a non-writable segment. */
|
||||
DF_BIND_NOW = 0x08, /**< Process all relocations on load. */
|
||||
DF_STATIC_TLS = 0x10 /**< Reject attempts to load dynamically. */
|
||||
DF_ORIGIN = 0x00000001, /**< The object may reference $ORIGIN. */
|
||||
DF_SYMBOLIC = 0x00000002, /**< Search the shared lib before searching the exe. */
|
||||
DF_TEXTREL = 0x00000004, /**< Relocations may modify a non-writable segment. */
|
||||
DF_BIND_NOW = 0x00000008, /**< Process all relocations on load. */
|
||||
DF_STATIC_TLS = 0x00000010, /**< Reject attempts to load dynamically. */
|
||||
};
|
||||
|
||||
/* State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1 entry. */
|
||||
enum DYNAMIC_FLAGS_1 {
|
||||
DF_1_NOW = 0x00000001, /**< Set RTLD_NOW for this object. */
|
||||
DF_1_GLOBAL = 0x00000002, /**< Set RTLD_GLOBAL for this object. */
|
||||
|
@ -16,6 +16,7 @@
|
||||
#ifndef LIEF_ELF_TYPE_TRAITS_H_
|
||||
#define LIEF_ELF_TYPE_TRAITS_H_
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include "LIEF/iterators.hpp"
|
||||
|
||||
#include "LIEF/ELF/Structures.hpp"
|
||||
@ -102,6 +103,8 @@ using arm_flags_list_t = flags_list_t<ARM_EFLAGS>;
|
||||
using mips_flags_list_t = flags_list_t<MIPS_EFLAGS>;
|
||||
using hexagon_flags_list_t = flags_list_t<HEXAGON_EFLAGS>;
|
||||
using ppc64_flags_list_t = flags_list_t<PPC64_EFLAGS>;
|
||||
|
||||
using dynamic_flags_list_t = flags_list_t<uint32_t>;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -54,6 +54,7 @@ class DynamicEntryLibrary;
|
||||
class DynamicSharedObject;
|
||||
class DynamicEntryRunPath;
|
||||
class DynamicEntryRpath;
|
||||
class DynamicEntryFlags;
|
||||
|
||||
class Symbol;
|
||||
class SymbolVersion;
|
||||
@ -229,6 +230,9 @@ class DLL_PUBLIC Visitor {
|
||||
//! @brief Method to visit a LIEF::ELF::DynamicEntryRpath
|
||||
virtual void visit(const ELF::DynamicEntryRpath& rpath);
|
||||
|
||||
//! @brief Method to visit a LIEF::ELF::DynamicEntryFlags
|
||||
virtual void visit(const ELF::DynamicEntryFlags& flags);
|
||||
|
||||
//! @brief Method to visit a LIEF::ELF::Symbol
|
||||
virtual void visit(const ELF::Symbol& symbol);
|
||||
|
||||
|
@ -38,6 +38,7 @@ class DLL_PUBLIC JsonVisitor : public LIEF::JsonVisitor {
|
||||
virtual void visit(const DynamicEntryRpath& entry) override;
|
||||
virtual void visit(const DynamicEntryRunPath& entry) override;
|
||||
virtual void visit(const DynamicSharedObject& entry) override;
|
||||
virtual void visit(const DynamicEntryFlags& entry) override;
|
||||
virtual void visit(const Symbol& symbol) override;
|
||||
virtual void visit(const Relocation& relocation) override;
|
||||
virtual void visit(const SymbolVersion& sv) override;
|
||||
|
@ -40,6 +40,7 @@ set(LIEF_ELF_SRC
|
||||
"${CMAKE_CURRENT_LIST_DIR}/SymbolVersionDefinition.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/DynamicEntry.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/DynamicEntryRpath.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/DynamicEntryFlags.cpp"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/Builder.tcc"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/Parser.tcc")
|
||||
|
||||
@ -49,6 +50,7 @@ set(LIEF_ELF_INC_FILES
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/ELF/Builder.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/ELF/DynamicEntry.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/ELF/DynamicEntryArray.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/ELF/DynamicEntryFlags.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/ELF/DynamicEntryLibrary.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/ELF/DynamicEntryRpath.hpp"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/include/LIEF/ELF/DynamicEntryRunPath.hpp"
|
||||
|
@ -67,7 +67,7 @@ std::ostream& DynamicEntryArray::print(std::ostream& os) const {
|
||||
[] (std::string& s, uint64_t x) {
|
||||
std::stringstream ss;
|
||||
ss << "0x" << std::hex << x;
|
||||
return s.empty() ? ss.str() : " ," + ss.str();
|
||||
return s.empty() ? ss.str() : s + ", " + ss.str();
|
||||
})
|
||||
<< "]";
|
||||
|
||||
|
165
src/ELF/DynamicEntryFlags.cpp
Normal file
165
src/ELF/DynamicEntryFlags.cpp
Normal file
@ -0,0 +1,165 @@
|
||||
/* 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 <numeric>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
#include "LIEF/ELF/DynamicEntryFlags.hpp"
|
||||
#include "LIEF/ELF/EnumToString.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace ELF {
|
||||
|
||||
DynamicEntryFlags::DynamicEntryFlags(void) = default;
|
||||
DynamicEntryFlags& DynamicEntryFlags::operator=(const DynamicEntryFlags&) = default;
|
||||
DynamicEntryFlags::DynamicEntryFlags(const DynamicEntryFlags&) = default;
|
||||
|
||||
|
||||
|
||||
bool DynamicEntryFlags::has(DYNAMIC_FLAGS f) const {
|
||||
if (this->tag() != DYNAMIC_TAGS::DT_FLAGS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (f & this->value()) > 0;
|
||||
}
|
||||
|
||||
|
||||
bool DynamicEntryFlags::has(DYNAMIC_FLAGS_1 f) const {
|
||||
if (this->tag() != DYNAMIC_TAGS::DT_FLAGS_1) {
|
||||
return false;
|
||||
}
|
||||
return (f & this->value()) > 0;
|
||||
}
|
||||
|
||||
dynamic_flags_list_t DynamicEntryFlags::flags(void) const {
|
||||
dynamic_flags_list_t flags;
|
||||
|
||||
std::copy_if(
|
||||
std::begin(dynamic_flags_array),
|
||||
std::end(dynamic_flags_array),
|
||||
std::inserter(flags, std::begin(flags)),
|
||||
std::bind(static_cast<bool (DynamicEntryFlags::*)(DYNAMIC_FLAGS) const>(&DynamicEntryFlags::has),
|
||||
this, std::placeholders::_1));
|
||||
|
||||
std::copy_if(
|
||||
std::begin(dynamic_flags_1_array),
|
||||
std::end(dynamic_flags_1_array),
|
||||
std::inserter(flags, std::begin(flags)),
|
||||
std::bind(static_cast<bool (DynamicEntryFlags::*)(DYNAMIC_FLAGS_1) const>(&DynamicEntryFlags::has),
|
||||
this, std::placeholders::_1));
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
void DynamicEntryFlags::add(DYNAMIC_FLAGS f) {
|
||||
if (this->tag() != DYNAMIC_TAGS::DT_FLAGS) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->value(this->value() | static_cast<uint64_t>(f));
|
||||
}
|
||||
|
||||
void DynamicEntryFlags::add(DYNAMIC_FLAGS_1 f) {
|
||||
if (this->tag() != DYNAMIC_TAGS::DT_FLAGS_1) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->value(this->value() | static_cast<uint64_t>(f));
|
||||
}
|
||||
|
||||
void DynamicEntryFlags::remove(DYNAMIC_FLAGS f) {
|
||||
if (this->tag() != DYNAMIC_TAGS::DT_FLAGS) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->value(this->value() & (~ static_cast<uint64_t>(f)));
|
||||
}
|
||||
|
||||
void DynamicEntryFlags::remove(DYNAMIC_FLAGS_1 f) {
|
||||
if (this->tag() != DYNAMIC_TAGS::DT_FLAGS_1) {
|
||||
return;
|
||||
}
|
||||
|
||||
this->value(this->value() & (~ static_cast<uint64_t>(f)));
|
||||
}
|
||||
|
||||
|
||||
DynamicEntryFlags& DynamicEntryFlags::operator+=(DYNAMIC_FLAGS f) {
|
||||
this->add(f);
|
||||
return *this;
|
||||
}
|
||||
|
||||
DynamicEntryFlags& DynamicEntryFlags::operator+=(DYNAMIC_FLAGS_1 f) {
|
||||
this->add(f);
|
||||
return *this;
|
||||
}
|
||||
|
||||
DynamicEntryFlags& DynamicEntryFlags::operator-=(DYNAMIC_FLAGS f) {
|
||||
this->remove(f);
|
||||
return *this;
|
||||
}
|
||||
|
||||
DynamicEntryFlags& DynamicEntryFlags::operator-=(DYNAMIC_FLAGS_1 f) {
|
||||
this->remove(f);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void DynamicEntryFlags::accept(Visitor& visitor) const {
|
||||
DynamicEntry::accept(visitor);
|
||||
visitor(*this); // Double dispatch to avoid down-casting
|
||||
|
||||
for (uint32_t f : this->flags()) {
|
||||
visitor.visit(f);
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream& DynamicEntryFlags::print(std::ostream& os) const {
|
||||
DynamicEntry::print(os);
|
||||
|
||||
const dynamic_flags_list_t& flags = this->flags();
|
||||
std::string flags_str = "";
|
||||
|
||||
if (this->tag() == DYNAMIC_TAGS::DT_FLAGS) {
|
||||
flags_str = std::accumulate(
|
||||
std::begin(flags),
|
||||
std::end(flags), std::string{},
|
||||
[] (const std::string& a, uint32_t b) {
|
||||
DYNAMIC_FLAGS flag = static_cast<DYNAMIC_FLAGS>(b);
|
||||
return a.empty() ? to_string(flag) : a + " - " + to_string(flag);
|
||||
});
|
||||
}
|
||||
|
||||
if (this->tag() == DYNAMIC_TAGS::DT_FLAGS_1) {
|
||||
flags_str = std::accumulate(
|
||||
std::begin(flags),
|
||||
std::end(flags), std::string{},
|
||||
[] (const std::string& a, uint32_t b) {
|
||||
DYNAMIC_FLAGS_1 flag = static_cast<DYNAMIC_FLAGS_1>(b);
|
||||
return a.empty() ? to_string(flag) : a + " - " + to_string(flag);
|
||||
});
|
||||
}
|
||||
|
||||
os << " " << flags_str;
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -306,7 +306,7 @@ const char* to_string(DYNAMIC_TAGS e) {
|
||||
{ DYNAMIC_TAGS::DT_FINI_ARRAYSZ, "FINI_ARRAYSZ"},
|
||||
{ DYNAMIC_TAGS::DT_RUNPATH, "RUNPATH"},
|
||||
{ DYNAMIC_TAGS::DT_FLAGS, "FLAGS"},
|
||||
{ DYNAMIC_TAGS::DT_ENCODING, "ENCODING"},
|
||||
//{ DYNAMIC_TAGS::DT_ENCODING, "ENCODING"}, // SKIPED
|
||||
{ DYNAMIC_TAGS::DT_PREINIT_ARRAY, "PREINIT_ARRAY"},
|
||||
{ DYNAMIC_TAGS::DT_PREINIT_ARRAYSZ, "PREINIT_ARRAYSZ"},
|
||||
{ DYNAMIC_TAGS::DT_LOOS, "LOOS"},
|
||||
@ -1087,16 +1087,50 @@ const char* to_string(SYMBOL_SECTION_INDEX e) {
|
||||
|
||||
|
||||
const char* to_string(DYNAMIC_FLAGS e) {
|
||||
const std::map<DYNAMIC_FLAGS, const char*> enumStrings {
|
||||
{ DYNAMIC_FLAGS::DF_ORIGIN, "ORIGIN" },
|
||||
{ DYNAMIC_FLAGS::DF_SYMBOLIC, "SYMBOLIC" },
|
||||
{ DYNAMIC_FLAGS::DF_TEXTREL, "TEXTREL" },
|
||||
{ DYNAMIC_FLAGS::DF_BIND_NOW, "BIND_NOW" },
|
||||
{ DYNAMIC_FLAGS::DF_STATIC_TLS, "STATIC_TLS" },
|
||||
const std::map<DYNAMIC_FLAGS, const char*> enum_strings {
|
||||
{ DYNAMIC_FLAGS::DF_ORIGIN, "ORIGIN" },
|
||||
{ DYNAMIC_FLAGS::DF_SYMBOLIC, "SYMBOLIC" },
|
||||
{ DYNAMIC_FLAGS::DF_TEXTREL, "TEXTREL" },
|
||||
{ DYNAMIC_FLAGS::DF_BIND_NOW, "BIND_NOW" },
|
||||
{ DYNAMIC_FLAGS::DF_STATIC_TLS, "STATIC_TLS" },
|
||||
};
|
||||
|
||||
auto it = enumStrings.find(e);
|
||||
return it == enumStrings.end() ? "UNDEFINED" : it->second;
|
||||
auto it = enum_strings.find(e);
|
||||
return it == enum_strings.end() ? "UNDEFINED" : it->second;
|
||||
}
|
||||
|
||||
const char* to_string(DYNAMIC_FLAGS_1 e) {
|
||||
const std::map<DYNAMIC_FLAGS_1, const char*> enum_strings_flags1 {
|
||||
{ DYNAMIC_FLAGS_1::DF_1_NOW, "NOW" },
|
||||
{ DYNAMIC_FLAGS_1::DF_1_GLOBAL, "GLOBAL" },
|
||||
{ DYNAMIC_FLAGS_1::DF_1_GROUP, "GROUP" },
|
||||
{ DYNAMIC_FLAGS_1::DF_1_NODELETE, "NODELETE" },
|
||||
{ DYNAMIC_FLAGS_1::DF_1_LOADFLTR, "LOADFLTR" },
|
||||
{ DYNAMIC_FLAGS_1::DF_1_INITFIRST, "INITFIRST" },
|
||||
{ DYNAMIC_FLAGS_1::DF_1_NOOPEN, "NOOPEN" },
|
||||
{ DYNAMIC_FLAGS_1::DF_1_ORIGIN, "ORIGIN" },
|
||||
{ DYNAMIC_FLAGS_1::DF_1_DIRECT, "DIRECT" },
|
||||
{ DYNAMIC_FLAGS_1::DF_1_TRANS, "TRANS" },
|
||||
{ DYNAMIC_FLAGS_1::DF_1_INTERPOSE, "INTERPOSE" },
|
||||
{ DYNAMIC_FLAGS_1::DF_1_NODEFLIB, "NODEFLIB" },
|
||||
{ DYNAMIC_FLAGS_1::DF_1_NODUMP, "NODUMP" },
|
||||
{ DYNAMIC_FLAGS_1::DF_1_CONFALT, "CONFALT" },
|
||||
{ DYNAMIC_FLAGS_1::DF_1_ENDFILTEE, "ENDFILTEE" },
|
||||
{ DYNAMIC_FLAGS_1::DF_1_DISPRELDNE, "DISPRELDNE" },
|
||||
{ DYNAMIC_FLAGS_1::DF_1_DISPRELPND, "DISPRELPND" },
|
||||
{ DYNAMIC_FLAGS_1::DF_1_NODIRECT, "NODIRECT" },
|
||||
{ DYNAMIC_FLAGS_1::DF_1_IGNMULDEF, "IGNMULDEF" },
|
||||
{ DYNAMIC_FLAGS_1::DF_1_NOKSYMS, "NOKSYMS" },
|
||||
{ DYNAMIC_FLAGS_1::DF_1_NOHDR, "NOHDR" },
|
||||
{ DYNAMIC_FLAGS_1::DF_1_EDITED, "EDITED" },
|
||||
{ DYNAMIC_FLAGS_1::DF_1_NORELOC, "NORELOC" },
|
||||
{ DYNAMIC_FLAGS_1::DF_1_SYMINTPOSE, "SYMINTPOSE" },
|
||||
{ DYNAMIC_FLAGS_1::DF_1_GLOBAUDIT, "GLOBAUDIT" },
|
||||
{ DYNAMIC_FLAGS_1::DF_1_SINGLETON, "SINGLETON" },
|
||||
};
|
||||
|
||||
auto it = enum_strings_flags1.find(e);
|
||||
return it == enum_strings_flags1.end() ? "UNDEFINED" : it->second;
|
||||
}
|
||||
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <map>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <numeric>
|
||||
|
||||
#include "LIEF/exception.hpp"
|
||||
#include "LIEF/visitors/Hash.hpp"
|
||||
@ -567,6 +568,52 @@ std::ostream& operator<<(std::ostream& os, const Header& hdr)
|
||||
ss << static_cast<uint32_t>(identity[IDENTITY::EI_MAG3]) << " ";
|
||||
const std::string& ident_magic = ss.str();
|
||||
|
||||
std::string processor_flags_str = "";
|
||||
|
||||
if (hdr.machine_type() == ARCH::EM_ARM) {
|
||||
const arm_flags_list_t& flags = hdr.arm_flags_list();
|
||||
processor_flags_str = std::accumulate(
|
||||
std::begin(flags),
|
||||
std::end(flags), std::string{},
|
||||
[] (const std::string& a, ARM_EFLAGS b) {
|
||||
return a.empty() ? to_string(b) : a + " " + to_string(b);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (hdr.machine_type() == ARCH::EM_PPC64) {
|
||||
const ppc64_flags_list_t& flags = hdr.ppc64_flags_list();
|
||||
processor_flags_str = std::accumulate(
|
||||
std::begin(flags),
|
||||
std::end(flags), std::string{},
|
||||
[] (const std::string& a, PPC64_EFLAGS b) {
|
||||
return a.empty() ? to_string(b) : a + " " + to_string(b);
|
||||
});
|
||||
}
|
||||
|
||||
if (hdr.machine_type() == ARCH::EM_HEXAGON) {
|
||||
const hexagon_flags_list_t& flags = hdr.hexagon_flags_list();
|
||||
processor_flags_str = std::accumulate(
|
||||
std::begin(flags),
|
||||
std::end(flags), std::string{},
|
||||
[] (const std::string& a, HEXAGON_EFLAGS b) {
|
||||
return a.empty() ? to_string(b) : a + " " + to_string(b);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
if (hdr.machine_type() == ARCH::EM_MIPS or
|
||||
hdr.machine_type() == ARCH::EM_MIPS_RS3_LE or
|
||||
hdr.machine_type() == ARCH::EM_MIPS_X) {
|
||||
const mips_flags_list_t& flags = hdr.mips_flags_list();
|
||||
processor_flags_str = std::accumulate(
|
||||
std::begin(flags),
|
||||
std::end(flags), std::string{},
|
||||
[] (const std::string& a, MIPS_EFLAGS b) {
|
||||
return a.empty() ? to_string(b) : a + " " + to_string(b);
|
||||
});
|
||||
}
|
||||
|
||||
os << std::hex << std::left;
|
||||
os << std::setw(33) << std::setfill(' ') << "Magic:" << ident_magic << std::endl;
|
||||
os << std::setw(33) << std::setfill(' ') << "Class" << to_string(hdr.identity_class()) << std::endl;
|
||||
@ -579,7 +626,7 @@ std::ostream& operator<<(std::ostream& os, const Header& hdr)
|
||||
os << std::setw(33) << std::setfill(' ') << "Entry Point:" << "0x" << hdr.entrypoint() << std::endl;
|
||||
os << std::setw(33) << std::setfill(' ') << "Program header offset:" << "0x" << hdr.program_headers_offset() << std::endl;
|
||||
os << std::setw(33) << std::setfill(' ') << "Section header offset:" << hdr.section_headers_offset() << std::endl;
|
||||
os << std::setw(33) << std::setfill(' ') << "Processor Flag" << hdr.processor_flag() << std::endl;
|
||||
os << std::setw(33) << std::setfill(' ') << "Processor Flag" << hdr.processor_flag() << " " << processor_flags_str << std::endl;
|
||||
os << std::setw(33) << std::setfill(' ') << "Header size:" << hdr.header_size() << std::endl;
|
||||
os << std::setw(33) << std::setfill(' ') << "Size of program header :" << hdr.program_header_size() << std::endl;
|
||||
os << std::setw(33) << std::setfill(' ') << "Number of program header:" << hdr.numberof_segments() << std::endl;
|
||||
|
@ -14,8 +14,11 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
#include "easylogging++.h"
|
||||
|
||||
#include "LIEF/utils.hpp"
|
||||
|
||||
#include "LIEF/ELF/DynamicEntryFlags.hpp"
|
||||
|
||||
namespace LIEF {
|
||||
namespace ELF {
|
||||
template<typename ELF_T>
|
||||
@ -1019,8 +1022,14 @@ void Parser::parse_dynamic_entries(uint64_t offset, uint64_t size) {
|
||||
break;
|
||||
}
|
||||
|
||||
case DYNAMIC_TAGS::DT_FLAGS_1:
|
||||
case DYNAMIC_TAGS::DT_FLAGS:
|
||||
{
|
||||
dynamic_entry = new DynamicEntryFlags{entry};
|
||||
break;
|
||||
}
|
||||
|
||||
case DYNAMIC_TAGS::DT_SYMTAB :
|
||||
case DYNAMIC_TAGS::DT_SYMTAB:
|
||||
{
|
||||
dynamic_entry = new DynamicEntry{entry};
|
||||
break;
|
||||
|
@ -108,6 +108,10 @@ void Visitor::visit(const ELF::DynamicEntryRpath& rpath) {
|
||||
rpath.accept(*this);
|
||||
}
|
||||
|
||||
void Visitor::visit(const ELF::DynamicEntryFlags& flags) {
|
||||
flags.accept(*this);
|
||||
}
|
||||
|
||||
void Visitor::visit(const ELF::Symbol& symbol) {
|
||||
symbol.accept(*this);
|
||||
}
|
||||
|
@ -249,6 +249,34 @@ void JsonVisitor::visit(const DynamicSharedObject& entry) {
|
||||
this->node_["library"] = entry.name();
|
||||
}
|
||||
|
||||
|
||||
void JsonVisitor::visit(const DynamicEntryFlags& entry) {
|
||||
|
||||
const dynamic_flags_list_t& flags = entry.flags();
|
||||
std::vector<std::string> flags_str;
|
||||
flags_str.reserve(flags.size());
|
||||
|
||||
if (entry.tag() == DYNAMIC_TAGS::DT_FLAGS) {
|
||||
std::transform(
|
||||
std::begin(flags), std::end(flags),
|
||||
std::back_inserter(flags_str),
|
||||
[] (uint32_t f) {
|
||||
return to_string(static_cast<DYNAMIC_FLAGS>(f));
|
||||
});
|
||||
}
|
||||
|
||||
if (entry.tag() == DYNAMIC_TAGS::DT_FLAGS_1) {
|
||||
std::transform(
|
||||
std::begin(flags), std::end(flags),
|
||||
std::back_inserter(flags_str),
|
||||
[] (uint32_t f) {
|
||||
return to_string(static_cast<DYNAMIC_FLAGS_1>(f));
|
||||
});
|
||||
}
|
||||
|
||||
this->node_["flags"] = flags_str;
|
||||
}
|
||||
|
||||
void JsonVisitor::visit(const Symbol& symbol) {
|
||||
this->node_["type"] = to_string(symbol.type());
|
||||
this->node_["binding"] = to_string(symbol.binding());
|
||||
|
@ -204,15 +204,14 @@ class TestELF(TestCase):
|
||||
dynsym = list(rvs.dynamic_symbols)
|
||||
self.assertEqual(len(dynsym), 10)
|
||||
|
||||
def test_dynamic_flags(self):
|
||||
sample = "ELF/ELF32_ARM_binary_ls.bin"
|
||||
ls = lief.parse(get_sample(sample))
|
||||
d_flags = ls.dynamic_entry_from_tag(lief.ELF.DYNAMIC_TAGS.FLAGS)
|
||||
d_flags_1 = ls.dynamic_entry_from_tag(lief.ELF.DYNAMIC_TAGS.FLAGS_1)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
self.assertIn(lief.ELF.DYNAMIC_FLAGS.BIND_NOW, d_flags)
|
||||
self.assertIn(lief.ELF.DYNAMIC_FLAGS_1.NOW, d_flags_1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user