コード例 #1
0
ファイル: cpu.py プロジェクト: pmarkowsky/miasm
def ast_parse_op(t):
    if len(t) == 1:
        return t[0]
    if len(t) == 2:
        if t[0] in ['-', '+', '!']:
            return m2_expr.ExprOp(t[0], t[1])
    if len(t) == 3:
        args = [t[0], t[2]]
        if t[1] == '-':
            # a - b => a + (-b)
            t[1] = '+'
            t[2] = -t[2]
        return m2_expr.ExprOp(t[1], t[0], t[2])
    t = t[::-1]
    while len(t) >= 3:
        o1, op, o2 = t.pop(), t.pop(), t.pop()
        if op == '-':
            # a - b => a + (-b)
            op = '+'
            o2 = -o2
        e = m2_expr.ExprOp(op, o1, o2)
        t.append(e)
    if len(t) != 1:
        raise NotImplementedError('strange op')
    return t[0]
コード例 #2
0
    def patch_rotate_tpl(ir, instr, dst, src, op, left=False):
        '''Template to generate a rotater with operation @op
        A temporary basic block is generated to handle 0-rotate
        @op: operation to execute
        @left (optional): indicates a left rotate if set, default is False
        '''
        # Compute results
        shifter = get_shift(dst, src)
        res = m2_expr.ExprOp(op, dst, shifter)

        # CF is computed with 1-less round than `res`
        new_cf = m2_expr.ExprOp(
            op, dst, shifter - m2_expr.ExprInt(1, size=shifter.size))
        new_cf = new_cf.msb() if left else new_cf[:1]

        # OF is defined only for @b == 1
        new_of = m2_expr.ExprCond(
            src - m2_expr.ExprInt(1, size=src.size),
            m2_expr.ExprInt(0, size=of.size),
            res.msb() ^ new_cf if left else (dst ^ res).msb())

        # Build basic blocks
        e_do = [
            m2_expr.ExprAff(cf, new_cf),
            m2_expr.ExprAff(of, new_of),
            m2_expr.ExprAff(dst, res)
        ]
        # Don't generate conditional shifter on constant
        return (e_do, [])
コード例 #3
0
    def patch_div(ir, instr, src1):

        # print '[*] Calling patched div.'

        e = []
        size = src1.size
        if size == 8:
            src2 = mRAX[instr.mode][:16]
        elif size in [16, 32, 64]:
            s1, s2 = mRDX[size], mRAX[size]
            src2 = m2_expr.ExprCompose(s2, s1)
        else:
            raise ValueError('div arg not impl', src1)

        c_d = m2_expr.ExprOp('udiv', src2, src1.zeroExtend(src2.size))
        c_r = m2_expr.ExprOp('umod', src2, src1.zeroExtend(src2.size))

        # if 8 bit div, only ax is affected
        if size == 8:
            e.append(
                m2_expr.ExprAff(src2, m2_expr.ExprCompose(c_d[:8], c_r[:8])))
        else:
            e.append(m2_expr.ExprAff(s1, c_r[:size]))
            e.append(m2_expr.ExprAff(s2, c_d[:size]))

        return e, []
コード例 #4
0
    def patch_rotate_with_carry_tpl(ir, instr, op, dst, src):
        # Compute results
        shifter = get_shift(dst, src).zeroExtend(dst.size + 1)
        result = m2_expr.ExprOp(op, m2_expr.ExprCompose(dst, cf), shifter)

        new_cf = result[dst.size:dst.size + 1]
        new_dst = result[:dst.size]

        result_trunc = result[:dst.size]
        if op == '<<<':
            of_value = result_trunc.msb() ^ new_cf
        else:
            of_value = (dst ^ result_trunc).msb()
        # OF is defined only for @b == 1
        new_of = m2_expr.ExprCond(src - m2_expr.ExprInt(1, size=src.size),
                                  m2_expr.ExprInt(0, size=of.size), of_value)

        # Build basic blocks
        e_do = [
            m2_expr.ExprAff(cf, new_cf),
            m2_expr.ExprAff(of, new_of),
            m2_expr.ExprAff(dst, new_dst)
        ]

        return (e_do, [])
