Esempio n. 1
0
 def _op_divmod(self, args):
     if self.is_signed:
         quotient = (args[0].SDiv(claripy.SignExt(self._from_size - self._to_size, args[1])))
         remainder = (args[0].SMod(claripy.SignExt(self._from_size - self._to_size, args[1])))
         quotient_size = self._to_size
         remainder_size = self._to_size
         return claripy.Concat(
             claripy.Extract(remainder_size - 1, 0, remainder),
             claripy.Extract(quotient_size - 1, 0, quotient)
         )
     else:
         quotient = (args[0] // claripy.ZeroExt(self._from_size - self._to_size, args[1]))
         remainder = (args[0] % claripy.ZeroExt(self._from_size - self._to_size, args[1]))
         quotient_size = self._to_size
         remainder_size = self._to_size
         return claripy.Concat(
             claripy.Extract(remainder_size - 1, 0, remainder),
             claripy.Extract(quotient_size - 1, 0, quotient)
         )
Esempio n. 2
0
    def _handle_DivMod(self, expr):
        arg0, arg1 = expr.args
        r0 = self._expr(arg0)
        r1 = self._expr(arg1)

        result_size = expr.result_size(self.tyenv)
        if r0.data.concrete and r1.data.concrete:
            # constants
            try:
                signed = "U" in expr.op  # Iop_DivModU64to32 vs Iop_DivMod
                from_size = r0.data.size()
                to_size = r1.data.size()
                if signed:
                    quotient = (r0.data.SDiv(
                        claripy.SignExt(from_size - to_size, r1.data)))
                    remainder = (r0.data.SMod(
                        claripy.SignExt(from_size - to_size, r1.data)))
                    quotient_size = to_size
                    remainder_size = to_size
                    result = claripy.Concat(
                        claripy.Extract(remainder_size - 1, 0, remainder),
                        claripy.Extract(quotient_size - 1, 0, quotient))
                else:
                    quotient = (r0.data //
                                claripy.ZeroExt(from_size - to_size, r1.data))
                    remainder = (r0.data %
                                 claripy.ZeroExt(from_size - to_size, r1.data))
                    quotient_size = to_size
                    remainder_size = to_size
                    result = claripy.Concat(
                        claripy.Extract(remainder_size - 1, 0, remainder),
                        claripy.Extract(quotient_size - 1, 0, quotient))

                return RichR(result)
            except ZeroDivisionError:
                pass

        r = self.state.top(result_size)
        return RichR(r)
Esempio n. 3
0
 def extend_size(self, o):
     cur_size = o.size()
     if cur_size < self._output_size_bits:
         l.debug("Extending output of %s from %d to %d bits", self.name, cur_size, self._output_size_bits)
         ext_size = self._output_size_bits - cur_size
         if self._to_signed == 'S' or (self._from_signed == 'S' and self._to_signed is None):
             return claripy.SignExt(ext_size, o)
         else:
             return claripy.ZeroExt(ext_size, o)
     elif cur_size > self._output_size_bits:
         __import__('ipdb').set_trace()
         raise SimOperationError('output of %s is too big', self.name)
     else:
         return o
Esempio n. 4
0
File: irop.py Progetto: sumepr/angr
    def extend_size(self, o):
        cur_size = o.size()
        if cur_size == self._output_size_bits:
            return o
        if cur_size < self._output_size_bits:
            ext_size = self._output_size_bits - cur_size
            if self._to_signed == 'S' or (self._from_signed == 'S'
                                          and self._to_signed is None):
                return claripy.SignExt(ext_size, o)
            else:
                return claripy.ZeroExt(ext_size, o)

        # if cur_size > self._output_size_bits:
        # breakpoint here. it should never happen!
        __import__('ipdb').set_trace()
        raise SimOperationError('output of %s is too big' % self.name)
Esempio n. 5
0
    def _ail_handle_Div(self, expr):

        arg0, arg1 = expr.operands

        r0 = self._expr(arg0)
        r1 = self._expr(arg1)
        from_size = expr.bits
        to_size = r1.bits

        if expr.signed:
            remainder = r0.data.SMod(claripy.SignExt(from_size - to_size, r1.data))
        else:
            remainder = r0.data % claripy.ZeroExt(from_size - to_size, r1.data)

        return RichR(remainder,
                     # typevar=r0.typevar,  # FIXME: Handle typevars for Div
                     )
Esempio n. 6
0
    def extend_size(self, o):
        cur_size = o.size()
        target_size = self._output_size_bits
        if self._vector_count is not None:
            # phrased this awkward way to account for vectorized widening multiply
            target_size //= self._vector_count
        if cur_size == target_size:
            return o
        if cur_size < target_size:
            ext_size = target_size - cur_size
            if self._to_signed == 'S' or (self._to_signed is None and self._from_signed == 'S') or (self._to_signed is None and self._vector_signed == 'S'):
                return claripy.SignExt(ext_size, o)
            else:
                return claripy.ZeroExt(ext_size, o)

        # if cur_size > target_size:
        # it should never happen!
        raise SimOperationError('output of %s is too big' % self.name)
Esempio n. 7
0
    def _op_mapped(self, args):
        if self._from_size is not None:
            sized_args = [ ]
            for a in args:
                s = a.size()
                if s == self._from_size:
                    sized_args.append(a)
                elif s < self._from_size:
                    if self.is_signed:
                        sized_args.append(claripy.SignExt(self._from_size - s, a))
                    else:
                        sized_args.append(claripy.ZeroExt(self._from_size - s, a))
                elif s > self._from_size:
                    raise SimOperationError("operation %s received too large an argument" % self.name)
        else:
            sized_args = args

        if self._generic_name in operation_map:  # bitwise/arithmetic/shift operations
            o = operation_map[self._generic_name]
        else:
            raise SimOperationError("op_mapped called with invalid mapping, for %s" % self.name)

        return getattr(claripy.ast.BV, o)(*sized_args)
Esempio n. 8
0
 def _op_sign_extend(self, args):
     return claripy.SignExt(self._to_size - args[0].size(), args[0])
Esempio n. 9
0
    def _ail_handle_Convert(self, expr: Expr.Convert) -> PropValue:
        o_value = self._expr(expr.operand)

        if o_value is None or self.state.is_top(o_value.value):
            new_value = self.state.top(expr.to_bits)
        else:
            if expr.from_bits < expr.to_bits:
                if expr.is_signed:
                    new_value = claripy.SignExt(expr.to_bits - expr.from_bits, o_value.value)
                else:
                    new_value = claripy.ZeroExt(expr.to_bits - expr.from_bits, o_value.value)
            elif expr.from_bits > expr.to_bits:
                new_value = claripy.Extract(expr.to_bits - 1, 0, o_value.value)
            else:
                new_value = o_value.value

        o_expr = o_value.one_expr
        o_defat = o_value.one_defat
        if o_expr is not None:
            # easy cases
            if type(o_expr) is Expr.Convert:
                if expr.from_bits == o_expr.to_bits and expr.to_bits == o_expr.from_bits:
                    # eliminate the redundant Convert
                    new_expr = o_expr.operand
                else:
                    new_expr = Expr.Convert(expr.idx, o_expr.from_bits, expr.to_bits, expr.is_signed, o_expr.operand)
            elif type(o_expr) is Expr.Const:
                # do the conversion right away
                value = o_expr.value
                mask = (2 ** expr.to_bits) - 1
                value &= mask
                new_expr = Expr.Const(expr.idx, o_expr.variable, value, expr.to_bits)
            else:
                new_expr = Expr.Convert(expr.idx, expr.from_bits, expr.to_bits, expr.is_signed, o_expr, **expr.tags)

            if isinstance(new_expr, Expr.Convert) and not new_expr.is_signed \
                    and new_expr.to_bits > new_expr.from_bits and new_expr.from_bits % self.arch.byte_width == 0:
                # special handling for zero-extension: it simplifies the code if we explicitly model zeros
                new_size = new_expr.from_bits // self.arch.byte_width
                offset_and_details = {
                    0: Detail(new_size, new_expr.operand, o_defat),
                    new_size: Detail(
                        new_expr.size - new_size,
                        Expr.Const(expr.idx, None, 0, new_expr.to_bits - new_expr.from_bits),
                        self._codeloc()),
                }
            else:
                offset_and_details = {0: Detail(expr.size, new_expr, self._codeloc())}

            return PropValue(new_value, offset_and_details=offset_and_details)

        elif o_value.offset_and_details:
            # hard cases... we will keep certain labels and eliminate other labels
            start_offset = 0
            end_offset = expr.to_bits // self.arch.byte_width  # end_offset is exclusive
            offset_and_details = {}
            max_offset = max(o_value.offset_and_details.keys())
            for offset_, detail_ in o_value.offset_and_details.items():
                if offset_ < start_offset < offset_ + detail_.size:
                    # we start here
                    off = 0
                    siz = min(end_offset, offset_ + detail_.size) - start_offset
                    expr_ = PropValue.extract_ail_expression(
                        (start_offset - offset_) * self.arch.byte_width,
                        siz * self.arch.byte_width,
                        detail_.expr
                    )
                    offset_and_details[off] = Detail(siz, expr_, detail_.def_at)
                elif offset_ >= start_offset and offset_ + detail_.size <= end_offset:
                    # we include the whole thing
                    off = offset_ - start_offset
                    siz = detail_.size
                    if off == max_offset and off + siz < end_offset:
                        # extend the expr
                        expr_ = PropValue.extend_ail_expression(
                            (end_offset - (off + siz)) * self.arch.byte_width,
                            detail_.expr
                        )
                        siz = end_offset - off
                    else:
                        expr_ = detail_.expr
                    offset_and_details[off] = Detail(siz, expr_, detail_.def_at)
                elif offset_ < end_offset <= offset_ + detail_.size:
                    # we include all the way until end_offset
                    if offset_ < start_offset:
                        off = 0
                        siz = end_offset - start_offset
                    else:
                        off = offset_ - start_offset
                        siz = end_offset - offset_
                    expr_ = PropValue.extract_ail_expression(0, siz * self.arch.byte_width, detail_.expr)
                    offset_and_details[off] = Detail(siz, expr_, detail_.def_at)

            return PropValue(
                new_value,
                offset_and_details=offset_and_details
            )
        else:
            # it's empty... no expression is available for whatever reason
            return PropValue.from_value_and_details(new_value, expr.size, expr, self._codeloc())