Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Expose API to list functions found in a binary
  • Loading branch information
romainthomas committed Sep 12, 2018
1 parent 5c757df commit b5a0846
Show file tree
Hide file tree
Showing 69 changed files with 1,702 additions and 464 deletions.
6 changes: 3 additions & 3 deletions api/python/Abstract/CMakeLists.txt
@@ -1,19 +1,19 @@

set(LIEF_PYTHON_ABSTRACT_SRC
"${CMAKE_CURRENT_LIST_DIR}/init.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects"
"${CMAKE_CURRENT_LIST_DIR}/pyAbstract.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyBinary.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyHeader.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pySection.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyParser.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pySymbol.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyRelocation.cpp"
"${CMAKE_CURRENT_LIST_DIR}/objects/pyFunction.cpp"
"${CMAKE_CURRENT_LIST_DIR}/pyEnums.cpp"
)


set(LIEF_PYTHON_ABSTRACT_HDR
"${CMAKE_CURRENT_LIST_DIR}/init.hpp"
"${CMAKE_CURRENT_LIST_DIR}/pyAbstract.hpp"
)

source_group("Source Files\\Abstract" FILES ${LIEF_PYTHON_ABSTRACT_SRC})
Expand Down
61 changes: 19 additions & 42 deletions api/python/Abstract/objects/pyBinary.cpp
Expand Up @@ -13,16 +13,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "init.hpp"
#include "pyAbstract.hpp"
#include "LIEF/Abstract/Binary.hpp"
#include "LIEF/ELF/Binary.hpp"

#include <algorithm>

using namespace LIEF;

#define PY_ENUM(x) LIEF::to_string(x), x

