Esempio n. 1
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]
Esempio n. 2
0
def ins(ir, instr, a, b, c, d):
    e = []
    pos = int(c)
    l = int(d)

    my_slices = []
    if pos != 0:
        my_slices.append((a[:pos], 0, pos))
    if l != 0:
        my_slices.append((b[:l], pos, pos + l))
    if pos + l != 32:
        my_slices.append((a[pos + l:], pos + l, 32))
    r = m2_expr.ExprCompose(my_slices)
    e.append(m2_expr.ExprAssign(a, r))
    return e, []
Esempio n. 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
Esempio n. 4
0
 def dst2ExprAssign(self, dst):
     """Return an ExprAssign corresponding to @dst equation
     @dst: Expr instance"""
     return m2_expr.ExprAssign(dst, self[dst])
Esempio n. 5
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))
Esempio n. 6
0
 def to_constraint(self):
     return m2_expr.ExprAssign(self.expr,
                               m2_expr.ExprInt(0, self.expr.size))
Esempio n. 7
0
    def callback(self, jitter):

        # Check previous state

        # When it is possible, consider only elements modified in the last run
        # -> speed up to avoid browsing the whole memory
        to_consider = self.symb.modified_expr

        for symbol in to_consider:
            # Do not consider PC
            if symbol == self.ira.pc:
                continue

            # Read from ... @NN[... argX ...] ...
            symb_value = self.symb.eval_expr(symbol)
            to_replace = {}
            for expr in m2_expr.ExprAssign(symbol,
                                           symb_value).get_r(mem_read=True):
                if self.is_symbolic(expr):
                    if expr.is_mem():
                        # Consider each byte individually
                        # Case: @32[X] with only @8[X+1] to replace
                        addr_expr = expr.ptr
                        new_expr = []
                        consider = False
                        for offset in xrange(expr.size / 8):
                            sub_expr = m2_expr.ExprMem(
                                self.symb.expr_simp(
                                    addr_expr + m2_expr.ExprInt(
                                        offset, size=addr_expr.size)), 8)
                            if not self.is_pointer(sub_expr):
                                # Not a PTR, we have to replace with the real value
                                original_sub_expr = sub_expr.replace_expr(
                                    self.init_values)
                                new_expr.append(
                                    self.symb.eval_expr(original_sub_expr))
                                consider = True
                            else:
                                new_expr.append(sub_expr)

                        # Rebuild the corresponding expression
                        if consider:
                            assert len(new_expr) == expr.size / 8
                            to_replace[expr] = m2_expr.ExprCompose(*new_expr)

                    if expr not in self.memories_write:
                        # Do not consider memory already written during the run
                        self.memories_read.add(expr)

            # Write to @NN[... argX ...]
            # Must be after Read, case: @[X] = f(@[X])
            if self.is_symbolic(symbol):
                self.memories_write.add(symbol)

            # Replace with real value for non-pointer symbols
            if to_replace:
                symb_value = self.symb.expr_simp(
                    symb_value.replace_expr(to_replace))
                if isinstance(symbol, m2_expr.ExprMem):
                    # Replace only in ptr (case to_replace: @[arg] = 8, expr:
                    # @[arg] = @[arg])
                    symbol = m2_expr.ExprMem(
                        self.symb.expr_simp(
                            symbol.ptr.replace_expr(to_replace)), symbol.size)
                self.symb.apply_change(symbol, symb_value)

            # Check computed values against real ones
            # TODO idem memory
            if (isinstance(symbol, m2_expr.ExprId)
                    and isinstance(symb_value, m2_expr.ExprInt)):
                if hasattr(jitter.cpu, symbol.name):
                    value = m2_expr.ExprInt(getattr(jitter.cpu, symbol.name),
                                            symbol.size)
                    assert value == self.symb.symbols[symbol]

        cur_addr = jitter.pc
        self.logger.debug("Current address: %s", hex(cur_addr))
        if cur_addr == 0x1337BEEF or cur_addr == self.return_addr:
            # End reached
            if self.logger.isEnabledFor(logging.DEBUG):
                print "In:"
                for x in self.memories_read:
                    print "\t%s (%s)" % (
                        x,
                        self.c_handler.expr_to_c(x),
                    )
                print "Out:"
                for x in self.memories_write:
                    print "\t%s (%s)" % (
                        x,
                        self.c_handler.expr_to_c(x),
                    )
            return True

        # Update state
        self.symb.reset_modified()
        asm_block = self.mdis.dis_block(cur_addr)
        ircfg = self.symb_ir.new_ircfg()
        self.symb_ir.add_asmblock_to_ircfg(asm_block, ircfg)

        self.symb.run_at(ircfg, cur_addr)

        return True