Exemple #1
0
def slt(arg1, arg2, arg3):
    """If @arg2 is less than @arg3 (signed), @arg1 is set to one. It gets zero
    otherwise."""
    arg1 = m2_expr.ExprCond(
        m2_expr.ExprOp(m2_expr.TOK_INF_SIGNED, arg2, arg3),
        m2_expr.ExprInt(1, arg1.size),
        m2_expr.ExprInt(0, arg1.size)
    )
def expr_simp_equal(expr_simp, e):
    """(x - y)?(0:1) == (x == y)"""

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

    return ExprOp_equal(r[jok1], expr_simp(-r[jok2]))
Exemple #3
0
    def get_ir(self, instr):
        args = instr.args
        instr_ir, extra_ir = get_mnemo_expr(self, instr, *args)

        fixed_regs = {
            self.pc: m2_expr.ExprInt(instr.offset + 4, 32),
            ZERO: m2_expr.ExprInt(0, 32)
        }

        instr_ir = [m2_expr.ExprAssign(expr.dst, expr.src.replace_expr(fixed_regs))
                    for expr in instr_ir]

        new_extra_ir = [irblock.modify_exprs(mod_src=lambda expr: expr.replace_expr(fixed_regs))
                        for irblock in extra_ir]
        return instr_ir, new_extra_ir
Exemple #4
0
    def block2assignblks(self, block):
        irblocks_list = super(mipsCGen, self).block2assignblks(block)
        for irblocks in irblocks_list:
            for blk_idx, irblock in enumerate(irblocks):
                has_breakflow = any(assignblock.instr.breakflow()
                                    for assignblock in irblock)
                if not has_breakflow:
                    continue

                irs = []
                for assignblock in irblock:
                    if self.ir_arch.pc not in assignblock:
                        irs.append(AssignBlock(assignments, assignblock.instr))
                        continue
                    assignments = dict(assignblock)
                    # Add internal branch destination
                    assignments[self.delay_slot_dst] = assignblock[
                        self.ir_arch.pc]
                    assignments[self.delay_slot_set] = m2_expr.ExprInt(1, 32)
                    # Replace IRDst with next instruction
                    dst_loc_key = self.ir_arch.get_next_instr(
                        assignblock.instr)
                    assignments[self.ir_arch.IRDst] = m2_expr.ExprLoc(
                        dst_loc_key, 32)
                    irs.append(AssignBlock(assignments, assignblock.instr))
                irblocks[blk_idx] = IRBlock(irblock.loc_key, irs)

        return irblocks_list
