2017-03-30 16:56:49 +02:00
|
|
|
|
#/usr/bin/env python
|
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
|
|
# Description
|
|
|
|
|
# -----------
|
|
|
|
|
# Universal format reader.
|
|
|
|
|
# Input can be PE, ELF or Mach-O
|
|
|
|
|
|
|
|
|
|
import lief
|
|
|
|
|
import sys
|
|
|
|
|
|
|
|
|
|
def print_sections(sections):
|
|
|
|
|
print("== Sections ==")
|
|
|
|
|
f_title = "|{:<30} | {:<18}| {:<18}| {:<18}| {:<9}|"
|
|
|
|
|
f_value = "|{:<30} | 0x{:<16x}| 0x{:<16x}| 0x{:<16x}| {:<9.2f}|"
|
|
|
|
|
print(f_title.format("Name", "File offset", "Size", "Virtual Address", "Entropy"))
|
|
|
|
|
for section in sections:
|
|
|
|
|
print(f_value.format(\
|
|
|
|
|
section.name,\
|
|
|
|
|
section.offset,\
|
|
|
|
|
section.size,\
|
|
|
|
|
section.virtual_address,\
|
|
|
|
|
section.entropy))
|
|
|
|
|
print("")
|
|
|
|
|
|
|
|
|
|
def print_symbols(symbols):
|
|
|
|
|
|
|
|
|
|
print("== Symbols ==")
|
|
|
|
|
|
|
|
|
|
f = "|{:<30} |"
|
|
|
|
|
|
|
|
|
|
print(f.format("Name"))
|
|
|
|
|
|
|
|
|
|
for symbol in symbols:
|
|
|
|
|
print(f.format(symbol.name))
|
|
|
|
|
print("")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def print_exported_functions(functions):
|
|
|
|
|
|
|
|
|
|
print("== Exported functions ==")
|
|
|
|
|
f = "|{:<30} |"
|
|
|
|
|
print(f.format("Name"))
|
|
|
|
|
for func in functions:
|
|
|
|
|
print(f.format(func))
|
|
|
|
|
print("")
|
|
|
|
|
|
|
|
|
|
def print_imported_functions(functions):
|
|
|
|
|
|
|
|
|
|
print("== Imported functions ==")
|
|
|
|
|
f = "|{:<30} |"
|
|
|
|
|
print(f.format("Name"))
|
|
|
|
|
for func in functions:
|
|
|
|
|
print(f.format(func))
|
|
|
|
|
print("")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def print_imported_libraries(libraries):
|
|
|
|
|
|
|
|
|
|
print("== Imported Libraries ==")
|
|
|
|
|
f = "|{:<30} |"
|
|
|
|
|
print(f.format("Name"))
|
|
|
|
|
for library in libraries:
|
|
|
|
|
print(f.format(library))
|
|
|
|
|
print("")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def read_binary(path):
|
|
|
|
|
print("== Abstract Reader ==")
|
|
|
|
|
|
Improve the ELF part of LIEF
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
2017-09-02 08:54:54 +02:00
|
|
|
|
binary = lief.parse(path).abstract
|
2017-06-27 16:01:03 +02:00
|
|
|
|
header = binary.header
|
|
|
|
|
print(header)
|
2017-03-30 16:56:49 +02:00
|
|
|
|
|
|
|
|
|
sections = binary.sections
|
|
|
|
|
symbols = binary.symbols
|
|
|
|
|
func_exported = binary.exported_functions
|
|
|
|
|
func_imported = binary.imported_functions
|
|
|
|
|
libraries = binary.libraries
|
|
|
|
|
|
|
|
|
|
if len(sections) > 0:
|
|
|
|
|
print_sections(sections)
|
|
|
|
|
|
|
|
|
|
if len(symbols) > 0:
|
|
|
|
|
print_symbols(symbols)
|
|
|
|
|
|
|
|
|
|
if len(func_exported) > 0:
|
|
|
|
|
print_exported_functions(func_exported)
|
|
|
|
|
|
|
|
|
|
if len(func_imported) > 0:
|
|
|
|
|
print_imported_functions(func_imported)
|
|
|
|
|
|
|
|
|
|
if len(libraries) > 0:
|
|
|
|
|
print_imported_libraries(libraries)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
|
|
|
|
|
if len(sys.argv) != 2:
|
|
|
|
|
print("Usage:", sys.argv[0], "<binary>")
|
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
|
|
read_binary(sys.argv[1])
|
|
|
|
|
|