コード例 #5
0
    def substract_mems(self, a, b):
        ex = b.arg - a.arg
        ex = self.expr_simp(self.eval_expr(ex, {}))
        if not isinstance(ex, m2_expr.ExprInt):
            return None
        ptr_diff = int(int32(ex.arg))
        out = []
        if ptr_diff < 0:
            #    [a     ]
            #[b      ]XXX
            sub_size = b.size + ptr_diff * 8
            if sub_size >= a.size:
                pass
            else:
                ex = m2_expr.ExprOp('+', a.arg,
                                    m2_expr.ExprInt_from(a.arg, sub_size / 8))
                ex = self.expr_simp(self.eval_expr(ex, {}))

                rest_ptr = ex
                rest_size = a.size - sub_size

                val = self.symbols[a][sub_size:a.size]
                out = [(m2_expr.ExprMem(rest_ptr, rest_size), val)]
        else:
            #[a         ]
            # XXXX[b   ]YY

            #[a     ]
            # XXXX[b     ]

            out = []
            # part X
            if ptr_diff > 0:
                val = self.symbols[a][0:ptr_diff * 8]
                out.append((m2_expr.ExprMem(a.arg, ptr_diff * 8), val))
            # part Y
            if ptr_diff * 8 + b.size < a.size:

                ex = m2_expr.ExprOp('+', b.arg,
                                    m2_expr.ExprInt_from(b.arg, b.size / 8))
                ex = self.expr_simp(self.eval_expr(ex, {}))

                rest_ptr = ex
                rest_size = a.size - (ptr_diff * 8 + b.size)
                val = self.symbols[a][ptr_diff * 8 + b.size:a.size]
                out.append((m2_expr.ExprMem(ex, val.size), val))
        return out
コード例 #6
0
 def _simp_handle_segm(self, e_s, expr):
     """Handle 'segm' operation"""
     if expr.op != "segm":
         return expr
     segm_nb = int(expr.args[0])
     segmaddr = self.cpu.get_segm_base(segm_nb)
     return e_s(
         m2_expr.ExprOp("+", m2_expr.ExprInt(segmaddr, expr.size),
                        expr.args[1]))
コード例 #7
0
ファイル: sem.py プロジェクト: LOUISLCE/miasm
 def get_ir(self, instr):
     args = instr.args
     if len(args) and isinstance(args[-1], m2_expr.ExprOp):
         if (args[-1].op in ['<<', '>>', '<<a', 'a>>', '<<<', '>>>']
                 and isinstance(args[-1].args[-1], m2_expr.ExprId)):
             args[-1] = m2_expr.ExprOp(args[-1].op, args[-1].args[0],
                                       args[-1].args[-1][:8].zeroExtend(32))
     instr_ir, extra_ir = get_mnemo_expr(self, instr, *args)
     self.mod_pc(instr, instr_ir, extra_ir)
     instr_ir, extra_ir = self.del_dst_zr(instr, instr_ir, extra_ir)
     return instr_ir, extra_ir
