Example #1
0
def csetm(ir, instr, arg1, arg2):
    e = []
    cond_expr = cond2expr[arg2.name]
    e.append(
        m2_expr.ExprAff(
            arg1,
            m2_expr.ExprCond(cond_expr, m2_expr.ExprInt(-1, arg1.size),
                             m2_expr.ExprInt(0, arg1.size))))
    return e, []
Example #2
0
def csinc(ir, instr, arg1, arg2, arg3, arg4):
    e = []
    cond_expr = cond2expr[arg4.name]
    e.append(
        m2_expr.ExprAff(
            arg1,
            m2_expr.ExprCond(cond_expr, arg2,
                             arg3 + m2_expr.ExprInt(1, arg3.size))))
    return e, []
Example #3
0
File: sem.py Project: digdugg/miasm
def csetm(ir, instr, arg1, arg2):
    e = []
    cond_expr = cond2expr[arg2.name]
    e.append(
        m2_expr.ExprAff(
            arg1,
            m2_expr.ExprCond(cond_expr, m2_expr.ExprInt_from(arg1, -1),
                             m2_expr.ExprInt_from(arg1, 0))))
    return e, []
Example #4
0
def expr_simp_equal(expr_simp, e):
    """(x - y)?(0:1) == (x == y)"""

    to_match = m2_expr.ExprCond(jok1 + jok2, m2_expr.ExprInt1(0),
                                m2_expr.ExprInt1(1))
    r = __MatchExprWrap(e, to_match, [jok1, jok2])
    if r is False:
        return e

    return ExprOp_equal(r[jok1], expr_simp(-r[jok2]))
Example #5
0
def bgez(ir, instr, a, b):
    """Branches on @b if the quantities of register @a is greater than or equal
    to zero"""
    e = []
    n = m2_expr.ExprId(ir.get_next_break_label(instr))
    dst_o = m2_expr.ExprCond(a.msb(), n, b)
    e = [m2_expr.ExprAff(PC, dst_o),
         m2_expr.ExprAff(ir.IRDst, dst_o)
     ]
    return e, []
Example #6
0
def movz(ir, instr, a, b, c):
    lbl_do = m2_expr.ExprId(ir.gen_label(), 32)
    lbl_skip = m2_expr.ExprId(ir.get_next_instr(instr), 32)
    e_do = []
    e_do.append(m2_expr.ExprAff(a, b))
    e_do.append(m2_expr.ExprAff(ir.IRDst, lbl_skip))
    e = []
    e.append(m2_expr.ExprAff(ir.IRDst, m2_expr.ExprCond(c, lbl_skip, lbl_do)))

    return e, [irbloc(lbl_do.name, [e_do], [])]
Example #7
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
Example #8
0
def ccmp(ir, instr, arg1, arg2, arg3, arg4):
    e = []
    if (arg2.is_int):
        arg2 = m2_expr.ExprInt(arg2.arg.arg, arg1.size)
    default_nf = arg3[0:1]
    default_zf = arg3[1:2]
    default_cf = arg3[2:3]
    default_of = arg3[3:4]
    cond_expr = cond2expr[arg4.name]
    res = arg1 - arg2
    new_nf = nf
    new_zf = update_flag_zf(res)[0].src
    new_cf = update_flag_sub_cf(arg1, arg2, res).src
    new_of = update_flag_sub_of(arg1, arg2, res).src

    e.append(
        m2_expr.ExprAff(nf, m2_expr.ExprCond(cond_expr, new_nf, default_nf)))
    e.append(
        m2_expr.ExprAff(zf, m2_expr.ExprCond(cond_expr, new_zf, default_zf)))
    e.append(
        m2_expr.ExprAff(cf, m2_expr.ExprCond(cond_expr, new_cf, default_cf)))
    e.append(
        m2_expr.ExprAff(of, m2_expr.ExprCond(cond_expr, new_of, default_of)))
    return e, []
Example #9
0
def teq(ir, instr, arg1, arg2):
    e = []

    loc_except, loc_except_expr = ir.gen_loc_key_and_expr(ir.IRDst.size)
    loc_next = ir.get_next_loc_key(instr)
    loc_next_expr = m2_expr.ExprLoc(loc_next, ir.IRDst.size)

    do_except = []
    do_except.append(
        m2_expr.ExprAssign(
            exception_flags,
            m2_expr.ExprInt(EXCEPT_DIV_BY_ZERO, exception_flags.size)))
    do_except.append(m2_expr.ExprAssign(ir.IRDst, loc_next_expr))
    blk_except = IRBlock(loc_except.index, [AssignBlock(do_except, instr)])

    cond = arg1 - arg2

    e = []
    e.append(
        m2_expr.ExprAssign(
            ir.IRDst, m2_expr.ExprCond(cond, loc_next_expr, loc_except_expr)))

    return e, [blk_except]
