Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Add constructor functions in the abstract layer
New API:
  * LIEF::ELF::Binary::get_relocation
  * LIEF::Binary::ctor_functions
  • Loading branch information
romainthomas committed Jun 19, 2018
1 parent 6e7e373 commit 67d924a
Show file tree
Hide file tree
Showing 13 changed files with 1,250 additions and 1,003 deletions.
4 changes: 4 additions & 0 deletions api/python/Abstract/objects/pyBinary.cpp
Expand Up @@ -195,6 +195,10 @@ void init_LIEF_Binary_class(py::module& m) {
"",
py::return_value_policy::reference)

.def_property_readonly("ctor_functions",
&Binary::ctor_functions,
"Constructor functions that are called prior any other functions")

.def("xref",
&Binary::xref,
"Return all **virtual address** that *use* the ``address`` given in parameter"
Expand Down
19 changes: 19 additions & 0 deletions api/python/ELF/objects/pyBinary.cpp
Expand Up @@ -458,6 +458,25 @@ void create<Binary>(py::module& m) {
py::return_value_policy::reference)


.def("get_relocation",
static_cast<no_const_func<Relocation*, const std::string&>>(&Binary::get_relocation),
"Return the " RST_CLASS_REF(lief.ELF.Relocation) " associated with the given symbol name",
"symbol_name"_a,
py::return_value_policy::reference)

.def("get_relocation",
static_cast<no_const_func<Relocation*, const Symbol&>>(&Binary::get_relocation),
"Return the " RST_CLASS_REF(lief.ELF.Relocation) " associated with the given " RST_CLASS_REF(lief.ELF.Symbol) "",
"symbol"_a,
py::return_value_policy::reference)

.def("get_relocation",
static_cast<no_const_func<Relocation*, uint64_t>>(&Binary::get_relocation),
"Return the " RST_CLASS_REF(lief.ELF.Relocation) " associated with the given address",
"address"_a,
py::return_value_policy::reference)



.def(py::self += Segment())
.def(py::self += Section())
Expand Down
17 changes: 17 additions & 0 deletions examples/python/elf_reader.py
Expand Up @@ -405,6 +405,16 @@ def print_notes(binary):
print("\n")


@exceptions_handler(Exception)
def print_ctor(binary):
print("== Constructors ==\n")

print("Functions: ({:d})".format(len(binary.ctor_functions)))
for idx, address in enumerate(binary.ctor_functions):
print(" [{:d}] 0x{:x}".format(idx, address))



def main():
optparser = OptionParser(
usage='Usage: %prog [options] <elf-file>',
Expand Down Expand Up @@ -484,6 +494,10 @@ def main():
default=False,
help='Do not trunc symbol names ...')

optparser.add_option('--ctor',
action='store_true', dest='show_ctor',
help='Constructor functions')

options, args = optparser.parse_args()

if options.help or len(args) == 0:
Expand Down Expand Up @@ -539,6 +553,9 @@ def main():
if options.show_notes or options.show_all:
print_notes(binary)

if options.show_ctor or options.show_all:
print_ctor(binary)




Expand Down
16 changes: 16 additions & 0 deletions examples/python/macho_reader.py
Expand Up @@ -632,6 +632,15 @@ def print_encryption_info(binary):
print("")


@exceptions_handler(Exception)
def print_ctor(binary):
print("== Constructors ==\n")

print("Functions: ({:d})".format(len(binary.ctor_functions)))
for idx, address in enumerate(binary.ctor_functions):
print(" [{:d}] 0x{:x}".format(idx, address))



def main():
parser = argparse.ArgumentParser(usage='%(prog)s [options] <macho-file>')
Expand Down Expand Up @@ -755,6 +764,10 @@ def main():
action='store_true', dest='show_opcodes',
help='Display the bind and rebase opcodes')

parser.add_argument('--ctor',
action='store_true', dest='show_ctor',
help='Constructor functions')

parser.add_argument("binary",
metavar="<macho-file>",
help='Target Mach-O File')
Expand Down Expand Up @@ -859,6 +872,9 @@ def main():
if (args.show_export_trie or args.show_opcodes) and binary.has_dyld_info:
print_export_trie(binary)

if args.show_ctor or args.show_all:
print_ctor(binary)

sys.exit(EXIT_STATUS)


Expand Down
16 changes: 16 additions & 0 deletions examples/python/pe_reader.py
Expand Up @@ -433,6 +433,15 @@ def print_load_configuration(binary):