コード例 #8
0
    def apply_expr_on_state_visit_cache(self, expr, state, cache, level=0):
        """
        Deep First evaluate nodes:
            1. evaluate node's sons
            2. simplify
        """

        expr = self.expr_simp(expr)

        #print '\t'*level, "Eval:", expr
        if expr in cache:
            ret = cache[expr]
            #print "In cache!", ret
        elif expr.is_int():
            return expr
        elif expr.is_id():
            if isinstance(expr.name, asmblock.AsmLabel) and expr.name.offset is not None:
                ret = m2_expr.ExprInt(expr.name.offset, expr.size)
            else:
                ret = state.get(expr, expr)
        elif expr.is_mem():
            ptr = self.apply_expr_on_state_visit_cache(expr.arg, state, cache, level+1)
            ret = m2_expr.ExprMem(ptr, expr.size)
            ret = self.get_mem_state(ret)
            assert expr.size == ret.size
        elif expr.is_cond():
            cond = self.apply_expr_on_state_visit_cache(expr.cond, state, cache, level+1)
            src1 = self.apply_expr_on_state_visit_cache(expr.src1, state, cache, level+1)
            src2 = self.apply_expr_on_state_visit_cache(expr.src2, state, cache, level+1)
            ret = m2_expr.ExprCond(cond, src1, src2)
        elif expr.is_slice():
            arg = self.apply_expr_on_state_visit_cache(expr.arg, state, cache, level+1)
            ret = m2_expr.ExprSlice(arg, expr.start, expr.stop)
        elif expr.is_op():
            args = []
            for oarg in expr.args:
                arg = self.apply_expr_on_state_visit_cache(oarg, state, cache, level+1)
                assert oarg.size == arg.size
                args.append(arg)
            ret = m2_expr.ExprOp(expr.op, *args)
        elif expr.is_compose():
            args = []
            for arg in expr.args:
                args.append(self.apply_expr_on_state_visit_cache(arg, state, cache, level+1))
            ret = m2_expr.ExprCompose(*args)
        else:
            raise TypeError("Unknown expr type")
        #print '\t'*level, "Result", ret
        ret = self.expr_simp(ret)
        #print '\t'*level, "Result simpl", ret

        assert expr.size == ret.size
        cache[expr] = ret
        return ret
コード例 #9
0
def asm_ast_to_expr_with_size(arg, symbol_pool, size):
    if isinstance(arg, AstId):
        return m2_expr.ExprId(arg.name, size)
    if isinstance(arg, AstOp):
        args = [
            asm_ast_to_expr_with_size(tmp, symbol_pool, size)
            for tmp in arg.args
        ]
        return m2_expr.ExprOp(arg.op, *args)
    if isinstance(arg, AstInt):
        return m2_expr.ExprInt(arg.value, size)
    return None
コード例 #10
0
def ast_parse_op(tokens):
    if len(tokens) == 1:
        return tokens[0]
    if len(tokens) == 2:
        if tokens[0] in ['-', '+', '!']:
            return m2_expr.ExprOp(tokens[0], tokens[1])
    if len(tokens) == 3:
        if tokens[1] == '-':
            # a - b => a + (-b)
            tokens[1] = '+'
            tokens[2] = -tokens[2]
        return m2_expr.ExprOp(tokens[1], tokens[0], tokens[2])
    tokens = tokens[::-1]
    while len(tokens) >= 3:
        o1, op, o2 = tokens.pop(), tokens.pop(), tokens.pop()
        if op == '-':
            # a - b => a + (-b)
            op = '+'
            o2 = -o2
        e = m2_expr.ExprOp(op, o1, o2)
        tokens.append(e)
    if len(tokens) != 1:
        raise NotImplementedError('strange op')
    return tokens[0]
コード例 #11
0
def simp_add_mul(expr_simp, expr):
    "Naive Simplification: a + a + a == a * 3"

    # Match the expected form
    ## isinstance(expr, m2_expr.ExprOp) is not needed: simplifications are
    ## attached to expression types
    if expr.op == "+" and \
            len(expr.args) == 3 and \
            expr.args.count(expr.args[0]) == len(expr.args):

        # Effective simplification
        return m2_expr.ExprOp("*", expr.args[0],
                              m2_expr.ExprInt(3, expr.args[0].size))
    else:
        # Do not simplify
        return expr
コード例 #12
0
    def operation(cls, size=32, depth=1):
        """Return an ExprOp
        @size: (optional) Operation size
        @depth: (optional) Expression depth
        """
        operand_type = random.choice(cls.operations_by_args_number.keys())
        if isinstance(operand_type, str) and "+" in operand_type:
            number_args = random.randint(int(operand_type[:-1]),
                                         cls.operations_max_args_number)
        else:
            number_args = operand_type

        args = [
            cls._gen(size=size, depth=depth - 1) for _ in xrange(number_args)
        ]
        operand = random.choice(cls.operations_by_args_number[operand_type])
        return m2_expr.ExprOp(operand, *args)
