LIEF/examples/python/abstract_reader.py
2018-10-01 10:40:58 +02:00

214 lines
6.0 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Description
# -----------
# Universal format reader.
# Input can be PE, ELF or Mach-O
import lief
import sys
import argparse
import traceback
class exceptions_handler(object):
func = None
def __init__(self, exceptions, on_except_callback=None):
self.exceptions = exceptions
self.on_except_callback = on_except_callback
def __call__(self, *args, **kwargs):
if self.func is None:
self.func = args[0]
return self
try:
return self.func(*args, **kwargs)
except self.exceptions as e:
if self.on_except_callback is not None:
self.on_except_callback(e)
else:
print("-" * 60)
print("Exception in {}: {}".format(self.func.__name__, e))
exc_type, exc_value, exc_traceback = sys.exc_info()
traceback.print_tb(exc_traceback)
print("-" * 60)
@exceptions_handler(Exception)
def print_header(binary):
header = binary.header
print("== Header ==\n")
format_str = "{:<15} {:<30}"
format_hex = "{:<15} 0x{:<13x}"
format_dec = "{:<15} {:<30d}"
modes_str = " - ".join([str(m).split(".")[-1] for m in header.modes])
bitness = ""
if header.is_32:
bitness = "32-bits"
if header.is_64:
bitness = "64-bits"
print(format_str.format("Architecture:", str(header.architecture).split(".")[-1]))
print(format_str.format("Modes:", modes_str))
print(format_hex.format("Entrypoint:", header.entrypoint))
print(format_str.format("Object type:", str(header.object_type).split(".")[-1]))
print(format_str.format("Endianness:", str(header.endianness).split(".")[-1]))
print(format_str.format("Bitness:", bitness))
print("")
@exceptions_handler(Exception)
def print_sections(binary):
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 binary.sections:
print(f_value.format(\
section.name,\
section.offset,\
section.size,\
section.virtual_address,\
section.entropy))
print("")
@exceptions_handler(Exception)
def print_relocations(binary):
print("== Relocations ==")
f_title = "|{:<18} | {:<6}|"
f_value = "|0x{:<16x} | {:<6d}|"
print(f_title.format("Address", "Size"))
for relocation in binary.relocations:
print(f_value.format(\
relocation.address,\
relocation.size))
print("")
@exceptions_handler(Exception)
def print_symbols(binary):
print("== Symbols ==")
f = "|{:<30} |"
print(f.format("Name"))
for symbol in binary.symbols:
print(f.format(symbol.name))
print("")
@exceptions_handler(Exception)
def print_exported_functions(binary):
print("== Exported functions ==")
f = "|{:<30} |"
print(f.format("Name"))
for func in binary.exported_functions:
print(f.format(func))
print("")
@exceptions_handler(Exception)
def print_imported_functions(binary):
print("== Imported functions ==")
f = "|{:<30} |"
print(f.format("Name"))
for func in binary.imported_functions:
print(f.format(func))
print("")
@exceptions_handler(Exception)
def print_imported_libraries(binary):
print("== Imported Libraries ==")
f = "|{:<30} |"
print(f.format("Name"))
for library in binary.libraries:
print(f.format(library))
print("")
def main():
parser = argparse.ArgumentParser(usage='%(prog)s [options] <elf-pe-macho>')
parser.add_argument('-a', '--all',
action='store_true', dest='show_all',
help='Show all information')
parser.add_argument('-H', '--header',
action='store_true', dest='show_header',
help='Display header')
parser.add_argument('-i', '--imported',
action='store_true', dest='show_imported_functions',
help='Display imported functions')
parser.add_argument('-L', '--libraries',
action='store_true', dest='show_libraries',
help='Display Imported Libraries')
parser.add_argument('-r', '--relocations',
action='store_true', dest='show_relocs',
help='Display the relocations (if present)')
parser.add_argument('-s', '--symbols',
action='store_true', dest='show_symbols',
help='Display Symbols')
parser.add_argument('-S', '--sections',
action='store_true', dest='show_sections',
help='Display Sections')
parser.add_argument('-x', '--exported',
action='store_true', dest='show_exported_functions',
help='Display exported functions')
parser.add_argument("binary",
metavar="<elf-pe-macho>",
help='Target File')
args = parser.parse_args()
binary = None
try:
binary = lief.parse(args.binary)
except lief.exception as e:
print(e)
sys.exit(1)
binary = binary.abstract
if args.show_header or args.show_all:
print_header(binary)
if (args.show_imported_functions or args.show_all) and len(binary.imported_functions) > 0:
print_imported_functions(binary)
if (args.show_exported_functions or args.show_all) and len(binary.exported_functions) > 0:
print_exported_functions(binary)
if (args.show_libraries or args.show_all) and len(binary.libraries) > 0:
print_imported_libraries(binary)
if (args.show_sections or args.show_all) and len(binary.sections) > 0:
print_sections(binary)
if (args.show_symbols or args.show_all) and len(binary.symbols) > 0:
print_symbols(binary)
if (args.show_relocs or args.show_all) and len(binary.relocations) > 0:
print_relocations(binary)
if __name__ == "__main__":
main()