Skip to content

Commit

Permalink
Improve the ELF part of LIEF
Browse files Browse the repository at this point in the history
Major changes (features):
  * Enable adding multiple sections/segments - Executable (PIE or not), Library
  * Enable adding multiple dynamic entries (DT_NEEDED, DT_INIT etc)
  * Enable adding multiple relocations
  * Enable adding multiple dynamic symbols
  * Enable segment replacement

Major changes (API):
  * Getters Binary::get_*name*() has been renamed to "name()"
  * Binary::add(const DynamicEntry& entry) - To add an entry in the dynamic table
  * Section& Binary::add(const Section& section, bool loaded = true) - To add a section(s)
  * Segment& Binary::add(const Segment& segment, uint64_t base = 0) - To add segments
  * Segment& replace(const Segment& new_segment, const Segment& original_segment, uint64_t base = 0)
  * Binary's last_offset_section(), last_offset_segment(), next_virtual_address()
    to have information about offset
  * Binary's add_library(), get_library(), has_library() to handle
    DT_NEEDED entries

Other changes:
  * Binary::insert_content() - Use add(const Section&) or add(const Segment&) instead
  * ELF's DataHandler has been cleaned
  * Through LIEF::Section one can look for integers, strings, data
    within the section (see LIEF::Section::search,
    LIEF::Section::search_all)
  * Through LIEF::Binary one can get *xref* of a number (or address)
    see LIEF::Binary::xref function
  * To access to the Abstract binary in Python, one can now use
    the 'abstract' attribute. (e.g. binary.abstract.header.is_32)

Resolve: #83
Resolve: #66
Resolve: #48
  • Loading branch information
romainthomas committed Sep 2, 2017
1 parent 5df162c commit b94900c
Show file tree
Hide file tree
Showing 79 changed files with 3,305 additions and 1,215 deletions.
10 changes: 7 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ option(LIEF_ELF "Build LIEF with ELF module" ON)
option(LIEF_PE "Build LIEF with PE module" ON)
option(LIEF_MACHO "Build LIEF with MachO module" ON)


# CCACHE
# ======
find_program(CCACHE_FOUND ccache)
Expand Down Expand Up @@ -255,6 +256,7 @@ set(LIEF_ABSTRACT_SRC
"${CMAKE_CURRENT_SOURCE_DIR}/src/Abstract/EnumToString.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/Abstract/Header.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/Abstract/Section.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/src/Abstract/Section.tcc"
"${CMAKE_CURRENT_SOURCE_DIR}/src/Abstract/Parser.cpp")

# Grouping basic LIEF source files
Expand Down Expand Up @@ -451,11 +453,14 @@ if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(LIB_LIEF_COMPILE_FLAGS
-Wall -Wextra -Wpedantic
-fno-stack-protector
-fomit-frame-pointer -fno-strict-aliasing
-fno-strict-aliasing
-fomit-frame-pointer
-fexceptions
-fvisibility=hidden)


if (HAS_NO_EXPANSION_TO_DEFINED)
set(LIB_LIEF_COMPILE_FLAGS ${LIB_LIEF_COMPILE_FLAGS} -Wno-expansion-to-defined)
list(APPEND LIB_LIEF_COMPILE_FLAGS -Wno-expansion-to-defined)
endif()
target_compile_options(LIB_LIEF_STATIC PRIVATE ${LIB_LIEF_COMPILE_FLAGS})
target_compile_options(LIB_LIEF_SHARED PRIVATE ${LIB_LIEF_COMPILE_FLAGS})
Expand Down Expand Up @@ -502,7 +507,6 @@ if(APPLE)
set_target_properties(LIB_LIEF_SHARED PROPERTIES MACOSX_RPATH ".")
endif()


# API
# ===

