예제 #1
0
 def get_filter_constraints(self, filter_opts):
     res = list()
     for opt in filter_opts:
         if opt["type"] == "limit_symbol":
             claripy_obj = self.symbols[opt["symbol_id"]].claripy_obj
             expr = claripy.And(claripy.SGE(claripy_obj, int(opt["min"])),
                                claripy.SLE(claripy_obj, int(opt["max"])))
             res.append(expr)
     return res
예제 #2
0
 def check_symbol_range(state, range_symbols):
     for sid in range_symbols:
         symbol, rmin, rmax = range_symbols[sid]
         if not state.solver.satisfiable(extra_constraints=[
             claripy.And(
                 claripy.SGE(symbol, rmin),
                 claripy.SLE(symbol, rmax)
             )
         ]):
             return False
     return True
예제 #3
0
    def claripy_ast_from_ail_condition(self, condition) -> claripy.ast.Base:

        # Unpack a condition all the way to the leaves
        if isinstance(condition, claripy.ast.Base):  # pylint:disable=isinstance-second-argument-not-valid-type
            return condition

        def _op_with_unified_size(op, conv, operand0, operand1):
            # ensure operand1 is of the same size as operand0
            if isinstance(operand1, ailment.Expr.Const):
                # amazing - we do the eazy thing here
                return op(conv(operand0), operand1.value)
            if operand1.bits == operand0.bits:
                return op(conv(operand0), conv(operand1))
            # extension is required
            assert operand1.bits < operand0.bits
            operand1 = ailment.Expr.Convert(None, operand1.bits, operand0.bits, False, operand1)
            return op(conv(operand0), conv(operand1))

        _mapping = {
            'LogicalAnd': lambda expr, conv: claripy.And(conv(expr.operands[0]), conv(expr.operands[1])),
            'LogicalOr': lambda expr, conv: claripy.Or(conv(expr.operands[0]), conv(expr.operands[1])),
            'CmpEQ': lambda expr, conv: conv(expr.operands[0]) == conv(expr.operands[1]),
            'CmpNE': lambda expr, conv: conv(expr.operands[0]) != conv(expr.operands[1]),
            'CmpLE': lambda expr, conv: conv(expr.operands[0]) <= conv(expr.operands[1]),
            'CmpLEs': lambda expr, conv: claripy.SLE(conv(expr.operands[0]), conv(expr.operands[1])),
            'CmpLT': lambda expr, conv: conv(expr.operands[0]) < conv(expr.operands[1]),
            'CmpLTs': lambda expr, conv: claripy.SLT(conv(expr.operands[0]), conv(expr.operands[1])),
            'CmpGE': lambda expr, conv: conv(expr.operands[0]) >= conv(expr.operands[1]),
            'CmpGEs': lambda expr, conv: claripy.SGE(conv(expr.operands[0]), conv(expr.operands[1])),
            'CmpGT': lambda expr, conv: conv(expr.operands[0]) > conv(expr.operands[1]),
            'CmpGTs': lambda expr, conv: claripy.SGT(conv(expr.operands[0]), conv(expr.operands[1])),
            'Add': lambda expr, conv: conv(expr.operands[0]) + conv(expr.operands[1]),
            'Sub': lambda expr, conv: conv(expr.operands[0]) - conv(expr.operands[1]),
            'Mul': lambda expr, conv: conv(expr.operands[0]) * conv(expr.operands[1]),
            'Not': lambda expr, conv: claripy.Not(conv(expr.operand)),
            'Xor': lambda expr, conv: conv(expr.operands[0]) ^ conv(expr.operands[1]),
            'And': lambda expr, conv: conv(expr.operands[0]) & conv(expr.operands[1]),
            'Or': lambda expr, conv: conv(expr.operands[0]) | conv(expr.operands[1]),
            'Shr': lambda expr, conv: _op_with_unified_size(claripy.LShR, conv, expr.operands[0], expr.operands[1]),
            'Shl': lambda expr, conv: _op_with_unified_size(operator.lshift, conv, expr.operands[0], expr.operands[1]),
            'Sar': lambda expr, conv: _op_with_unified_size(operator.rshift, conv, expr.operands[0], expr.operands[1]),
        }

        if isinstance(condition, (ailment.Expr.Load, ailment.Expr.DirtyExpression, ailment.Expr.BasePointerOffset,
                                  ailment.Expr.ITE, ailment.Stmt.Call)):
            var = claripy.BVS('ailexpr_%s' % repr(condition), condition.bits, explicit_name=True)
            self._condition_mapping[var.args[0]] = condition
            return var
        elif isinstance(condition, ailment.Expr.Register):
            var = claripy.BVS('ailexpr_%s-%d' % (repr(condition), condition.idx), condition.bits, explicit_name=True)
            self._condition_mapping[var.args[0]] = condition
            return var
        elif isinstance(condition, ailment.Expr.Convert):
            # convert is special. if it generates a 1-bit variable, it should be treated as a BVS
            if condition.to_bits == 1:
                var_ = self.claripy_ast_from_ail_condition(condition.operands[0])
                name = 'ailcond_Conv(%d->%d, %s)' % (condition.from_bits, condition.to_bits, repr(var_))
                var = claripy.BoolS(name, explicit_name=True)
            else:
                var_ = self.claripy_ast_from_ail_condition(condition.operands[0])
                name = 'ailexpr_Conv(%d->%d, %s)' % (condition.from_bits, condition.to_bits, repr(var_))
                var = claripy.BVS(name, condition.to_bits, explicit_name=True)
            self._condition_mapping[var.args[0]] = condition
            return var
        elif isinstance(condition, ailment.Expr.Const):
            var = claripy.BVV(condition.value, condition.bits)
            return var
        elif isinstance(condition, ailment.Expr.Tmp):
            l.warning("Left-over ailment.Tmp variable %s.", condition)
            if condition.bits == 1:
                var = claripy.BoolV('ailtmp_%d' % condition.tmp_idx)
            else:
                var = claripy.BVS('ailtmp_%d' % condition.tmp_idx, condition.bits, explicit_name=True)
            self._condition_mapping[var.args[0]] = condition
            return var

        lambda_expr = _mapping.get(condition.verbose_op, None)
        if lambda_expr is None:
            raise NotImplementedError("Unsupported AIL expression operation %s. Consider implementing." % condition.op)
        r = lambda_expr(condition, self.claripy_ast_from_ail_condition)
        if r is NotImplemented:
            r = claripy.BVS("ailexpr_%r" % condition, condition.bits, explicit_name=True)
            self._condition_mapping[r.args[0]] = condition
        else:
            # don't lose tags
            r = r.annotate(TagsAnnotation(**condition.tags))
        return r
