#!/usr/bin/python # -*- coding: utf-8 -*- import re from pychrysalide.analysis import InstrBlock from pychrysalide.analysis.blocks import FlowBlock class VisitIndent: def __init__(self): self.offset = 0 def get_padding(self): return ' ' * self.offset def inc_offset(self): self.offset = self.offset + 1 def dec_offset(self): self.offset = self.offset - 1 def get_c_address_of_pygobject(obj): """Parse the string representation of a given object and return its memory address.""" ret = re.match('.*(0x[0-9a-f]+)\)>', str(obj), re.I) if ret == None: result = '???' else: result = ret.group(1) return result def visit_block(block, order, indent): """Describe each visited basic block.""" padding = indent.get_padding() addr = get_c_address_of_pygobject(block) if isinstance(block, FlowBlock): start, end = block.boundary_addresses rank = block.rank links = block.get_links_block() if links != None: laddr = get_c_address_of_pygobject(links) print '%s- flow %s (rank=%d) : 0x%08lx -> 0x%08lx (links = %s)' \ % (padding, addr, rank, start, end, laddr) else: print '%s- flow %s (rank=%d) : 0x%08lx -> 0x%08lx' \ % (padding, addr, rank, start, end) else: if order != InstrBlock.BVO_OUT: print '%s- virtual %s' % (padding, addr) indent.inc_offset() else: indent.dec_offset() return True def show_basic_blocks(binary): """Print the tree of all basic blocks for each routine of a given binary.""" fmt = binary.get_format() indent = VisitIndent() for r in fmt.routines: print '==== %s ====' % str(r) r.basic_blocks.visit(visit_block, indent) print