Example #10
0
def teq(ir, instr, arg1, arg2):
    e = []

    lbl_except, lbl_except_expr = ir.gen_label_and_expr(ir.IRDst.size)
    lbl_next = ir.get_next_label(instr)
    lbl_next_expr = m2_expr.ExprId(lbl_next, ir.IRDst.size)

    do_except = []
    do_except.append(
        m2_expr.ExprAff(
            exception_flags,
            m2_expr.ExprInt(EXCEPT_DIV_BY_ZERO, exception_flags.size)))
    do_except.append(m2_expr.ExprAff(ir.IRDst, lbl_next_expr))
    blk_except = IRBlock(lbl_except, [AssignBlock(do_except, instr)])

    cond = arg1 - arg2

    e = []
    e.append(
        m2_expr.ExprAff(ir.IRDst,
                        m2_expr.ExprCond(cond, lbl_next_expr,
                                         lbl_except_expr)))

    return e, [blk_except]
Example #11
0
 def to_constraint(self):
     cst1, cst2 = m2_expr.ExprInt(0, 1), m2_expr.ExprInt(1, 1)
     return m2_expr.ExprAff(cst1, m2_expr.ExprCond(self.expr, cst1, cst2))
Example #12
0
def update_flag_zf(a):
    return [m2_expr.ExprAff(zf, m2_expr.ExprCond(a, m2_expr.ExprInt(0, 1), m2_expr.ExprInt(1, 1)))]
Example #13
0
def update_flag_zf(a):
    return [
        m2_expr.ExprAff(
            zf, m2_expr.ExprCond(a, m2_expr.ExprInt1(0), m2_expr.ExprInt1(1)))
    ]
Example #14
0
    def patch_shift_tpl(op,
                        ir,
                        instr,
                        a,
                        b,
                        c=None,
                        op_inv=None,
                        left=False,
                        custom_of=None):
        # assert c is not None
        if c is not None:
            shifter = get_shift(a, c)
        else:
            shifter = get_shift(a, b)

        res = m2_expr.ExprOp(op, a, shifter)
        cf_from_dst = m2_expr.ExprOp(op, a,
                                     (shifter - m2_expr.ExprInt(1, a.size)))
        cf_from_dst = cf_from_dst.msb() if left else cf_from_dst[:1]

        new_cf = cf_from_dst
        i1 = m2_expr.ExprInt(1, size=a.size)
        if c is not None:
            # There is a source for new bits
            isize = m2_expr.ExprInt(a.size, size=a.size)
            mask = m2_expr.ExprOp(op_inv, i1, (isize - shifter)) - i1

            # An overflow can occured, emulate the 'undefined behavior'
            # Overflow behavior if (shift / size % 2)
            base_cond_overflow = c if left else (
                c - m2_expr.ExprInt(1, size=c.size))
            cond_overflow = base_cond_overflow & m2_expr.ExprInt(
                a.size, c.size)
            if left:
                # Overflow occurs one round before right
                mask = m2_expr.ExprCond(cond_overflow, mask, ~mask)
            else:
                mask = m2_expr.ExprCond(cond_overflow, ~mask, mask)

            # Build res with dst and src
            res = ((m2_expr.ExprOp(op, a, shifter) & mask) |
                   (m2_expr.ExprOp(op_inv, b, (isize - shifter)) & ~mask))

            # Overflow case: cf come from src (bit number shifter % size)
            cf_from_src = m2_expr.ExprOp(
                op, b,
                (c.zeroExtend(b.size) & m2_expr.ExprInt(a.size - 1, b.size)) -
                i1)
            cf_from_src = cf_from_src.msb() if left else cf_from_src[:1]
            new_cf = m2_expr.ExprCond(cond_overflow, cf_from_src, cf_from_dst)

        # Overflow flag, only occured when shifter is equal to 1
        if custom_of is None:
            value_of = a.msb() ^ a[-2:-1] if left else b[:1] ^ a.msb()
        else:
            value_of = custom_of

        # Build basic blocks
        e_do = [
            m2_expr.ExprAff(regs.cf, new_cf),
            m2_expr.ExprAff(
                regs.of,
                m2_expr.ExprCond(shifter - i1,
                                 m2_expr.ExprInt(0, regs.of.size), value_of)),
            m2_expr.ExprAff(a, res),
        ]
        e_do += update_flag_znp(res)

        return (e_do, [])