예제 #4
0
파일: solve.py 프로젝트: zu3st/angr-doc
 def run(self, _, length):  # pylint: disable=W0221
     bvs = claripy.BVS("Random.nextInt", 32)
     cs = claripy.And(claripy.SGE(bvs, 0), claripy.SLE(bvs, length))
     self.state.add_constraints(cs)
     return bvs
예제 #5
0
파일: analyzer.py 프로젝트: Deeby/pakala
    def check_state(self, state, path=None):
        """Check a reachable state for bugs"""
        logger.debug("Check state: %s", state)
        logger.debug("Constraints: %s", state.solver.constraints)

        solver = state.solver.branch()

        if path is None:
            path = [state]
            # Static read were we never wrote, but we know the key is not symbolic.
            # So we go and fetch it.
            for key, value in state.storage_read.items():
                constraint = state.storage_read[key] == self._read_storage(
                    state, key)
                solver.add(constraint)
                logger.debug("Add storage constraint: %s", constraint)

        for s in path:
            solver.add(list(s.env.extra_constraints()))
            solver.add([
                s.env.caller == utils.DEFAULT_CALLER,
                s.env.origin == utils.DEFAULT_CALLER,
            ])

        # Calls
        total_sent = sum(s.env.value for s in path)
        sent_constraints = [s.env.value < self.max_wei_to_send for s in path]

        total_received_by_me = utils.bvv(0)
        total_received = utils.bvv(0)

        for call in state.calls:
            # TODO: Improve delegatecall support! And make it clearer it's
            # delegatecall, not just based on the length.
            assert 6 <= len(call) <= 7
            value, to, gas = call[-3:]  # pylint: disable=unused-variable,invalid-name

            delegatecall = len(call) == 6

            if delegatecall:
                if solver.satisfiable(
                        extra_constraints=[to[159:0] == self.caller[159:0]]):
                    logger.info("Found delegatecall bug.")
                    solver.add(to[159:0] == self.caller[159:0])
                    return solver
            else:
                total_received_by_me += claripy.If(
                    to[159:0] == self.caller[159:0], value, utils.bvv(0))
                total_received += value
                solver.add(value <= total_sent + path[0].env.balance)

        final_balance = path[0].env.balance + total_sent - total_received

        # Suicide
        if state.selfdestruct_to is not None:
            constraints = [
                final_balance >= self.min_wei_to_receive,
                state.selfdestruct_to[159:0] == self.caller[159:0],
            ]
            logger.debug("Check for selfdestruct bug with constraints %s",
                         constraints)
            if solver.satisfiable(extra_constraints=constraints):
                logger.info("Found selfdestruct bug.")
                solver.add(constraints)
                return solver

        if total_received_by_me is utils.bvv(0):
            return

        logger.debug("Found calls back to caller: %s", total_received_by_me)

        solver.add(sent_constraints)
        solver.add([
            claripy.SGE(final_balance, 0),
            total_received_by_me > total_sent,  # I get more than what I sent?
            total_received_by_me > self.min_wei_to_receive,
        ])

        if solver.satisfiable():
            logger.info("Found call bug.")
            return solver