namespace LIEF {

template<class T>
using getter_t = T (Binary::*)(void) const;

Expand All @@ -35,15 +36,14 @@ using it_t = T (Binary::*)(void);
template<class T, class P>
using no_const_func = T (Binary::*)(P);

void init_LIEF_Binary_class(py::module& m) {


template<>
void create<Binary>(py::module& m) {
py::class_<Binary, Object> pybinary(m, "Binary");

py::enum_<LIEF::Binary::VA_TYPES>(pybinary, "VA_TYPES")
.value(PY_ENUM(LIEF::Binary::VA_TYPES::AUTO))
.value(PY_ENUM(LIEF::Binary::VA_TYPES::VA))
.value(PY_ENUM(LIEF::Binary::VA_TYPES::RVA));
py::enum_<Binary::VA_TYPES>(pybinary, "VA_TYPES")
.value(PY_ENUM(Binary::VA_TYPES::AUTO))
.value(PY_ENUM(Binary::VA_TYPES::VA))
.value(PY_ENUM(Binary::VA_TYPES::RVA));

pybinary
.def_property_readonly("format",
Expand Down Expand Up @@ -87,35 +87,12 @@ void init_LIEF_Binary_class(py::module& m) {
py::return_value_policy::reference_internal)

.def_property_readonly("exported_functions",
[] (const Binary& binary) {
const std::vector<std::string>& exported_functions = binary.exported_functions();
std::vector<py::object> exported_functions_encoded;
exported_functions_encoded.reserve(exported_functions.size());

std::transform(
std::begin(exported_functions),
std::end(exported_functions),
std::back_inserter(exported_functions_encoded),
&safe_string_converter);
return exported_functions_encoded;

},
"Return binary's exported functions (name)")
&Binary::exported_functions,
"Return binary's exported " RST_CLASS_REF(lief.Function) "")

.def_property_readonly("imported_functions",
[] (const Binary& binary) {
const std::vector<std::string>& imported_functions = binary.imported_functions();
std::vector<py::object> imported_functions_encoded;
imported_functions_encoded.reserve(imported_functions.size());

std::transform(
std::begin(imported_functions),
std::end(imported_functions),
std::back_inserter(imported_functions_encoded),
&safe_string_converter);
return imported_functions_encoded;
},
"Return binary's imported functions (name)")
&Binary::imported_functions,
"Return binary's imported " RST_CLASS_REF(lief.Function) " (name)")

.def_property_readonly("libraries",
[] (const Binary& binary) {
Expand Down Expand Up @@ -154,20 +131,20 @@ void init_LIEF_Binary_class(py::module& m) {
"function_name"_a)

.def("patch_address",
static_cast<void (Binary::*) (uint64_t, const std::vector<uint8_t>&, LIEF::Binary::VA_TYPES)>(&Binary::patch_address),
static_cast<void (Binary::*) (uint64_t, const std::vector<uint8_t>&, Binary::VA_TYPES)>(&Binary::patch_address),
"Patch the address with the given value",
"Virtual address is specified in the first argument and the content in the second (as a list of bytes).\n"
"If the underlying binary is a PE, one can specify if the virtual address is a " RST_ATTR_REF(lief.Binary.VA_TYPES.RVA) ""
" or a " RST_ATTR_REF(lief.Binary.VA_TYPES.VA) ". By default it is set to " RST_ATTR_REF(lief.Binary.VA_TYPES.AUTO) "",
"address"_a, "patch_value"_a, "va_type"_a = LIEF::Binary::VA_TYPES::AUTO)
"address"_a, "patch_value"_a, "va_type"_a = Binary::VA_TYPES::AUTO)

.def("patch_address",
static_cast<void (Binary::*) (uint64_t, uint64_t, size_t, LIEF::Binary::VA_TYPES)>(&Binary::patch_address),
static_cast<void (Binary::*) (uint64_t, uint64_t, size_t, Binary::VA_TYPES)>(&Binary::patch_address),
"Patch the address with the given value",
"Virtual address is specified in the first argument, integer in the second and sizeof the integer in third one.\n"
"If the underlying binary is a PE, one can specify if the virtual address is a " RST_ATTR_REF(lief.Binary.VA_TYPES.RVA) ""
" or a " RST_ATTR_REF(lief.Binary.VA_TYPES.VA) ". By default it is set to " RST_ATTR_REF(lief.Binary.VA_TYPES.AUTO) "",
"address"_a, "patch_value"_a, "size"_a = 8, "va_type"_a = LIEF::Binary::VA_TYPES::AUTO)
"address"_a, "patch_value"_a, "size"_a = 8, "va_type"_a = Binary::VA_TYPES::AUTO)


.def("get_content_from_virtual_address",
Expand All @@ -176,7 +153,7 @@ void init_LIEF_Binary_class(py::module& m) {
"Virtual address is specified in the first argument and size to read (in bytes) in the second.\n"
"If the underlying binary is a PE, one can specify if the virtual address is a " RST_ATTR_REF(lief.Binary.VA_TYPES.RVA) ""
" or a " RST_ATTR_REF(lief.Binary.VA_TYPES.VA) ". By default it is set to " RST_ATTR_REF(lief.Binary.VA_TYPES.AUTO) "",
"virtual_address"_a, "size"_a, "va_type"_a = LIEF::Binary::VA_TYPES::AUTO)
"virtual_address"_a, "size"_a, "va_type"_a = Binary::VA_TYPES::AUTO)

.def_property_readonly("abstract",
[m] (py::object& self) {
Expand Down Expand Up @@ -220,5 +197,5 @@ void init_LIEF_Binary_class(py::module& m) {

}


}

67 changes: 67 additions & 0 deletions api/python/Abstract/objects/pyFunction.cpp
@@ -0,0 +1,67 @@
/* 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 "pyAbstract.hpp"
#include "LIEF/Abstract/Symbol.hpp"

#include <string>
#include <sstream>

#define PY_ENUM(x) LIEF::to_string(x), x

namespace LIEF {

template<class T>
using getter_t = T (Function::*)(void) const;

template<class T>
using setter_t = void (Function::*)(T);

template<>
void create<Function>(py::module& m) {

py::class_<Function, Symbol> pyfunction(m, "Function");

py::enum_<Function::FLAGS>(pyfunction, "FLAGS")
.value(PY_ENUM(Function::FLAGS::IMPORTED))
.value(PY_ENUM(Function::FLAGS::EXPORTED))
.value(PY_ENUM(Function::FLAGS::CONSTRUCTOR))
.value(PY_ENUM(Function::FLAGS::DESTRUCTOR))
.value(PY_ENUM(Function::FLAGS::DEBUG));

pyfunction
.def(py::init())
.def(py::init<const std::string&>())
.def(py::init<uint64_t>())
.def(py::init<const std::string&, uint64_t>())


.def_property("address",
static_cast<getter_t<uint64_t>>(&Function::address),
static_cast<setter_t<uint64_t>>(&Function::address),
"Symbol's value")


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

}
39 changes: 21 additions & 18 deletions api/python/Abstract/objects/pyHeader.cpp
Expand Up @@ -15,61 +15,64 @@
*/
#include <sstream>

#include "init.hpp"
#include "pyAbstract.hpp"
#include "LIEF/Abstract/Header.hpp"

namespace LIEF {
template<class T>
using getter_t = T (LIEF::Header::*)(void) const;
using getter_t = T (Header::*)(void) const;

template<class T>
using setter_t = void (LIEF::Header::*)(T);
using setter_t = void (Header::*)(T);

void init_LIEF_Header_class(py::module& m) {
py::class_<LIEF::Header, LIEF::Object>(m, "Header")
template<>
void create<Header>(py::module& m) {
py::class_<Header, Object>(m, "Header")
.def(py::init())

.def_property("architecture",
static_cast<getter_t<LIEF::ARCHITECTURES>>(&LIEF::Header::architecture),
static_cast<setter_t<LIEF::ARCHITECTURES>>(&LIEF::Header::architecture),
static_cast<getter_t<ARCHITECTURES>>(&Header::architecture),
static_cast<setter_t<ARCHITECTURES>>(&Header::architecture),
"Target architecture (" RST_CLASS_REF(lief.ARCHITECTURES) ")")

.def_property("modes",
static_cast<getter_t<const std::set<LIEF::MODES>&>>(&LIEF::Header::modes),
static_cast<setter_t<const std::set<LIEF::MODES>&>>(&LIEF::Header::modes),
static_cast<getter_t<const std::set<MODES>&>>(&Header::modes),
static_cast<setter_t<const std::set<MODES>&>>(&Header::modes),
"Target " RST_CLASS_REF(lief.MODES) " (32-bits, 64-bits...)")

.def_property("entrypoint",
static_cast<getter_t<uint64_t>>(&LIEF::Header::entrypoint),
static_cast<setter_t<uint64_t>>(&LIEF::Header::entrypoint),
static_cast<getter_t<uint64_t>>(&Header::entrypoint),
static_cast<setter_t<uint64_t>>(&Header::entrypoint),
"Binary entrypoint")

.def_property("object_type",
static_cast<getter_t<LIEF::OBJECT_TYPES>>(&LIEF::Header::object_type),
static_cast<setter_t<LIEF::OBJECT_TYPES>>(&LIEF::Header::object_type),
static_cast<getter_t<OBJECT_TYPES>>(&Header::object_type),
static_cast<setter_t<OBJECT_TYPES>>(&Header::object_type),
"Type of the binary (executable, library...)\n"
"See: " RST_CLASS_REF(lief.OBJECT_TYPES) "")

.def_property("endianness",
static_cast<getter_t<LIEF::ENDIANNESS>>(&LIEF::Header::endianness),
static_cast<setter_t<LIEF::ENDIANNESS>>(&LIEF::Header::endianness),
static_cast<getter_t<ENDIANNESS>>(&Header::endianness),
static_cast<setter_t<ENDIANNESS>>(&Header::endianness),
"Binary endianness\n"
"See: " RST_CLASS_REF(lief.ENDIANNESS) "")

.def_property_readonly("is_32",
&LIEF::Header::is_32,
&Header::is_32,
"``True`` if the binary target a ``32-bits`` architecture")

.def_property_readonly("is_64",
&LIEF::Header::is_64,
&Header::is_64,
"``True`` if the binary target a ``64-bits`` architecture")


.def("__str__",
[] (const LIEF::Header& header)
[] (const Header& header)
{
std::ostringstream stream;
stream << header;
std::string str = stream.str();
return str;
});
}
}
13 changes: 8 additions & 5 deletions api/python/Abstract/objects/pyParser.cpp
Expand Up @@ -13,22 +13,24 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "init.hpp"
#include "pyAbstract.hpp"

#include "LIEF/Abstract/Parser.hpp"

#include <string>

void init_LIEF_Parser_class(py::module& m) {
namespace LIEF {
template<>
void create<Parser>(py::module& m) {

m.def("parse",
static_cast<std::unique_ptr<LIEF::Binary> (*) (const std::string&)>(&LIEF::Parser::parse),
static_cast<std::unique_ptr<Binary> (*) (const std::string&)>(&Parser::parse),
"Parse the given binary and return a " RST_CLASS_REF(lief.Binary) " object",
"filepath"_a,
py::return_value_policy::take_ownership);

m.def("parse",
static_cast<std::unique_ptr<LIEF::Binary> (*) (const std::vector<uint8_t>&, const std::string&)>(&LIEF::Parser::parse),
static_cast<std::unique_ptr<Binary> (*) (const std::vector<uint8_t>&, const std::string&)>(&Parser::parse),
"Parse the given binary and return a " RST_CLASS_REF(lief.Binary) " object",
"raw"_a, "name"_a = "",
py::return_value_policy::take_ownership);
Expand Down Expand Up @@ -65,9 +67,10 @@ void init_LIEF_Parser_class(py::module& m) {
std::make_move_iterator(std::begin(raw_str)),
std::make_move_iterator(std::end(raw_str))};

return LIEF::Parser::parse(std::move(raw), name);
return Parser::parse(std::move(raw), name);
},
"io"_a,
"name"_a = "",
py::return_value_policy::take_ownership);
}
}

0 comments on commit b5a0846

Please sign in to comment.