Example #15
0
File: ir.py Project: acru3l/miasm
    def remove_jmp_blocks(self):
        """
        Remove irblock with only IRDst set, by linking it's parent destination to
        the block destination.
        """

        # Find candidates
        jmp_blocks = set()
        for block in self.blocks.itervalues():
            if len(block) != 1:
                continue
            assignblk = block[0]
            if len(assignblk) > 1:
                continue
            assert set(assignblk.keys()) == set([self.IRDst])
            if len(self.graph.successors(block.loc_key)) != 1:
                continue
            if not assignblk[self.IRDst].is_loc():
                continue
            dst = assignblk[self.IRDst].loc_key
            if dst == block.loc_key:
                # Infinite loop block
                continue
            jmp_blocks.add(block.loc_key)

        # Remove them, relink graph
        modified = False
        for loc_key in jmp_blocks:
            block = self.blocks[loc_key]
            dst_loc_key = block.dst
            parents = self.graph.predecessors(block.loc_key)
            for lbl in parents:
                parent = self.blocks.get(lbl, None)
                if parent is None:
                    continue
                dst = parent.dst
                if dst.is_id(block.loc_key):
                    dst = m2_expr.ExprLoc(dst_loc_key, dst.size)

                    self.graph.discard_edge(lbl, block.loc_key)
                    self.graph.discard_edge(block.loc_key, dst_loc_key)

                    self.graph.add_uniq_edge(lbl, dst_loc_key)
                    modified = True
                elif dst.is_cond():
                    src1, src2 = dst.src1, dst.src2
                    if src1.is_id(block.loc_key):
                        dst = m2_expr.ExprCond(dst.cond, m2_expr.ExprLoc(dst_loc_key, dst.size), dst.src2)
                        self.graph.discard_edge(lbl, block.loc_key)
                        self.graph.discard_edge(block.loc_key, dst_loc_key)
                        self.graph.add_uniq_edge(lbl, dst_loc_key)
                        modified = True
                    if src2.is_id(block.loc_key):
                        dst = m2_expr.ExprCond(dst.cond, dst.src1, m2_expr.ExprLoc(dst_loc_key, dst.size))
                        self.graph.discard_edge(lbl, block.loc_key)
                        self.graph.discard_edge(block.loc_key, dst_loc_key)
                        self.graph.add_uniq_edge(lbl, dst_loc_key)
                        modified = True
                    if dst.src1 == dst.src2:
                        dst = dst.src1
                else:
                    continue
                new_parent = parent.set_dst(dst)
                self.blocks[parent.loc_key] = new_parent

        # Remove unlinked useless nodes
        for loc_key in jmp_blocks:
            if (len(self.graph.predecessors(loc_key)) == 0 and
                len(self.graph.successors(loc_key)) == 0):
                self.graph.del_node(loc_key)
                del self.blocks[loc_key]
        return modified
Example #16
0
File: ir.py Project: zhencang/miasm
    def remove_jmp_blocks(self):
        """
        Remove irblock with only IRDst set, by linking it's parent destination to
        the block destination.
        """

        # Find candidates
        jmp_blocks = set()
        for block in self.blocks.itervalues():
            if len(block.irs) != 1:
                continue
            assignblk = block.irs[0]
            if len(assignblk) > 1:
                continue
            assert set(assignblk.keys()) == set([self.IRDst])
            if len(self.graph.successors(block.label)) != 1:
                continue
            if not expr_is_label(assignblk[self.IRDst]):
                continue
            jmp_blocks.add(block)

        # Remove them, relink graph
        modified = False
        for block in jmp_blocks:
            dst_label = block.dst.name
            parents = self.graph.predecessors(block.label)
            for lbl in parents:
                parent = self.blocks.get(lbl, None)
                if parent is None:
                    continue
                dst = parent.dst
                if dst.is_id(block.label):
                    dst = m2_expr.ExprId(dst_label, dst.size)

                    self.graph.discard_edge(lbl, block.label)
                    self.graph.discard_edge(block.label, dst_label)

                    self.graph.add_uniq_edge(lbl, dst_label)
                    modified = True
                elif dst.is_cond():
                    src1, src2 = dst.src1, dst.src2
                    if src1.is_id(block.label):
                        dst = m2_expr.ExprCond(
                            dst.cond, m2_expr.ExprId(dst_label, dst.size),
                            dst.src2)
                        self.graph.discard_edge(lbl, block.label)
                        self.graph.discard_edge(block.label, dst_label)
                        self.graph.add_uniq_edge(lbl, dst_label)
                        modified = True
                    if src2.is_id(block.label):
                        dst = m2_expr.ExprCond(
                            dst.cond, dst.src1,
                            m2_expr.ExprId(dst_label, dst.size))
                        self.graph.discard_edge(lbl, block.label)
                        self.graph.discard_edge(block.label, dst_label)
                        self.graph.add_uniq_edge(lbl, dst_label)
                        modified = True
                    if dst.src1 == dst.src2:
                        dst = src1
                else:
                    continue
                parent.dst = dst

        # Remove unlinked useless nodes
        for block in jmp_blocks:
            if (len(self.graph.predecessors(block.label)) == 0
                    and len(self.graph.successors(block.label)) == 0):
                self.graph.del_node(block.label)
        return modified
Example #17
0
def csneg(ir, instr, arg1, arg2, arg3, arg4):
    e = []
    cond_expr = cond2expr[arg4.name]
    e.append(m2_expr.ExprAff(arg1, m2_expr.ExprCond(cond_expr, arg2, -arg3)))
    return e, []