about summary refs log tree commit diff stats
path: root/miasm2/ir/translators/python.py
blob: f32e458597ec92531cc74cef629c09cda9b759fc (plain) (blame)
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
from miasm2.expression.expression import ExprInt
from miasm2.ir.translators.translator import Translator


class TranslatorPython(Translator):
    """Translate a Miasm expression to an equivalent Python code

    Memory is abstracted using the unimplemented function:
    int memory(int address, int size)
    """

    # Implemented language
    __LANG__ = "Python"
    # Operations translation
    op_no_translate = ["+", "-", "/", "%", ">>", "<<", "&", "^", "|", "*"]

    def from_ExprInt(self, expr):
        return str(expr)

    def from_ExprId(self, expr):
        return str(expr)

    def from_ExprLoc(self, expr):
        return str(expr)

    def from_ExprMem(self, expr):
        return "memory(%s, 0x%x)" % (self.from_expr(expr.ptr),
                                     expr.size / 8)

    def from_ExprSlice(self, expr):
        out = self.from_expr(expr.arg)
        if expr.start != 0:
            out = "(%s >> %d)" % (out, expr.start)
        return "(%s & 0x%x)" % (out, (1 << (expr.stop - expr.start)) - 1)

    def from_ExprCompose(self, expr):
        out = []
        for index, arg in expr.iter_args():
            out.append("((%s & 0x%x) << %d)" % (self.from_expr(arg),
                                                 (1 << arg.size) - 1,
                                                 index))
        return "(%s)" % ' | '.join(out)

    def from_ExprCond(self, expr):
        return "(%s if (%s) else %s)" % (self.from_expr(expr.src1),
                                         self.from_expr(expr.cond),
                                         self.from_expr(expr.src2))

    def from_ExprOp(self, expr):
        if expr.op in self.op_no_translate:
            args = map(self.from_expr, expr.args)
            if len(expr.args) == 1:
                return "((%s %s) & 0x%x)" % (expr.op,
                                             args[0],
                                             (1 << expr.size) - 1)
            else:
                return "((%s) & 0x%x)" % ((" %s " % expr.op).join(args),
                                        (1 << expr.size) - 1)
        elif expr.op == "parity":
            return "(%s & 0x1)" % self.from_expr(expr.args[0])

        elif expr.op in ["<<<", ">>>"]:
            amount_raw = expr.args[1]
            amount = expr.args[1] % ExprInt(amount_raw.size, expr.size)
            amount_inv = ExprInt(expr.size, expr.size) - amount
            if expr.op == "<<<":
                amount, amount_inv = amount_inv, amount
            part1 = "(%s >> %s)"% (self.from_expr(expr.args[0]),
                                   self.from_expr(amount))
            part2 = "(%s << %s)"% (self.from_expr(expr.args[0]),
                                         self.from_expr(amount_inv))

            return "((%s | %s) &0x%x)" % (part1, part2, int(expr.mask))

        raise NotImplementedError("Unknown operator: %s" % expr.op)

    def from_ExprAssign(self, expr):
        return "%s = %s" % tuple(map(self.from_expr, (expr.dst, expr.src)))


# Register the class
Translator.register(TranslatorPython)