コード例 #13
0
def udiv(arg1, arg2, arg3):
    if arg3:
        arg1 = m2_expr.ExprOp('udiv', arg2, arg3)
    else:
        exception_flags = m2_expr.ExprInt(EXCEPT_DIV_BY_ZERO,
                                          exception_flags.size)
コード例 #14
0
def asr(arg1, arg2, arg3):
    arg1 = m2_expr.ExprOp(
        'a>>', arg2, (arg3 & m2_expr.ExprInt(arg3.size - 1, arg3.size)))
コード例 #15
0
def asr(arg1, arg2, arg3):
    arg1 = m2_expr.ExprOp('a>>', arg2,
                          (arg3 & m2_expr.ExprInt_from(arg3, arg3.size - 1)))
コード例 #16
0
    def eval_ExprMem(self, e, eval_cache=None):
        if eval_cache is None:
            eval_cache = {}
        a_val = self.expr_simp(self.eval_expr(e.arg, eval_cache))
        if a_val != e.arg:
            a = self.expr_simp(m2_expr.ExprMem(a_val, size=e.size))
        else:
            a = e
        if a in self.symbols:
            return self.symbols[a]
        tmp = None
        # test if mem lookup is known
        if a_val in self.symbols.symbols_mem:
            tmp = self.symbols.symbols_mem[a_val][0]
        if tmp is None:

            v = self.find_mem_by_addr(a_val)
            if not v:
                out = []
                ov = self.get_mem_overlapping(a, eval_cache)
                off_base = 0
                ov.sort()
                # ov.reverse()
                for off, x in ov:
                    # off_base = off * 8
                    # x_size = self.symbols[x].size
                    if off >= 0:
                        m = min(a.size - off * 8, x.size)
                        ee = m2_expr.ExprSlice(self.symbols[x], 0, m)
                        ee = self.expr_simp(ee)
                        out.append((ee, off_base, off_base + m))
                        off_base += m
                    else:
                        m = min(a.size - off * 8, x.size)
                        ee = m2_expr.ExprSlice(self.symbols[x], -off * 8, m)
                        ff = self.expr_simp(ee)
                        new_off_base = off_base + m + off * 8
                        out.append((ff, off_base, new_off_base))
                        off_base = new_off_base
                if out:
                    missing_slice = self.rest_slice(out, 0, a.size)
                    for sa, sb in missing_slice:
                        ptr = self.expr_simp(
                            a_val + m2_expr.ExprInt_from(a_val, sa / 8))
                        mm = m2_expr.ExprMem(ptr, size=sb - sa)
                        mm.is_term = True
                        mm.is_simp = True
                        out.append((mm, sa, sb))
                    out.sort(key=lambda x: x[1])
                    # for e, sa, sb in out:
                    #    print str(e), sa, sb
                    ee = m2_expr.ExprSlice(m2_expr.ExprCompose(out), 0, a.size)
                    ee = self.expr_simp(ee)
                    return ee
            if self.func_read and isinstance(a.arg, m2_expr.ExprInt):
                return self.func_read(a)
            else:
                # XXX hack test
                a.is_term = True
                return a
        # bigger lookup
        if a.size > tmp.size:
            rest = a.size
            ptr = a_val
            out = []
            ptr_index = 0
            while rest:
                v = self.find_mem_by_addr(ptr)
                if v is None:
                    # raise ValueError("cannot find %s in mem"%str(ptr))
                    val = m2_expr.ExprMem(ptr, 8)
                    v = val
                    diff_size = 8
                elif rest >= v.size:
                    val = self.symbols[v]
                    diff_size = v.size
                else:
                    diff_size = rest
                    val = self.symbols[v][0:diff_size]
                val = (val, ptr_index, ptr_index + diff_size)
                out.append(val)
                ptr_index += diff_size
                rest -= diff_size
                ptr = self.expr_simp(
                    self.eval_expr(
                        m2_expr.ExprOp('+', ptr,
                                       m2_expr.ExprInt_from(ptr, v.size / 8)),
                        eval_cache))
            e = self.expr_simp(m2_expr.ExprCompose(out))
            return e
        # part lookup
        tmp = self.expr_simp(m2_expr.ExprSlice(self.symbols[tmp], 0, a.size))
        return tmp
