Source code for ducky.tools.profile

try:
  import cPickle as pickle

except ImportError:
  import pickle

import collections
import optparse
import sys

from six import itervalues

[docs]def read_profiling_data(logger, files_in): from ..profiler import ProfileRecord data = collections.defaultdict(ProfileRecord) for path in files_in: logger.info('Reading profile data from %s', path) with open(path, 'rb') as f_in: file_data = pickle.load(f_in) for record in itervalues(file_data): data[record.ip].merge(record) logger.debug('%d records merged', len(file_data)) return data
[docs]def main(): from . import add_common_options, parse_options parser = optparse.OptionParser() add_common_options(parser) parser.add_option('-i', dest = 'files_in', action = 'append', default = [], help = 'Input file') parser.add_option('-b', dest = 'binary', action = 'store', default = None, help = 'Profiled binary') options, logger = parse_options(parser) if not options.files_in: parser.print_help() sys.exit(1) if not options.binary: parser.print_help() sys.exit(1) merged_data = read_profiling_data(logger, options.files_in) from ..mm.binary import File from ..util import SymbolTable binary = File.open(logger, options.binary, 'r') binary.load() binary.load_symbols() symbol_table = SymbolTable(binary) all_hits = sum([record.count for record in itervalues(merged_data)]) def print_points(): from ..mm import UINT32_FMT from ..cpu.instructions import DuckyInstructionSet table = [ ['Address', 'Symbol', 'Offset', 'Hits', 'Percentage', 'Inst'] ] for ip in sorted(merged_data.keys(), key = lambda x: merged_data[x].count, reverse = True): record = merged_data[ip] # binary_ip = record.ip - DEFAULT_BOOTLOADER_ADDRESS binary_ip = record.ip symbol, offset = symbol_table[binary_ip] if symbol is None: symbol_name = '' inst_disassembly = '<unknown>' else: symbol_name = symbol symbol = symbol_table.get_symbol(symbol) header, content = binary.get_section(symbol.section) inst_encoding, inst_cls, inst_opcode = DuckyInstructionSet.decode_instruction(logger, content[(symbol.address + offset - header.base) / 4].value) inst_disassembly = DuckyInstructionSet.disassemble_instruction(logger, inst_encoding) table.append([UINT32_FMT(binary_ip), symbol_name, UINT32_FMT(offset), record.count, '%.02f' % (float(record.count) / float(all_hits) * 100.0), inst_disassembly]) logger.table(table) print_points()