summaryrefslogtreecommitdiff
path: root/plugins/python/samples/basic_blocks.py
blob: 90f3a2c6672aca984bba37367ea5c138f7228881 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#!/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