コード例 #17
0
def __ExprOp_cond(op, arg1, arg2):
    "Return an ExprOp standing for arg1 op arg2 with size to 1"
    ec = m2_expr.ExprOp(op, arg1, arg2)
    return ec
コード例 #18
0
ファイル: sem.py プロジェクト: pmarkowsky/miasm
def mul(ir, instr, a, b, c):
    """Multiplies @b by $c and stores the result in @a."""
    e = []
    e.append(m2_expr.ExprAff(a, m2_expr.ExprOp('imul', b, c)))
    return e, []
コード例 #19
0
    # Match the expected form
    ## isinstance(expr, m2_expr.ExprOp) is not needed: simplifications are
    ## attached to expression types
    if expr.op == "+" and \
            len(expr.args) == 3 and \
            expr.args.count(expr.args[0]) == len(expr.args):

        # Effective simplification
        return m2_expr.ExprOp("*", expr.args[0],
                              m2_expr.ExprInt(3, expr.args[0].size))
    else:
        # Do not simplify
        return expr


a = m2_expr.ExprId('a')
base_expr = a + a + a
print "Without adding the simplification:"
print "\t%s = %s" % (base_expr, expr_simp(base_expr))

# Enable pass
expr_simp.enable_passes({m2_expr.ExprOp: [simp_add_mul]})

print "After adding the simplification:"
print "\t%s = %s" % (base_expr, expr_simp(base_expr))

# Automatic fail
assert (expr_simp(base_expr) == m2_expr.ExprOp("*", a,
                                               m2_expr.ExprInt(3, a.size)))
コード例 #20
0
ファイル: sem.py プロジェクト: pmarkowsky/miasm
def swc1(ir, instr, a, b):
    e = []
    src = m2_expr.ExprOp('single_to_mem_%.2d' % a.size, a)
    e.append(m2_expr.ExprAff(b, src))
    return e, []
コード例 #21
0
ファイル: sem.py プロジェクト: pmarkowsky/miasm
def lwc1(ir, instr, a, b):
    e = []
    src = m2_expr.ExprOp('mem_%.2d_to_single' % b.size, b)
    e.append(m2_expr.ExprAff(a, src))
    return e, []
コード例 #22
0
ファイル: sem.py プロジェクト: pmarkowsky/miasm
def mul_d(ir, instr, a, b, c):
    # XXX TODO check
    e = []
    e.append(m2_expr.ExprAff(a, m2_expr.ExprOp('fmul', b, c)))
    return e, []
コード例 #23
0
def udiv(arg1, arg2, arg3):
    arg1 = m2_expr.ExprOp('udiv', arg2, arg3)
コード例 #24
0
ファイル: sem.py プロジェクト: pmarkowsky/miasm
def srav(ir, instr, a, b, c):
    e = []
    value = m2_expr.ExprOp('a>>', b, c&m2_expr.ExprInt32(0x1F))
    e.append(m2_expr.ExprAff(a, value))
    return e, []
コード例 #25
0
ファイル: sem.py プロジェクト: pmarkowsky/miasm
def sra(ir, instr, a, b, c):
    """Shifts a register value @b right by the shift amount @c and places the
    value in the destination register @a. The sign bit is shifted in."""
    e = []
    e.append(m2_expr.ExprAff(a, m2_expr.ExprOp('a>>', b, c)))
    return e, []