예제 #6
0
    def constrain_variables(self, func, solver, stack):
        self.offsets = self.funcdata[func.addr]
        self.bounds_marked = set()
        self.stack = stack
        self.solver = solver

        # do some sanity checking first
        top = min(self.offsets)
        for addr in stack.addr_list:
            if addr < top:
                raise Exception("Provided vars miss an access (off the top!)")
            base_addr = addr
            while base_addr not in self.offsets:
                base_addr -= 1
            this_offset = addr - base_addr
            if this_offset >= self.offsets[base_addr][0]:
                raise Exception(
                    "Provided vars miss an access (between the cracks!)")

        i = 0
        while i < len(stack.addr_list):
            addr = stack.addr_list[i]
            if addr in self.offsets:
                if i != 0 and self.offsets[stack.addr_list[
                        i - 1]][0] + stack.addr_list[i - 1] > addr:
                    raise Exception("Provided vars have an overlap!")
                i += 1
                continue
            stack.merge_up(i)

        # standard stuff
        stack.alloc_op.apply_constraints(solver)
        solver.add(stack.alloc_op.symval == -stack.sym_size)
        for op in stack.dealloc_ops:
            op.apply_constraints(solver)
            solver.add(op.symval == 0)

        solver.add(stack.sym_size % stack.arch.bytes == 0)
        solver.add(claripy.SGE(stack.sym_size, stack.conc_size))
        stack.unsafe_constraints.append(
            claripy.SGT(stack.sym_size, stack.conc_size))
        stack.unsafe_constraints.append(
            claripy.SGE(stack.sym_size, stack.conc_size * 2))
        stack.unsafe_constraints.append(
            claripy.SLT(stack.sym_size, stack.conc_size * 3))

        # loop through variables, add the important constraints!
        i = 0
        while i < len(stack.addr_list):
            addr = stack.addr_list[i]
            var = stack.variables[addr]
            var.size = self.offsets[addr][0]
            fix = self.offsets[addr][1]
            if fix == 'TOP':
                var.special_top = True
            elif fix == 'BOTTOM':
                var.special_bottom = True

            align = self.offsets[addr][2]
            if align != 1:
                solver.add(var.sym_addr % align == 0)
            var.sym_link(
                solver,
                stack)  # this hooks up the constrains to actual immediates
            # also the top/bottom fixing happens in there

            if i != 0:
                prev_var = stack.variables[stack.addr_list[i - 1]]
                self.mark_boundaries(prev_var, var)
            if i != len(stack.addr_list) - 1:
                next_var = stack.variables[stack.addr_list[i + 1]]
                self.mark_boundaries(var, next_var)

                # ew. ew ew ew ew ew ew!!!
                diff = next_var.conc_addr - var.conc_addr
                solver.add(claripy.SLT(var.sym_addr, var.sym_addr + diff))
            if i == 0:
                solver.add(claripy.SLE(-stack.sym_size, var.sym_addr))

            i += 1