print("")


@exceptions_handler(Exception)
def print_ctor(binary):
print("== Constructors ==\n")

print("Functions: ({:d})".format(len(binary.ctor_functions)))
for idx, address in enumerate(binary.ctor_functions):
print(" [{:d}] 0x{:x}".format(idx, address))

def main():
optparser = OptionParser(
usage='Usage: %prog [options] <pe-file>',
Expand Down Expand Up @@ -500,6 +509,10 @@ def main():
action='store_true', dest='show_loadconfig',
help='Display load configuration')

optparser.add_option('--ctor',
action='store_true', dest='show_ctor',
help='Constructor functions')



options, args = optparser.parse_args()
Expand Down Expand Up @@ -557,5 +570,8 @@ def main():
if (options.show_loadconfig or options.show_all) and binary.has_configuration:
print_load_configuration(binary)

if options.show_ctor or options.show_all:
print_ctor(binary)

if __name__ == "__main__":
main()
169 changes: 87 additions & 82 deletions include/LIEF/Abstract/Binary.hpp
Expand Up @@ -37,123 +37,128 @@ class LIEF_API Binary : public Object {

public:

//! Type of a virtual address
enum class VA_TYPES {
AUTO = 0, ///< Guess if it's relative or not
RVA = 1, ///< Relative
VA = 2, ///< Absolute
};
//! Type of a virtual address
enum class VA_TYPES {
AUTO = 0, ///< Guess if it's relative or not
RVA = 1, ///< Relative
VA = 2, ///< Absolute
};

using ctor_t = std::vector<uint64_t>;

public:
Binary(void);
virtual ~Binary(void);
Binary(void);
virtual ~Binary(void);

Binary& operator=(const Binary&);
Binary(const Binary&);

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

//! @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 header(void) const;

//! @brief Return the abstract header of the binary
Header header(void) const;
//! @brief Return list of symbols whose elements **can** be modified
it_symbols symbols(void);

//! @brief Return list of symbols whose elements **can** be modified
it_symbols symbols(void);
//! @brief Return list of symbols whose elements **can't** be modified
it_const_symbols symbols(void) const;

//! @brief Return list of symbols whose elements **can't** be modified
it_const_symbols symbols(void) const;
//! @brief Check if a Symbol with the given name exists
bool has_symbol(const std::string& name) const;

//! @brief Check if a Symbol with the given name exists
bool has_symbol(const std::string& name) const;
//! @brief Return the Symbol with the given name
const Symbol& get_symbol(const std::string& name) const;

//! @brief Return the Symbol with the given name
const Symbol& get_symbol(const std::string& name) const;
Symbol& get_symbol(const std::string& name);

Symbol& get_symbol(const std::string& name);
//! @brief Returns binary's sections
it_sections sections(void);
it_const_sections sections(void) const;

//! @brief Returns binary's sections
it_sections sections(void);
it_const_sections sections(void) const;
//! @brief Returns binary's relocations
it_relocations relocations(void);
it_const_relocations relocations(void) const;

//! @brief Returns binary's relocations
it_relocations relocations(void);
it_const_relocations relocations(void) const;
//! @brief Binary's entrypoint (if any)
virtual uint64_t entrypoint(void) const = 0;

//! @brief Binary's entrypoint (if any)
virtual uint64_t entrypoint(void) const = 0;
//! @brief Binary's name
const std::string& name(void) const;

//! @brief Binary's name
const std::string& name(void) const;
//! @brief Binary's original size
uint64_t original_size(void) const;

//! @brief Binary's original size
uint64_t original_size(void) const;
//! @brief Return functions's name exported by the binary
std::vector<std::string> exported_functions(void) const;

//! @brief Return functions's name exported by the binary
std::vector<std::string> exported_functions(void) const;
//! @brief Return libraries which are imported by the binary
std::vector<std::string> imported_libraries(void) const;

//! @brief Return libraries which are imported by the binary
std::vector<std::string> imported_libraries(void) const;
//! @brief Return functions's name imported by the binary
std::vector<std::string> imported_functions(void) const;

//! @brief Return functions's name imported by the binary
std::vector<std::string> imported_functions(void) const;
//! @brief Return the address of the given function name
virtual uint64_t get_function_address(const std::string& func_name) const;

//! @brief Return the address of the given function name
virtual uint64_t get_function_address(const std::string& func_name) const;
//! @brief Method so that a ``visitor`` can visit us
virtual void accept(Visitor& visitor) const override;

//! @brief Method so that a ``visitor`` can visit us
virtual void accept(Visitor& visitor) const override;
std::vector<uint64_t> xref(uint64_t address) const;

std::vector<uint64_t> xref(uint64_t address) const;
//! @brief Patch the content at virtual address @p address with @p patch_value
//!
//! @param[in] address Address to patch
//! @param[in] patch_value Patch to apply
virtual void patch_address(uint64_t address, const std::vector<uint8_t>& patch_value, VA_TYPES addr_type = VA_TYPES::AUTO) = 0;

//! @brief Patch the content at virtual address @p address with @p patch_value
//!
//! @param[in] address Address to patch
//! @param[in] patch_value Patch to apply
virtual void patch_address(uint64_t address, const std::vector<uint8_t>& patch_value, VA_TYPES addr_type = VA_TYPES::AUTO) = 0;
//! @brief Patch the address with the given value
//!
//! @param[in] address Address to patch
//! @param[in] patch_value Patch to apply
//! @param[in] size Size of the value in **bytes** (1, 2, ... 8)
virtual void patch_address(uint64_t address, uint64_t patch_value, size_t size = sizeof(uint64_t), VA_TYPES addr_type = VA_TYPES::AUTO) = 0;

//! @brief Patch the address with the given value
//!
//! @param[in] address Address to patch
//! @param[in] patch_value Patch to apply
//! @param[in] size Size of the value in **bytes** (1, 2, ... 8)
virtual void patch_address(uint64_t address, uint64_t patch_value, size_t size = sizeof(uint64_t), VA_TYPES addr_type = VA_TYPES::AUTO) = 0;
//! @brief Return the content located at virtual address
virtual std::vector<uint8_t> get_content_from_virtual_address(uint64_t virtual_address, uint64_t size, VA_TYPES addr_type = VA_TYPES::AUTO) const = 0;

//! @brief Return the content located at virtual address
virtual std::vector<uint8_t> get_content_from_virtual_address(uint64_t virtual_address, uint64_t size, VA_TYPES addr_type = VA_TYPES::AUTO) const = 0;
//! @brief Change binary's name
void name(const std::string& name);

//! @brief Change binary's name
void name(const std::string& name);
//! @brief Change binary's original size.
//!
//! @warning
//! Should be used carefully because some optimizations can be
//! done with this value
void original_size(uint64_t size);

//! @brief Change binary's original size.
//!
//! @warning
//! Should be used carefully because some optimizations can be
//! done with this value
void original_size(uint64_t size);
//! @brief Check if the binary is position independent
virtual bool is_pie(void) const = 0;

//! @brief Check if the binary is position independent
virtual bool is_pie(void) const = 0;
//! @brief Check if the binary uses ``NX`` protection
virtual bool has_nx(void) const = 0;

//! @brief Check if the binary uses ``NX`` protection
virtual bool has_nx(void) const = 0;
//! Constructor functions that are called prior any other functions
virtual LIEF::Binary::ctor_t ctor_functions(void) const = 0;

virtual std::ostream& print(std::ostream& os) const;
virtual std::ostream& print(std::ostream& os) const;

LIEF_API friend std::ostream& operator<<(std::ostream& os, const Binary& binary);
LIEF_API friend std::ostream& operator<<(std::ostream& os, const Binary& binary);

protected:
std::string name_;
std::string name_;

uint64_t original_size_;
uint64_t original_size_;

virtual Header get_abstract_header(void) const = 0;
virtual symbols_t get_abstract_symbols(void) = 0;
virtual sections_t get_abstract_sections(void) = 0;
virtual relocations_t get_abstract_relocations(void) = 0;
virtual Header get_abstract_header(void) const = 0;
virtual symbols_t get_abstract_symbols(void) = 0;
virtual sections_t get_abstract_sections(void) = 0;
virtual relocations_t get_abstract_relocations(void) = 0;

virtual std::vector<std::string> get_abstract_exported_functions(void) const = 0;
virtual std::vector<std::string> get_abstract_imported_functions(void) const = 0;
virtual std::vector<std::string> get_abstract_imported_libraries(void) const = 0;
virtual std::vector<std::string> get_abstract_exported_functions(void) const = 0;
virtual std::vector<std::string> get_abstract_imported_functions(void) const = 0;
virtual std::vector<std::string> get_abstract_imported_libraries(void) const = 0;


};
Expand Down

0 comments on commit 67d924a

Please sign in to comment.