Exemple #5
0
    def elements(self):
        value = self.cbReg.value
        if value in self.stk_args:
            line = self.ircfg.blocks[self.loc_key][self.line_nb].instr
            arg_num = self.stk_args[value]
            stk_high = m2_expr.ExprInt(idc.get_spd(line.offset), ir_arch.sp.size)
            stk_off = m2_expr.ExprInt(self.ira.sp.size // 8 * arg_num, ir_arch.sp.size)
            element =  m2_expr.ExprMem(self.mn.regs.regs_init[ir_arch.sp] + stk_high + stk_off, self.ira.sp.size)
            element = expr_simp(element)
            # Force stack unaliasing
            self.stk_unalias_force = True
        elif value:
            element = self.ira.arch.regs.all_regs_ids_byname.get(value, None)

        else:
            raise ValueError("Unknown element '%s'!" % value)
        return set([element])
Exemple #6
0
def bltzl(arg1, arg2):
    """Branches on @arg2 if the register @arg1 is less than zero"""
    dst_o = arg2 if m2_expr.ExprOp(
        m2_expr.TOK_INF_SIGNED, arg1, m2_expr.ExprInt(
            0, arg1.size)) else m2_expr.ExprLoc(
                ir.get_next_delay_loc_key(instr), ir.IRDst.size)
    PC = dst_o
    ir.IRDst = dst_o
Exemple #7
0
def bgtzl(arg1, arg2):
    """Branches on @arg2 if the register @arg1 is greater than zero"""
    cond = m2_expr.ExprOp(m2_expr.TOK_INF_EQUAL_SIGNED, arg1,
                          m2_expr.ExprInt(0, arg1.size))
    dst_o = m2_expr.ExprLoc(ir.get_next_delay_loc_key(instr),
                            ir.IRDst.size) if cond else arg2
    PC = dst_o
    ir.IRDst = dst_o
Exemple #8
0
def blezl(arg1, arg2):
    """Branches on @arg2 if the register @arg1 is less than or equal to zero"""
    cond = m2_expr.ExprOp(m2_expr.TOK_INF_EQUAL_SIGNED, arg1,
                          m2_expr.ExprInt(0, arg1.size))
    dst_o = arg2 if cond else m2_expr.ExprLoc(ir.get_next_delay_loc_key(instr),
                                              ir.IRDst.size)
    PC = dst_o
    ir.IRDst = dst_o
Exemple #9
0
 def _simp_handle_segm(self, e_s, expr):
     """Handle 'segm' operation"""
     if not is_op_segm(expr):
         return expr
     if not expr.args[0].is_int():
         return expr
     segm_nb = int(expr.args[0])
     segmaddr = self.cpu.get_segm_base(segm_nb)
     return e_s(m2_expr.ExprInt(segmaddr, expr.size) + expr.args[1])
Exemple #10
0
def bgezl(arg1, arg2):
    """Branches on @arg2 if the quantities of register @arg1 is greater than or
    equal to zero"""
    dst = m2_expr.ExprLoc(ir.get_next_delay_loc_key(instr),
                          ir.IRDst.size) if m2_expr.ExprOp(
                              m2_expr.TOK_INF_SIGNED, arg1,
                              m2_expr.ExprInt(0, arg1.size)) else arg2
    PC = dst
    ir.IRDst = dst
Exemple #11
0
    def resolve_args_with_symbols(self, symbols=None):
        if symbols is None:
            symbols = LocationDB()
        args_out = []
        for expr in self.args:
            # try to resolve symbols using symbols (0 for default value)
            loc_keys = m2_expr.get_expr_locs(expr)
            fixed_expr = {}
            for exprloc in loc_keys:
                loc_key = exprloc.loc_key
                names = symbols.get_location_names(loc_key)
                # special symbols
                if b'$' in names:
                    fixed_expr[exprloc] = self.get_asm_offset(exprloc)
                    continue
                if b'_' in names:
                    fixed_expr[exprloc] = self.get_asm_next_offset(exprloc)
                    continue
                arg_int = symbols.get_location_offset(loc_key)
                if arg_int is not None:
                    fixed_expr[exprloc] = m2_expr.ExprInt(
                        arg_int, exprloc.size)
                    continue
                if not names:
                    raise ValueError('Unresolved symbol: %r' % exprloc)

                offset = symbols.get_location_offset(loc_key)
                if offset is None:
                    raise ValueError(
                        'The offset of loc_key "%s" cannot be determined' %
                        names)
                else:
                    # Fix symbol with its offset
                    size = exprloc.size
                    if size is None:
                        default_size = self.get_symbol_size(exprloc, symbols)
                        size = default_size
                    value = m2_expr.ExprInt(offset, size)
                fixed_expr[exprloc] = value

            expr = expr.replace_expr(fixed_expr)
            expr = expr_simp(expr)
            args_out.append(expr)
        return args_out
Exemple #12
0
    def update_engine_from_cpu(self):
        """Updates CPU values according to @cpu instance"""

        for symbol in self.symbols:
            if isinstance(symbol, m2_expr.ExprId):
                if hasattr(self.cpu, symbol.name):
                    value = m2_expr.ExprInt(getattr(self.cpu, symbol.name),
                                            symbol.size)
                    self.symbols.symbols_id[symbol] = value
            else:
                raise NotImplementedError("Type not handled: %s" % symbol)
Exemple #13
0
    def _simp_handle_x86_cpuid(self, e_s, expr):
        """From miasm/jitter/op_semantics.h: x86_cpuid"""
        if expr.op != "x86_cpuid":
            return expr

        if any(not arg.is_int() for arg in expr.args):
            return expr
        a, reg_num = (int(arg) for arg in expr.args)

        # Not found error is keeped on purpose
        return m2_expr.ExprInt(self.x86_cpuid[a][reg_num], expr.size)
Exemple #14
0
    def gen_finalize(self, block):
        """
        Generate the C code for the final block instruction
        """

        loc_key = self.get_block_post_label(block)
        offset = self.ir_arch.loc_db.get_location_offset(loc_key)
        out = (self.CODE_RETURN_NO_EXCEPTION %
               (loc_key, self.C_PC, m2_expr.ExprId('branch_dst_irdst', 32),
                m2_expr.ExprId('branch_dst_irdst', 32),
                self.id_to_c(m2_expr.ExprInt(offset, 32)))).split('\n')
        return out
Exemple #15
0
    def mem_read(self, expr_mem):
        """Memory read wrapper for symbolic execution
        @expr_mem: ExprMem"""

        addr = expr_mem.ptr
        if not addr.is_int():
            return super(EmulatedSymbExec, self).mem_read(expr_mem)
        addr = int(addr)
        size = expr_mem.size // 8
        value = self.vm.get_mem(addr, size)
        if self.vm.is_little_endian():
            value = value[::-1]
        self.vm.add_mem_read(addr, size)

        return m2_expr.ExprInt(int(encode_hex(value), 16), expr_mem.size)
Exemple #16
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
Exemple #17
0
    def eval_updt_irblock(self, irb, step=False):
        """
        Symbolic execution of the @irb on the current state
        @irb: irblock instance
        @step: display intermediate steps
        """

        offset2cmt = {}
        for index, assignblk in enumerate(irb):
            if set(assignblk) == set([self.lifter.IRDst, self.lifter.pc]):
                # Don't display on jxx
                continue
            instr = assignblk.instr
            tmp_r = assignblk.get_r()
            tmp_w = assignblk.get_w()

            todo = set()

            # Replace PC with value to match IR args
            pc_fixed = {
                self.lifter.pc:
                m2_expr.ExprInt(instr.offset + instr.l, self.lifter.pc.size)
            }
            inputs = tmp_r
            inputs.update(arg for arg in tmp_w if arg.is_mem())
            for arg in inputs:
                arg = expr_simp(arg.replace_expr(pc_fixed))
                if arg in tmp_w and not arg.is_mem():
                    continue
                todo.add(arg)

            for expr in todo:
                if expr.is_int():
                    continue
                for c_str, c_type in self.chandler.expr_to_c_and_types(
                        expr, self.symbols):
                    expr = self.cst_propag_link.get((irb.loc_key, index),
                                                    {}).get(expr, expr)
                    offset2cmt.setdefault(instr.offset, set()).add(
                        "\n%s: %s\n%s" % (expr, c_str, c_type))
            self.eval_updt_assignblk(assignblk)
        for offset, value in viewitems(offset2cmt):
            idc.set_cmt(offset, '\n'.join(value), 0)
            print("%x\n" % offset, '\n'.join(value))

        return self.eval_expr(self.lifter.IRDst)
Exemple #18
0
def tne(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(ir.loc_db, loc_except, [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]
Exemple #19
0
def merge_sliceto_slice(expr):
    """
    Apply basic factorisation on ExprCompose sub components
    @expr: ExprCompose
    """

    out_args = []
    last_index = 0
    for index, arg in expr.iter_args():
        # Init
        if len(out_args) == 0:
            out_args.append(arg)
            continue

        last_value = out_args[-1]
        # Consecutive

        if last_index + last_value.size == index:
            # Merge consecutive integers
            if (isinstance(arg, m2_expr.ExprInt)
                    and isinstance(last_value, m2_expr.ExprInt)):
                new_size = last_value.size + arg.size
                value = int(arg) << last_value.size
                value |= int(last_value)
                out_args[-1] = m2_expr.ExprInt(value, size=new_size)
                continue

            # Merge consecuvite slice
            elif (isinstance(arg, m2_expr.ExprSlice)
                  and isinstance(last_value, m2_expr.ExprSlice)):
                value = arg.arg
                if (last_value.arg == value and last_value.stop == arg.start):
                    out_args[-1] = value[last_value.start:arg.stop]
                    continue

        # Unmergeable
        last_index = index
        out_args.append(arg)

    return out_args
Exemple #20
0
 def number(cls, size=32):
     """Return a random number
     @size: (optional) number max bits
     """
     num = random.randint(0, cls.number_max % (2**size))
     return m2_expr.ExprInt(num, size)
Exemple #21
0
 def get_asm_offset(self, expr):
     return m2_expr.ExprInt(self.offset, expr.size)
Exemple #22
0
 def get_asm_next_offset(self, expr):
     return m2_expr.ExprInt(self.offset+self.l, expr.size)
Exemple #23
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', 32)
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)))
Exemple #24
0
 def gen_pc_update(self, assignments, instr):
     offset = m2_expr.ExprInt(instr.offset, self.pc.size)
     assignments.append(AssignBlock({self.pc: offset}, instr))
Exemple #25
0
class imm64_noarg(object):
    int2expr = lambda self, x: m2_expr.ExprInt(x, 64)
Exemple #26
0
 def reset_regs(self):
     """Set registers value to 0. Ignore register aliases"""
     for reg in self.lifter.arch.regs.all_regs_ids_no_alias:
         self.symbols.symbols_id[reg] = m2_expr.ExprInt(0, size=reg.size)
Exemple #27
0
 def int2expr(self, v):
     if (v & ~self.intmask) != 0:
         return None
     return m2_expr.ExprInt(v, self.intsize)
Exemple #28
0
 def to_constraint(self):
     return m2_expr.ExprAssign(self.expr,
                               m2_expr.ExprInt(0, self.expr.size))
Exemple #29
0
def ast_int2expr(a):
    return m2_expr.ExprInt(a, 32)
Exemple #30
0
 def to_constraint(self):
     cst1, cst2 = m2_expr.ExprInt(0, 1), m2_expr.ExprInt(1, 1)
     return m2_expr.ExprAssign(cst1,
                               m2_expr.ExprCond(self.expr, cst1, cst2))