Skip to content

Commit

Permalink
Add the underlying executable format in the abstract layer
Browse files Browse the repository at this point in the history
API changes (Python/C++):
  * lief.Binary.format
  * LIEF::ELF::Binary::format()
  • Loading branch information
romainthomas committed Jul 22, 2017
1 parent bcbeb66 commit 9391238
Show file tree
Hide file tree
Showing 11 changed files with 71 additions and 24 deletions.
5 changes: 5 additions & 0 deletions api/python/Abstract/objects/pyBinary.cpp
Expand Up @@ -32,6 +32,11 @@ using it_t = T (Binary::*)(void);

void init_LIEF_Binary_class(py::module& m) {
py::class_<Binary>(m, "Binary")

.def_property_readonly("format",
&Binary::format,
"File format " RST_CLASS_REF(lief.EXE_FORMATS) " of the underlying binary.")

.def_property("name",
static_cast<getter_t<const std::string&>>(&Binary::name),
static_cast<setter_t<const std::string&>>(&Binary::name),
Expand Down
9 changes: 5 additions & 4 deletions api/python/Abstract/pyEnums.cpp
Expand Up @@ -20,10 +20,11 @@
#define PY_ENUM(x) LIEF::to_string(x), x

void init_LIEF_Enum(py::module& m) {
py::enum_<LIEF::FILE_FORMATS>(m, "FILE_FORMATS")
.value(PY_ENUM(LIEF::FILE_FORMATS::FORMAT_ELF))
.value(PY_ENUM(LIEF::FILE_FORMATS::FORMAT_PE))
.value(PY_ENUM(LIEF::FILE_FORMATS::FORMAT_MACHO))
py::enum_<LIEF::EXE_FORMATS>(m, "EXE_FORMATS")
.value(PY_ENUM(LIEF::EXE_FORMATS::FORMAT_UNKNOWN))
.value(PY_ENUM(LIEF::EXE_FORMATS::FORMAT_ELF))
.value(PY_ENUM(LIEF::EXE_FORMATS::FORMAT_PE))
.value(PY_ENUM(LIEF::EXE_FORMATS::FORMAT_MACHO))
.export_values();

py::enum_<LIEF::OBJECT_TYPES>(m, "OBJECT_TYPES")
Expand Down
2 changes: 1 addition & 1 deletion doc/sphinx/api/cpp/abstract.rst
Expand Up @@ -44,7 +44,7 @@ Symbol
Enums
*****

.. doxygenenum:: LIEF::FILE_FORMATS
.. doxygenenum:: LIEF::EXE_FORMATS
:project: lief

.. doxygenenum:: LIEF::OBJECT_TYPES
Expand Down
6 changes: 3 additions & 3 deletions doc/sphinx/api/python/abstract.rst
Expand Up @@ -53,10 +53,10 @@ Enums
*****


File Formats
~~~~~~~~~~~~
Executable formats
~~~~~~~~~~~~~~~~~~

.. autoclass:: lief.FILE_FORMATS
.. autoclass:: lief.EXE_FORMATS
:members:
:inherited-members:
:undoc-members:
Expand Down
3 changes: 3 additions & 0 deletions include/LIEF/Abstract/Binary.hpp
Expand Up @@ -41,6 +41,9 @@ class DLL_PUBLIC Binary : public Visitable {
Binary& operator=(const Binary&);
Binary(const Binary&);

//! @brief Executable format (ELF, PE, Mach-O) of the underlying binary
EXE_FORMATS format(void) const;

//! @brief Return the abstract header of the binary
Header get_header(void) const;

Expand Down
2 changes: 1 addition & 1 deletion include/LIEF/Abstract/EnumToString.hpp
Expand Up @@ -20,7 +20,7 @@
#include "LIEF/Abstract/enums.hpp"

namespace LIEF {
DLL_PUBLIC const char* to_string(FILE_FORMATS e);
DLL_PUBLIC const char* to_string(EXE_FORMATS e);
DLL_PUBLIC const char* to_string(ARCHITECTURES e);
DLL_PUBLIC const char* to_string(OBJECT_TYPES e);
DLL_PUBLIC const char* to_string(MODES e);
Expand Down
9 changes: 5 additions & 4 deletions include/LIEF/Abstract/enums.hpp
Expand Up @@ -20,10 +20,11 @@

namespace LIEF {

enum FILE_FORMATS {
FORMAT_ELF = 0,
FORMAT_PE = 1,
FORMAT_MACHO = 2
enum EXE_FORMATS {
FORMAT_UNKNOWN = 0,
FORMAT_ELF = 1,
FORMAT_PE = 2,
FORMAT_MACHO = 3,
};

enum OBJECT_TYPES {
Expand Down
21 changes: 21 additions & 0 deletions src/Abstract/Binary.cpp
Expand Up @@ -16,14 +16,35 @@
#include "LIEF/Abstract/Binary.hpp"
#include "LIEF/exception.hpp"

#include "LIEF/ELF/Binary.hpp"
#include "LIEF/PE/Binary.hpp"
#include "LIEF/MachO/Binary.hpp"

namespace LIEF {
Binary::Binary(void) :
name_{""},
original_size_{0}
{}

Binary::~Binary(void) = default;
Binary& Binary::operator=(const Binary&) = default;
Binary::Binary(const Binary&) = default;

EXE_FORMATS Binary::format(void) const {
if (typeid(*this) == typeid(LIEF::ELF::Binary)) {
return EXE_FORMATS::FORMAT_ELF;
}

if (typeid(*this) == typeid(LIEF::PE::Binary)) {
return EXE_FORMATS::FORMAT_PE;
}

if (typeid(*this) == typeid(LIEF::MachO::Binary)) {
return EXE_FORMATS::FORMAT_MACHO;
}

return EXE_FORMATS::FORMAT_UNKNOWN;
}

Header Binary::get_header(void) const {
return this->get_abstract_header();
Expand Down
11 changes: 6 additions & 5 deletions src/Abstract/EnumToString.cpp
Expand Up @@ -18,11 +18,12 @@

namespace LIEF {

const char* to_string(FILE_FORMATS e) {
const std::map<FILE_FORMATS, const char*> enumStrings {
{ FILE_FORMATS::FORMAT_ELF, "ELF" },
{ FILE_FORMATS::FORMAT_PE, "PE" },
{ FILE_FORMATS::FORMAT_MACHO, "MACHO" },
const char* to_string(EXE_FORMATS e) {
const std::map<EXE_FORMATS, const char*> enumStrings {
{ EXE_FORMATS::FORMAT_UNKNOWN, "UNKNOWN" },
{ EXE_FORMATS::FORMAT_ELF, "ELF" },
{ EXE_FORMATS::FORMAT_PE, "PE" },
{ EXE_FORMATS::FORMAT_MACHO, "MACHO" },
};
auto it = enumStrings.find(e);
return it == enumStrings.end() ? "UNDEFINED" : it->second;
Expand Down
1 change: 1 addition & 0 deletions src/visitors/json.cpp
Expand Up @@ -50,6 +50,7 @@ void JsonVisitor::visit(const Binary& binary) {

this->node_["name"] = binary.name();
this->node_["entrypoint"] = binary.entrypoint();
this->node_["format"] = to_string(binary.format());
this->node_["original_size"] = binary.original_size();
this->node_["exported_functions"] = binary.get_exported_functions();
this->node_["imported_libraries"] = binary.get_imported_libraries();
Expand Down
26 changes: 20 additions & 6 deletions tests/abstract/abstract_tests.py
Expand Up @@ -19,28 +19,42 @@ class TestAbstract(TestCase):
def setUp(self):
self.logger = logging.getLogger(__name__)

@staticmethod
def get_abstract_binary(binary):
return super(binary.__class__, binary)

def test_endianness(self):
binary = lief.parse(get_sample('ELF/ELF32_x86_binary_ls.bin'))
binary = super(binary.__class__, binary)
binary = TestAbstract.get_abstract_binary(lief.parse(get_sample('ELF/ELF32_x86_binary_ls.bin')))
header = binary.header

self.assertEqual(header.endianness, lief.ENDIANNESS.LITTLE)


binary = lief.parse(get_sample('MachO/MachO64_x86-64_binary_id.bin'))
binary = super(binary.__class__, binary)
binary = TestAbstract.get_abstract_binary(lief.parse(get_sample('MachO/MachO64_x86-64_binary_id.bin')))
header = binary.header

self.assertEqual(header.endianness, lief.ENDIANNESS.LITTLE)


binary = lief.parse(get_sample('PE/PE64_x86-64_binary_ConsoleApplication1.exe'))
binary = super(binary.__class__, binary)
binary = TestAbstract.get_abstract_binary(lief.parse(get_sample('PE/PE64_x86-64_binary_ConsoleApplication1.exe')))
header = binary.header

self.assertEqual(header.endianness, lief.ENDIANNESS.LITTLE)


def test_format(self):
binary = TestAbstract.get_abstract_binary(lief.parse(get_sample('ELF/ELF32_x86_binary_ls.bin')))
self.assertEqual(binary.format, lief.EXE_FORMATS.ELF)


binary = TestAbstract.get_abstract_binary(lief.parse(get_sample('MachO/MachO64_x86-64_binary_id.bin')))
self.assertEqual(binary.format, lief.EXE_FORMATS.MACHO)


binary = TestAbstract.get_abstract_binary(lief.parse(get_sample('PE/PE64_x86-64_binary_ConsoleApplication1.exe')))
self.assertEqual(binary.format, lief.EXE_FORMATS.PE)


if __name__ == '__main__':

root_logger = logging.getLogger()
Expand Down

0 comments on commit 9391238

Please sign in to comment.