Expand Down
4 changes: 2 additions & 2 deletions api/c/ELF/Binary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ void init_c_binary(Elf_Binary_t* c_binary, Binary* binary) {
c_binary->type = static_cast<enum ::ELF_CLASS>(binary->type());
c_binary->interpreter = nullptr;
if (binary->has_interpreter()) {
std::string interp = binary->get_interpreter();
std::string interp = binary->interpreter();
c_binary->interpreter = static_cast<char*>(malloc(interp.size() * sizeof(char)));
std::memcpy(
reinterpret_cast<void*>(const_cast<char*>(c_binary->interpreter)),
Expand Down Expand Up @@ -73,7 +73,7 @@ Elf_Binary_t* elf_parse(const char *file) {
// ==============

int elf_binary_save_header(Elf_Binary_t* binary) {
Header& hdr = reinterpret_cast<Binary*>(binary->handler)->get_header();
Header& hdr = reinterpret_cast<Binary*>(binary->handler)->header();

hdr.file_type(static_cast<LIEF::ELF::E_TYPE>(binary->header.file_type));
hdr.machine_type(static_cast<LIEF::ELF::ARCH>(binary->header.machine_type));
Expand Down
2 changes: 1 addition & 1 deletion api/c/ELF/DynamicEntry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ namespace ELF {

void init_c_dynamic_entries(Elf_Binary_t* c_binary, Binary* binary) {

it_dynamic_entries dyn_entries = binary->get_dynamic_entries();
it_dynamic_entries dyn_entries = binary->dynamic_entries();
c_binary->dynamic_entries = static_cast<Elf_DynamicEntry_t**>(
malloc((dyn_entries.size() + 1) * sizeof(Elf_DynamicEntry_t**)));

Expand Down
2 changes: 1 addition & 1 deletion api/c/ELF/Header.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ namespace ELF {

void init_c_header(Elf_Binary_t* c_binary, Binary* binary) {

const Header& hdr = binary->get_header();
const Header& hdr = binary->header();
c_binary->header.file_type = static_cast<enum ::E_TYPE>(hdr.file_type());
c_binary->header.machine_type = static_cast<enum ::ARCH>(hdr.machine_type());
c_binary->header.object_file_version = static_cast<enum ::VERSION>(hdr.object_file_version());
Expand Down
2 changes: 1 addition & 1 deletion api/c/ELF/Section.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace LIEF {
namespace ELF {
void init_c_sections(Elf_Binary_t* c_binary, Binary* binary) {

it_sections sections = binary->get_sections();
it_sections sections = binary->sections();

c_binary->sections = static_cast<Elf_Section_t**>(
malloc((sections.size() + 1) * sizeof(Elf_Section_t**)));
Expand Down
2 changes: 1 addition & 1 deletion api/c/ELF/Segment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ namespace ELF {

void init_c_segments(Elf_Binary_t* c_binary, Binary* binary) {

it_segments segments = binary->get_segments();
it_segments segments = binary->segments();
c_binary->segments = static_cast<Elf_Segment_t**>(
malloc((segments.size() + 1) * sizeof(Elf_Segment_t**)));
for (size_t i = 0; i < segments.size(); ++i) {
Expand Down
4 changes: 2 additions & 2 deletions api/c/ELF/Symbol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ namespace LIEF {
namespace ELF {

void init_c_dynamic_symbols(Elf_Binary_t* c_binary, Binary* binary) {
it_symbols dyn_symb = binary->get_dynamic_symbols();
it_symbols dyn_symb = binary->dynamic_symbols();

c_binary->dynamic_symbols = static_cast<Elf_Symbol_t**>(
malloc((dyn_symb.size() + 1) * sizeof(Elf_Symbol_t**)));
Expand All @@ -46,7 +46,7 @@ void init_c_dynamic_symbols(Elf_Binary_t* c_binary, Binary* binary) {


void init_c_static_symbols(Elf_Binary_t* c_binary, Binary* binary) {
it_symbols static_symb = binary->get_static_symbols();
it_symbols static_symb = binary->static_symbols();

c_binary->static_symbols = static_cast<Elf_Symbol_t**>(
malloc((static_symb.size() + 1) * sizeof(Elf_Symbol_t**)));
Expand Down
5 changes: 5 additions & 0 deletions api/python/Abstract/objects/pyBinary.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,11 @@ void init_LIEF_Binary_class(py::module& m) {
"Return the " RST_CLASS_REF(lief.Binary) " object",
py::return_value_policy::reference)

.def("xref",
&Binary::xref,
"Return all **virtual address** that *use* the ``address`` given in parameter"
"virtual_address"_a)

.def("__str__",
[] (const Binary& binary)
{
Expand Down
40 changes: 38 additions & 2 deletions api/python/Abstract/objects/pySection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@ using setter_t = void (LIEF::Section::*)(T);

void init_LIEF_Section_class(py::module& m) {
py::class_<LIEF::Section>(m, "Section")
.def(py::init())
.def(py::init(),
"Default constructor")

.def(py::init<const std::string&>(),
"Constructor from section name",
"name"_a)

.def_property("name",
[] (const LIEF::Section& obj) {
Expand Down Expand Up @@ -55,5 +60,36 @@ void init_LIEF_Section_class(py::module& m) {

.def_property_readonly("entropy",
&LIEF::Section::entropy,
"Section's entropy");
"Section's entropy")

.def("search",
static_cast<size_t (LIEF::Section::*)(uint64_t, size_t, size_t) const>(&LIEF::Section::search),
"Look for **integer** within the current section",
"number"_a, "pos"_a = 0, "size"_a = 0)

.def("search",
static_cast<size_t (LIEF::Section::*)(const std::string&, size_t) const>(&LIEF::Section::search),
"Look for **string** within the current section",
"str"_a, "pos"_a = 0)

.def("search_all",
static_cast<std::vector<size_t> (LIEF::Section::*)(uint64_t, size_t) const>(&LIEF::Section::search_all),
"Look for **all** integers within the current section",
"number"_a, "size"_a = 0)

.def("search_all",
static_cast<std::vector<size_t> (LIEF::Section::*)(const std::string&) const>(&LIEF::Section::search_all),
"Look for all **strings** within the current section",
"str"_a)

.def("__str__",
[] (const LIEF::Section& section)
{
std::ostringstream stream;
stream << section;
std::string str = stream.str();
return str;
});


}
1 change: 1 addition & 0 deletions api/python/ELF/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ set(LIEF_PYTHON_ELF_SRC
"${CMAKE_CURRENT_LIST_DIR}/objects/pySysvHash.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyBuilder.cpp"
"${CMAKE_CURRENT_LIST_DIR}/pyELFStructures.cpp"
"${CMAKE_CURRENT_LIST_DIR}/pySizes.cpp"
)

set(LIEF_PYTHON_ELF_HDR
Expand Down
Loading

0 comments on commit b94900c

Please sign in to comment.