Skip to content
Permalink
Browse files
Enhance LIEF's ELF header
API Changes (Python / C++):
  * lief.ELF.Header.{arm_flags_list, mips_flags_list, ppc64_flags_list, hexagon_flags_list} - Added

In python, one can do:
`` if lief.ELF.ARM_EFLAGS.EABI_VER5 in lief.ELF.Header: ...``

In C++ we added:
  * LIEF::ELF::Header::has(ARM_EFLAGS, PPC64_EFLAGS, MIPS_EFLAGS...)
  • Loading branch information
romainthomas committed Aug 1, 2017
1 parent 4539895 commit 730d045
Show file tree
Hide file tree
Showing 10 changed files with 714 additions and 163 deletions.
@@ -102,6 +102,30 @@ void init_ELF_Header_class(py::module& m) {
static_cast<getter_t<uint32_t>>(&Header::processor_flag),
static_cast<setter_t<uint32_t>>(&Header::processor_flag))

.def_property_readonly("arm_flags_list",
&Header::arm_flags_list,
"Return list of " RST_CLASS_REF(lief.ELF.ARM_EFLAGS) " present in "
":attr:`~lief.ELF.Header.processor_flag`",
py::return_value_policy::reference_internal)

.def_property_readonly("mips_flags_list",
&Header::mips_flags_list,
"Return list of " RST_CLASS_REF(lief.ELF.MIPS_EFLAGS) " present in "
":attr:`~lief.ELF.Header.processor_flag`",
py::return_value_policy::reference_internal)

.def_property_readonly("ppc64_flags_list",
&Header::ppc64_flags_list,
"Return list of " RST_CLASS_REF(lief.ELF.PPC64_EFLAGS) " present in "
":attr:`~lief.ELF.Header.processor_flag`",
py::return_value_policy::reference_internal)

.def_property_readonly("hexagon_flags_list",
&Header::hexagon_flags_list,
"Return list of " RST_CLASS_REF(lief.ELF.HEXAGON_EFLAGS) " present in "
":attr:`~lief.ELF.Header.processor_flag`",
py::return_value_policy::reference_internal)

.def_property("header_size",
static_cast<getter_t<uint32_t>>(&Header::header_size),
static_cast<setter_t<uint32_t>>(&Header::header_size),
@@ -139,6 +163,29 @@ void init_ELF_Header_class(py::module& m) {
return LIEF::Hash::hash(header);
})

.def("__contains__",
static_cast<bool (Header::*)(ARM_EFLAGS) const>(&Header::has),
"Check if the given " RST_CLASS_REF(lief.ELF.ARM_EFLAGS) " is present in "
":attr:`~lief.ELF.Header.processor_flag`")


.def("__contains__",
static_cast<bool (Header::*)(MIPS_EFLAGS) const>(&Header::has),
"Check if the given " RST_CLASS_REF(lief.ELF.MIPS_EFLAGS) " is present in "
":attr:`~lief.ELF.Header.processor_flag`")


.def("__contains__",
static_cast<bool (Header::*)(PPC64_EFLAGS) const>(&Header::has),
"Check if the given " RST_CLASS_REF(lief.ELF.PPC64_EFLAGS) " is present in "
":attr:`~lief.ELF.Header.processor_flag`")


.def("__contains__",
static_cast<bool (Header::*)(HEXAGON_EFLAGS) const>(&Header::has),
"Check if the given " RST_CLASS_REF(lief.ELF.HEXAGON_EFLAGS) " is present in "
":attr:`~lief.ELF.Header.processor_flag`")

.def("__str__",
[] (const Header& header)
{
@@ -913,4 +913,80 @@ void init_ELF_Structures_enum(py::module& m) {
.value(PY_ENUM(RELOCATION_PURPOSES::RELOC_PURPOSE_DYNAMIC))
.value(PY_ENUM(RELOCATION_PURPOSES::RELOC_PURPOSE_OBJECT))
.export_values();


py::enum_<ARM_EFLAGS>(m, "ARM_EFLAGS")
.value(PY_ENUM(ARM_EFLAGS::EF_ARM_SOFT_FLOAT))
.value(PY_ENUM(ARM_EFLAGS::EF_ARM_VFP_FLOAT))
.value(PY_ENUM(ARM_EFLAGS::EF_ARM_EABI_UNKNOWN))
.value(PY_ENUM(ARM_EFLAGS::EF_ARM_EABI_VER1))
.value(PY_ENUM(ARM_EFLAGS::EF_ARM_EABI_VER2))
.value(PY_ENUM(ARM_EFLAGS::EF_ARM_EABI_VER3))
.value(PY_ENUM(ARM_EFLAGS::EF_ARM_EABI_VER4))
.value(PY_ENUM(ARM_EFLAGS::EF_ARM_EABI_VER5))
.export_values();


py::enum_<PPC64_EFLAGS>(m, "PPC64_EFLAGS")
.value(PY_ENUM(PPC64_EFLAGS::EF_PPC64_ABI))
.export_values();

py::enum_<MIPS_EFLAGS>(m, "MIPS_EFLAGS")
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_NOREORDER))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_PIC))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_CPIC))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_ABI2))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_32BITMODE))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_FP64))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_NAN2008))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_ABI_O32))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_ABI_O64))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_ABI_EABI32))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_ABI_EABI64))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_MACH_3900))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_MACH_4010))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_MACH_4100))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_MACH_4650))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_MACH_4120))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_MACH_4111))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_MACH_SB1))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_MACH_OCTEON))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_MACH_XLR))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_MACH_OCTEON2))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_MACH_OCTEON3))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_MACH_5400))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_MACH_5900))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_MACH_5500))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_MACH_9000))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_MACH_LS2E))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_MACH_LS2F))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_MACH_LS3A))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_MICROMIPS))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_ARCH_ASE_M16))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_ARCH_ASE_MDMX))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_ARCH_1))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_ARCH_2))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_ARCH_3))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_ARCH_4))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_ARCH_5))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_ARCH_32))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_ARCH_64))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_ARCH_32R2))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_ARCH_64R2))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_ARCH_32R6))
.value(PY_ENUM(MIPS_EFLAGS::EF_MIPS_ARCH_64R6))
.export_values();