예제 #7
0
    def claripy_ast_from_ail_condition(self, condition):

        # Unpack a condition all the way to the leaves
        if isinstance(condition, claripy.ast.Base):
            return condition

        _mapping = {
            'LogicalAnd':
            lambda expr, conv: claripy.And(conv(expr.operands[0]),
                                           conv(expr.operands[1])),
            'LogicalOr':
            lambda expr, conv: claripy.Or(conv(expr.operands[0]),
                                          conv(expr.operands[1])),
            'CmpEQ':
            lambda expr, conv: conv(expr.operands[0]) == conv(expr.operands[1]
                                                              ),
            'CmpNE':
            lambda expr, conv: conv(expr.operands[0]) != conv(expr.operands[1]
                                                              ),
            'CmpLE':
            lambda expr, conv: conv(expr.operands[0]) <= conv(expr.operands[1]
                                                              ),
            'CmpLEs':
            lambda expr, conv: claripy.SLE(conv(expr.operands[0]),
                                           conv(expr.operands[1])),
            'CmpLT':
            lambda expr, conv: conv(expr.operands[0]) < conv(expr.operands[1]),
            'CmpLTs':
            lambda expr, conv: claripy.SLT(conv(expr.operands[0]),
                                           conv(expr.operands[1])),
            'CmpGE':
            lambda expr, conv: conv(expr.operands[0]) >= conv(expr.operands[1]
                                                              ),
            'CmpGEs':
            lambda expr, conv: claripy.SGE(conv(expr.operands[0]),
                                           conv(expr.operands[1])),
            'CmpGT':
            lambda expr, conv: conv(expr.operands[0]) > conv(expr.operands[1]),
            'CmpGTs':
            lambda expr, conv: claripy.SGT(conv(expr.operands[0]),
                                           conv(expr.operands[1])),
            'Add':
            lambda expr, conv: conv(expr.operands[0]) + conv(expr.operands[1]),
            'Sub':
            lambda expr, conv: conv(expr.operands[0]) - conv(expr.operands[1]),
            'Not':
            lambda expr, conv: claripy.Not(conv(expr.operand)),
            'Xor':
            lambda expr, conv: conv(expr.operands[0]) ^ conv(expr.operands[1]),
            'And':
            lambda expr, conv: conv(expr.operands[0]) & conv(expr.operands[1]),
            'Or':
            lambda expr, conv: conv(expr.operands[0]) | conv(expr.operands[1]),
            'Shr':
            lambda expr, conv: claripy.LShR(conv(expr.operands[0]), expr.
                                            operands[1].value)
        }

        if isinstance(condition,
                      (ailment.Expr.Load, ailment.Expr.DirtyExpression,
                       ailment.Expr.BasePointerOffset)):
            var = claripy.BVS('ailexpr_%s' % repr(condition),
                              condition.bits,
                              explicit_name=True)
            self._condition_mapping[var] = condition
            return var
        elif isinstance(condition, ailment.Expr.Register):
            var = claripy.BVS('ailexpr_%s-%d' %
                              (repr(condition), condition.idx),
                              condition.bits,
                              explicit_name=True)
            self._condition_mapping[var] = condition
            return var
        elif isinstance(condition, ailment.Expr.Convert):
            # convert is special. if it generates a 1-bit variable, it should be treated as a BVS
            if condition.to_bits == 1:
                var_ = self.claripy_ast_from_ail_condition(
                    condition.operands[0])
                name = 'ailcond_Conv(%d->%d, %s)' % (
                    condition.from_bits, condition.to_bits, repr(var_))
                var = claripy.BoolS(name, explicit_name=True)
            else:
                var_ = self.claripy_ast_from_ail_condition(
                    condition.operands[0])
                name = 'ailexpr_Conv(%d->%d, %s)' % (
                    condition.from_bits, condition.to_bits, repr(var_))
                var = claripy.BVS(name, condition.to_bits, explicit_name=True)
            self._condition_mapping[var] = condition
            return var
        elif isinstance(condition, ailment.Expr.Const):
            var = claripy.BVV(condition.value, condition.bits)
            return var
        elif isinstance(condition, ailment.Expr.Tmp):
            l.warning("Left-over ailment.Tmp variable %s.", condition)
            if condition.bits == 1:
                var = claripy.BoolV('ailtmp_%d' % condition.tmp_idx)
            else:
                var = claripy.BVS('ailtmp_%d' % condition.tmp_idx,
                                  condition.bits)
            self._condition_mapping[var] = condition
            return var

        lambda_expr = _mapping.get(condition.verbose_op, None)
        if lambda_expr is None:
            raise NotImplementedError(
                "Unsupported AIL expression operation %s. Consider implementing."
                % condition.op)
        r = lambda_expr(condition, self.claripy_ast_from_ail_condition)
        if r is NotImplemented:
            r = claripy.BVS("ailexpr_%r" % condition,
                            condition.bits,
                            explicit_name=True)
            self._condition_mapping[r] = condition
        return r
예제 #8
0
import settings
import claripy
settings.WARNING_ADDRESS = 0x1fcb0
settings.VERBOSE = True
settings.DEBUG = True
settings.TARGET_BINARY = "/home/stefan/Documents/Graduation/RISC-V-toolchain/riscv/Programs/Poly1305_onetimeauth/Radix2.26_woMultiplier/program.elf"
settings.TARGET_ADDRESS = 0x20011dfc
settings.A = claripy.BVS('A', 32)
settings.params = [settings.A]
settings.secret = settings.A
settings.constraints = [claripy.SLT(settings.A, 5), claripy.SGE(settings.A, 1)]
from pluginTime import TIME_STRATEGY_SHORTEST
settings.TIME_STRATEGY = TIME_STRATEGY_SHORTEST


def stateInit(startState):
    return True


settings.stateInit = stateInit
import tool