コード例 #26
0
def possible_values(expr):
    """Return possible values for expression @expr, associated with their
    condition constraint as a ConstrainedValues instance
    @expr: Expr instance
    """

    consvals = ConstrainedValues()

    # Terminal expression
    if (isinstance(expr, m2_expr.ExprInt) or
            isinstance(expr, m2_expr.ExprId)):
        consvals.add(ConstrainedValue(frozenset(), expr))
    # Unary expression
    elif isinstance(expr, m2_expr.ExprSlice):
        consvals.update(ConstrainedValue(consval.constraints,
                                         consval.value[expr.start:expr.stop])
                        for consval in possible_values(expr.arg))
    elif isinstance(expr, m2_expr.ExprMem):
        consvals.update(ConstrainedValue(consval.constraints,
                                         m2_expr.ExprMem(consval.value,
                                                         expr.size))
                        for consval in possible_values(expr.arg))
    elif isinstance(expr, m2_expr.ExprAff):
        consvals.update(possible_values(expr.src))
    # Special case: constraint insertion
    elif isinstance(expr, m2_expr.ExprCond):
        to_ret = set()
        src1cond = CondConstraintNotZero(expr.cond)
        src2cond = CondConstraintZero(expr.cond)
        consvals.update(ConstrainedValue(consval.constraints.union([src1cond]),
                                         consval.value)
                        for consval in possible_values(expr.src1))
        consvals.update(ConstrainedValue(consval.constraints.union([src2cond]),
                                         consval.value)
                        for consval in possible_values(expr.src2))
    # N-ary expression
    elif isinstance(expr, m2_expr.ExprOp):
        # For details, see ExprCompose
        consvals_args = [possible_values(arg) for arg in expr.args]
        for consvals_possibility in itertools.product(*consvals_args):
            args_value = [consval.value for consval in consvals_possibility]
            args_constraint = itertools.chain(*[consval.constraints
                                                for consval in consvals_possibility])
            consvals.add(ConstrainedValue(frozenset(args_constraint),
                                          m2_expr.ExprOp(expr.op, *args_value)))
    elif isinstance(expr, m2_expr.ExprCompose):
        # Generate each possibility for sub-argument, associated with the start
        # and stop bit
        consvals_args = [map(lambda x: x, possible_values(arg))
                         for arg in expr.args]
        for consvals_possibility in itertools.product(*consvals_args):
            # Merge constraint of each sub-element
            args_constraint = itertools.chain(*[consval.constraints
                                                for consval in consvals_possibility])
            # Gen the corresponding constraints / ExprCompose
            args = [consval.value for consval in consvals_possibility]
            consvals.add(
                ConstrainedValue(frozenset(args_constraint),
                                 m2_expr.ExprCompose(*args)))
    else:
        raise RuntimeError("Unsupported type for expr: %s" % type(expr))

    return consvals
コード例 #27
0
ファイル: sem.py プロジェクト: pmarkowsky/miasm
def c_le_d(ir, instr, a, b, c):
    e = []
    e.append(m2_expr.ExprAff(a, m2_expr.ExprOp('fcomp_le', b, c)))
    return e, []
コード例 #28
0
ファイル: sem.py プロジェクト: pmarkowsky/miasm
def cvt_d_w(ir, instr, a, b):
    e = []
    # TODO XXX
    e.append(m2_expr.ExprAff(a, m2_expr.ExprOp('flt_d_w', b)))
    return e, []
コード例 #29
0
ファイル: sem.py プロジェクト: pmarkowsky/miasm
def rotr(ir, instr, a, b, c):
    e = []
    e.append(m2_expr.ExprAff(a, m2_expr.ExprOp('>>>', b, c)))
    return e, []
コード例 #30
0
    "Naive Simplification: a + a + a == a * 3"

    # Match the expected form
    ## isinstance(expr, m2_expr.ExprOp) is not needed: simplifications are
    ## attached to expression types
    if expr.op == "+" and \
            len(expr.args) == 3 and \
            expr.args.count(expr.args[0]) == len(expr.args):

        # Effective simplification
        return m2_expr.ExprOp("*", expr.args[0],
                              m2_expr.ExprInt_from(expr.args[0], 3))
    else:
        # Do not simplify
        return expr

a = m2_expr.ExprId('a')
base_expr = a + a + a
print "Without adding the simplification:"
print "\t%s = %s" % (base_expr, expr_simp(base_expr))

# Enable pass
expr_simp.enable_passes({m2_expr.ExprOp: [simp_add_mul]})

print "After adding the simplification:"
print "\t%s = %s" % (base_expr, expr_simp(base_expr))

# Automatic fail
assert(expr_simp(base_expr) == m2_expr.ExprOp("*", a,
                                              m2_expr.ExprInt_from(a, 3)))