py::enum_<HEXAGON_EFLAGS>(m, "HEXAGON_EFLAGS")
.value(PY_ENUM(HEXAGON_EFLAGS::EF_HEXAGON_MACH_V2))
.value(PY_ENUM(HEXAGON_EFLAGS::EF_HEXAGON_MACH_V3))
.value(PY_ENUM(HEXAGON_EFLAGS::EF_HEXAGON_MACH_V4))
.value(PY_ENUM(HEXAGON_EFLAGS::EF_HEXAGON_MACH_V5))
.value(PY_ENUM(HEXAGON_EFLAGS::EF_HEXAGON_ISA_MACH))
.value(PY_ENUM(HEXAGON_EFLAGS::EF_HEXAGON_ISA_V2))
.value(PY_ENUM(HEXAGON_EFLAGS::EF_HEXAGON_ISA_V3))
.value(PY_ENUM(HEXAGON_EFLAGS::EF_HEXAGON_ISA_V4))
.value(PY_ENUM(HEXAGON_EFLAGS::EF_HEXAGON_ISA_V5))
.export_values();

}
@@ -54,9 +54,23 @@ def print_header(binary):

print("== Header ==\n")
format_str = "{:<30} {:<30}"
format_hex = "{:<30} 0x{:<28x}"
format_hex = "{:<30} 0x{:<13x}"
format_dec = "{:<30} {:<30d}"
format_ide = "{:<30} {:<02x} {:<02x} {:<02x} {:<02x}"

eflags_str = ""
if header.machine_type == lief.ELF.ARCH.ARM:
eflags_str = " - ".join([str(s).split(".")[-1] for s in header.arm_flags_list])

if header.machine_type in [lief.ELF.ARCH.MIPS, lief.ELF.ARCH.MIPS_RS3_LE, lief.ELF.ARCH.MIPS_X]:
eflags_str = " - ".join([str(s).split(".")[-1] for s in header.mips_flags_list])

if header.machine_type == lief.ELF.ARCH.PPC64:
eflags_str = " - ".join([str(s).split(".")[-1] for s in header.ppc64_flags_list])

if header.machine_type == lief.ELF.ARCH.HEXAGON:
eflags_str = " - ".join([str(s).split(".")[-1] for s in header.hexagon_flags_list])

print(format_ide.format("Magic:", identity[0], identity[1], identity[2], identity[3]))
print(format_str.format("Class:", str(header.identity_class).split(".")[-1]))
print(format_str.format("Endianness:", str(header.identity_data).split(".")[-1]))
@@ -68,7 +82,7 @@ def print_header(binary):
print(format_hex.format("Entry Point:", header.entrypoint))
print(format_hex.format("Program Header Offset:", header.program_header_offset))
print(format_hex.format("Section Header Offset:", header.section_header_offset))
print(format_hex.format("Processor flags:", header.processor_flag))
print(format_hex.format("Processor flags:", header.processor_flag) + eflags_str)
print(format_dec.format("Header Size:", header.header_size))
print(format_dec.format("Program Header Size:", header.program_header_size))
print(format_dec.format("Section Header Size:", header.section_header_size))
@@ -41,6 +41,13 @@ DLL_PUBLIC const char* to_string(DYNSYM_COUNT_METHODS e);
DLL_PUBLIC const char* to_string(NOTE_TYPES e);
DLL_PUBLIC const char* to_string(NOTE_ABIS e);
DLL_PUBLIC const char* to_string(RELOCATION_PURPOSES e);

DLL_PUBLIC const char* to_string(PPC64_EFLAGS e);
DLL_PUBLIC const char* to_string(ARM_EFLAGS e);
DLL_PUBLIC const char* to_string(MIPS_EFLAGS e);
DLL_PUBLIC const char* to_string(HEXAGON_EFLAGS e);


} // namespace ELF
} // namespace LIEF

