Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Enable to export and create dynamic symbols
New API:

  * Binary::{has_dynamic_symbol, has_static_symbol}
  * Binary::{get_dynamic_symbol, get_static_symbol}
  * Binary::add_exported_function
  * Binary::export_symbol

  * Symbol::visibility
  * SymbolVersion::local / SymbolVersion::global

Resolve #112
  • Loading branch information
romainthomas committed Feb 28, 2018
1 parent 253c2b5 commit a40da3e
Show file tree
Hide file tree
Showing 33 changed files with 1,179 additions and 91 deletions.
72 changes: 69 additions & 3 deletions api/python/ELF/objects/pyBinary.cpp
Expand Up @@ -219,6 +219,12 @@ void init_ELF_Binary_class(py::module& m) {
"type"_a,
py::return_value_policy::reference)

.def("get",
static_cast<no_const_func<Section&, ELF_SECTION_TYPES>>(&Binary::get),
"Return **first** binary's " RST_CLASS_REF(lief.ELF.Section) " given its " RST_CLASS_REF(lief.ELF.ELF_SECTION_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 @@ -234,6 +240,11 @@ void init_ELF_Binary_class(py::module& m) {
"Check if a " RST_CLASS_REF(lief.ELF.Note) " of *type* (" RST_CLASS_REF(lief.ELF.NOTE_TYPES) ") exists",
"type"_a)

.def("has",
static_cast<bool (Binary::*)(ELF_SECTION_TYPES) const>(&Binary::has),
"Check if a " RST_CLASS_REF(lief.ELF.Section) " of *type* (" RST_CLASS_REF(lief.ELF.ECTION_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 @@ -262,9 +273,9 @@ void init_ELF_Binary_class(py::module& m) {
py::return_value_policy::reference)

.def("add_dynamic_symbol",
&Binary::add_dynamic_symbol,
static_cast<Symbol& (Binary::*)(const Symbol&, const SymbolVersion&)>(&Binary::add_dynamic_symbol),
"Add a **dynamic** " RST_CLASS_REF(lief.ELF.Symbol) " to the binary",
"symbol"_a,
"symbol"_a, "symbol_version"_a = SymbolVersion::local(),
py::return_value_policy::reference)

.def("virtual_address_to_offset",
Expand Down Expand Up @@ -389,14 +400,59 @@ void init_ELF_Binary_class(py::module& m) {
.def("remove_section",
&Binary::remove_section,
"Remove the given section from its name",
"library_name"_a, "clear"_a = false)
"section_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("has_dynamic_symbol",
&Binary::has_dynamic_symbol,
"Check if the symbol with the given ``name`` exists in the **dynamic** symbol table",
"symbol_name"_a)

.def("get_dynamic_symbol",
static_cast<no_const_func<Symbol&, const std::string&>>(&Binary::get_dynamic_symbol),
"Get the dynamic symbol from the given name",
"symbol_name"_a,
py::return_value_policy::reference)

.def("has_static_symbol",
&Binary::has_static_symbol,
"Check if the symbol with the given ``name`` exists in the **static** symbol table",
"symbol_name"_a)

.def("get_static_symbol",
static_cast<no_const_func<Symbol&, const std::string&>>(&Binary::get_static_symbol),
"Get the **dynamic** symbol from the given ``name``",
"symbol_name"_a,
py::return_value_policy::reference)


.def("add_exported_function",
&Binary::add_exported_function,
"Create a symbol for the function at the given ``address`` and export it",
"address"_a, "name"_a = "",
py::return_value_policy::reference)


.def("export_symbol",
static_cast<Symbol& (Binary::*)(const Symbol&)>(&Binary::export_symbol),
"Export the given symbol and create it if it doesn't exist",
"symbol"_a,
py::return_value_policy::reference)


.def("export_symbol",
static_cast<Symbol& (Binary::*)(const std::string&, uint64_t)>(&Binary::export_symbol),
"Export the symbol with the given name and create it if it doesn't exist",
"symbol_name"_a, "value"_a = 0,
py::return_value_policy::reference)



.def(py::self += Segment())
.def(py::self += Section())
.def(py::self += DynamicEntry())
Expand All @@ -423,6 +479,12 @@ void init_ELF_Binary_class(py::module& m) {
"",
py::return_value_policy::reference)


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

.def("__contains__",
static_cast<bool (Binary::*)(SEGMENT_TYPES) const>(&Binary::has),
"Check if a " RST_CLASS_REF(lief.ELF.Segment) " of *type* (" RST_CLASS_REF(lief.ELF.SEGMENT_TYPES) ") exists")
Expand All @@ -435,6 +497,10 @@ void init_ELF_Binary_class(py::module& m) {
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("__contains__",
static_cast<bool (Binary::*)(ELF_SECTION_TYPES) const>(&Binary::has),
"Check if the " RST_CLASS_REF(lief.ELF.Section) " associated with the given " RST_CLASS_REF(lief.ELF.SECTION_TYPES) " exists")

.def("__str__",
[] (const Binary& binary)
{
Expand Down
5 changes: 5 additions & 0 deletions api/python/ELF/objects/pySection.cpp
Expand Up @@ -112,6 +112,11 @@ void init_ELF_Section_class(py::module& m) {
"Return segment(s) associated with the given section",
py::return_value_policy::reference_internal)

.def("clear",
&Section::clear,
"Clear the content of the section with the given ``value``",
"value"_a = 0,
py::return_value_policy::reference)

.def("add",
&Section::add,
Expand Down
11 changes: 10 additions & 1 deletion api/python/ELF/objects/pySymbol.cpp
Expand Up @@ -56,7 +56,16 @@ void init_ELF_Symbol_class(py::module& m) {
.def_property("other",
static_cast<getter_t<uint8_t>>(&Symbol::other),
static_cast<setter_t<uint8_t>>(&Symbol::other),
"This member currently holds ``0`` and has no defined meaning.")
"This member **should** holds ``0`` and **should** not have defined meaning.\n\n"

"See: " RST_ATTR_REF(lief.ELF.Symbol.visibility) "")

.def_property("visibility",
static_cast<getter_t<ELF_SYMBOL_VISIBILITY>>(&Symbol::visibility),
static_cast<setter_t<ELF_SYMBOL_VISIBILITY>>(&Symbol::visibility),
"Symbol " RST_CLASS_REF(lief.ELF.SYMBOL_VISIBILITY) ". \n\n"

"It's basically an alias on " RST_ATTR_REF(lief.ELF.Symbol.other) "")

.def_property("value",
static_cast<getter_t<uint64_t>>(&Symbol::value),
Expand Down
16 changes: 15 additions & 1 deletion api/python/ELF/objects/pySymbolVersion.cpp
Expand Up @@ -29,8 +29,22 @@ using setter_t = void (SymbolVersion::*)(T);

void init_ELF_SymbolVersion_class(py::module& m) {

// SymbolVersion version object
py::class_<SymbolVersion>(m, "SymbolVersion")
.def(py::init<>(),"Default constructor")
.def(py::init<uint16_t>(), "Constructor from :attr:`~lief.SymbolVersion.value`")

.def_property_readonly_static("local",
[] (const py::object&) {
return SymbolVersion::local();
},
"Generate a *local* " RST_CLASS_REF(lief.ELF.SymbolVersion) "")

.def_property_readonly_static("global_",
[] (const py::object&) {
return SymbolVersion::global();
},
"Generate a *global* " RST_CLASS_REF(lief.ELF.SymbolVersion) "")

.def_property("value",
static_cast<getter_t<uint16_t>>(&SymbolVersion::value),
static_cast<setter_t<uint16_t>>(&SymbolVersion::value),
Expand Down
2 changes: 1 addition & 1 deletion api/python/ELF/pyELF.cpp
Expand Up @@ -25,13 +25,13 @@ void init_ELF_module(py::module& m) {

// Objects
init_ELF_Parser_class(LIEF_ELF_module);
init_ELF_SymbolVersion_class(LIEF_ELF_module);
init_ELF_Binary_class(LIEF_ELF_module);
init_ELF_Header_class(LIEF_ELF_module);
init_ELF_Section_class(LIEF_ELF_module);
init_ELF_Segment_class(LIEF_ELF_module);
init_ELF_Symbol_class(LIEF_ELF_module);
init_ELF_Relocation_class(LIEF_ELF_module);
init_ELF_SymbolVersion_class(LIEF_ELF_module);
init_ELF_SymbolVersionAux_class(LIEF_ELF_module);
init_ELF_SymbolVersionAuxRequirement_class(LIEF_ELF_module);
init_ELF_SymbolVersionDefinition_class(LIEF_ELF_module);
Expand Down
8 changes: 8 additions & 0 deletions api/python/ELF/pyELFStructures.cpp
Expand Up @@ -1030,4 +1030,12 @@ void init_ELF_Structures_enum(py::module& m) {
.value(PY_ENUM(DYNAMIC_FLAGS_1::DF_1_SINGLETON))
.export_values();


py::enum_<ELF_SYMBOL_VISIBILITY>(m, "SYMBOL_VISIBILITY")
.value(PY_ENUM(ELF_SYMBOL_VISIBILITY::STV_DEFAULT))
.value(PY_ENUM(ELF_SYMBOL_VISIBILITY::STV_HIDDEN))
.value(PY_ENUM(ELF_SYMBOL_VISIBILITY::STV_INTERNAL))
.value(PY_ENUM(ELF_SYMBOL_VISIBILITY::STV_PROTECTED))
.export_values();

}
Binary file added doc/sphinx/_static/tutorial/08/bin2lib_a.pdf
Binary file not shown.
Binary file added doc/sphinx/_static/tutorial/08/bin2lib_a.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added doc/sphinx/_static/tutorial/08/bin2lib_b.pdf
Binary file not shown.
Binary file added doc/sphinx/_static/tutorial/08/bin2lib_b.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions doc/sphinx/api/cpp/elf.rst
Expand Up @@ -269,6 +269,14 @@ Symbol bindings

----------

Symbol visibility
~~~~~~~~~~~~~~~~~

.. doxygenenum:: LIEF::ELF::SYMBOL_VISIBILITY
:project: lief

----------

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

Expand Down
11 changes: 11 additions & 0 deletions doc/sphinx/api/python/elf.rst
Expand Up @@ -403,6 +403,17 @@ Symbol bindings

----------


Symbol Visibility
~~~~~~~~~~~~~~~~~

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

----------

Relocations x86-64
~~~~~~~~~~~~~~~~~~

Expand Down
35 changes: 18 additions & 17 deletions doc/sphinx/index.rst
Expand Up @@ -9,38 +9,39 @@ Welcome to LIEF's documentation!
.. toctree::
:maxdepth: 2

Intro.rst
installation.rst
getting_started.rst
compilation.rst
Intro
installation
getting_started
compilation

.. toctree::
:caption: Tutorials
:maxdepth: 1

tutorials/01_play_with_formats.rst
tutorials/02_pe_from_scratch.rst
tutorials/03_elf_change_symbols.rst
tutorials/04_elf_hooking.rst
tutorials/05_elf_infect_plt_got.rst
tutorials/06_pe_hooking.rst
tutorials/07_pe_resource.rst
tutorials/01_play_with_formats
tutorials/02_pe_from_scratch
tutorials/03_elf_change_symbols
tutorials/04_elf_hooking
tutorials/05_elf_infect_plt_got
tutorials/06_pe_hooking
tutorials/07_pe_resource
tutorials/08_elf_bin2lib


.. toctree::
:caption: API
:maxdepth: 1

api/python/index.rst
api/cpp/index.rst
api/c/index.rst
api/python/index
api/cpp/index
api/c/index

.. toctree::
:caption: Extra Information
:maxdepth: 1

formats/index.rst
references.rst
changelog.rst
formats/index
references
changelog


0 comments on commit a40da3e

Please sign in to comment.