@@ -22,6 +22,7 @@

#include "LIEF/Visitable.hpp"
#include "LIEF/visibility.h"
#include "LIEF/ELF/type_traits.hpp"

#include "LIEF/Abstract/enums.hpp"

@@ -45,13 +46,13 @@ class DLL_PUBLIC Header : public Visitable {
virtual ~Header(void);

//! @brief Define the object file type. (e.g. executable, library...)
E_TYPE file_type(void) const;
E_TYPE file_type(void) const;

//! @brief LIEF abstract object type
OBJECT_TYPES abstract_object_type(void) const;

//! @brief Target architecture
ARCH machine_type(void) const;
ARCH machine_type(void) const;

//! @brief LIEF abstract architecture
std::pair<ARCHITECTURES, std::set<MODES>> abstract_architecture(void) const;
@@ -60,11 +61,43 @@ class DLL_PUBLIC Header : public Visitable {
ENDIANNESS abstract_endianness(void) const;

//! @brief Version of the object file format
VERSION object_file_version(void) const;
uint64_t entrypoint(void) const;
uint64_t program_headers_offset(void) const;
uint64_t section_headers_offset(void) const;
uint32_t processor_flag(void) const;
VERSION object_file_version(void) const;

//! @brief Executable entrypoint
uint64_t entrypoint(void) const;

//! @brief Offset of program table
uint64_t program_headers_offset(void) const;

//! @brief Offset of section table
uint64_t section_headers_offset(void) const;

//! @brief processor-specific flags
uint32_t processor_flag(void) const;

//! @brief Check if the given flag is present in processor_flag()
bool has(ARM_EFLAGS f) const;

//! @brief Return a list of ARM_EFLAGS present in processor_flag()
arm_flags_list_t arm_flags_list(void) const;

//! @brief Check if the given flag is present in processor_flag()
bool has(MIPS_EFLAGS f) const;

//! @brief Return a list of MIPS_EFLAGS present in processor_flag()
mips_flags_list_t mips_flags_list(void) const;

//! @brief Check if the given flag is present in processor_flag()
bool has(PPC64_EFLAGS f) const;

//! @brief Return a list of PPC64_EFLAGS present in processor_flag()
ppc64_flags_list_t ppc64_flags_list(void) const;

//! @brief Check if the given flag is present in processor_flag()
bool has(HEXAGON_EFLAGS f) const;

//! @brief Return a list of HEXAGON_EFLAGS present in processor_flag()
hexagon_flags_list_t hexagon_flags_list(void) const;

//! @brief Size of the current header
//!
@@ -82,7 +115,6 @@ class DLL_PUBLIC Header : public Visitable {
//! registred in the header
uint32_t numberof_segments(void) const;


//! @brief Return the size of a ``Section header``
//!
//! This size should be 64 for a ``ELF64`` binary and 40 for
@@ -144,46 +176,46 @@ class DLL_PUBLIC Header : public Visitable {

private:
//! Field which represent ElfXX_Ehdr->e_ident
identity_t identity_;
identity_t identity_;

//! Field which represent ElfXX_Ehdr->e_type
E_TYPE fileType_;
E_TYPE file_type_;

//! Field which represent ElfXX_Ehdr->e_machine
ARCH machineType_;
ARCH machine_type_;

//! Field which represent ElfXX_Ehdr->e_version
VERSION objectFileVersion_;
VERSION object_file_version_;

//! Field which represent ElfXX_Ehdr->e_entry
uint64_t entryPoint_;
uint64_t entrypoint_;

//! Field which represent ElfXX_Ehdr->e_phoff
uint64_t programHeaderOffset_;
uint64_t program_headers_offset_;

//! Field which represent ElfXX_Ehdr->e_shoff
uint64_t sectionHeaderOffset_;
uint64_t section_headers_offset_;

//! Field which represent ElfXX_Ehdr->e_flags
uint32_t processorFlag_;
uint32_t processor_flags_;

//! Field which represent ElfXX_Ehdr->e_ehsize
uint32_t headerSize_;
uint32_t header_size_;

//! Field which represent ElfXX_Ehdr->e_phentsize
uint32_t programHeaderSize_;
uint32_t program_header_size_;

//! Field which represent ElfXX_Ehdr->e_phnum
uint32_t numberof_segments_;
uint32_t numberof_segments_;

//! Field which represent ElfXX_Ehdr->e_shentsize
uint32_t sizeOfSectionHeaderEntries_;
uint32_t section_header_size_;

//! Field which represent ElfXX_Ehdr->e_shnum
uint32_t numberof_sections_;
uint32_t numberof_sections_;

//! Field which represent ElfXX_Ehdr->e_shstrndx
uint32_t sectionNameStringTableIdx_;
uint32_t section_string_table_idx_;

};
}

0 comments on commit 730d045

Please sign in to comment.