Exemplo n.º 1
0
    def sym_xoroshiro128plusadvance(self, sym_s0, sym_s1):
        sym_s1 ^= sym_s0
        sym_s0 = z3.RotateLeft(sym_s0, 24) ^ sym_s1 ^ (
            (sym_s1 << 16) & 0xFFFFFFFFFFFFFFFF)
        sym_s1 = z3.RotateLeft(sym_s1, 37)

        return sym_s0, sym_s1
Exemplo n.º 2
0
def sym_xoroshiro128plusadvance(sym_s0, sym_s1):
    s0 = sym_s0
    s1 = sym_s1

    s1 ^= s0
    sym_s0 = z3.RotateLeft(s0, 24) ^ s1 ^ (s1 << 16)
    sym_s1 = z3.RotateLeft(s1, 37)

    return sym_s0, sym_s1
Exemplo n.º 3
0
def sym_xoroshiro128plus(sym_s0, sym_s1):
    sym_r = (sym_s0 + sym_s1) & 0xFFFFFFFF

    sym_s1 ^= sym_s0
    sym_s0 = z3.RotateLeft(sym_s0, 24) ^ sym_s1 ^ (
        (sym_s1 << 16) & 0xFFFFFFFFFFFFFFFF)
    sym_s1 = z3.RotateLeft(sym_s1, 37)

    return sym_s0, sym_s1, sym_r
Exemplo n.º 4
0
 def RotateLeft(self, other):
     if isinstance(other, int):
         other = BVV(other, self.size)
     else:
         assert isinstance(other, BV)
         assert self.size == other.size
     return BVExpr(self.size, z3.RotateLeft(self.z3obj, other.z3obj), self.interval.RotateLeft(other.interval))
Exemplo n.º 5
0
    def from_ExprOp(self, expr):
        args = map(self.from_expr, expr.args)
        res = args[0]

        if len(args) > 1:
            for arg in args[1:]:
                if expr.op in self.trivial_ops:
                    res = eval("res %s arg" % expr.op)
                elif expr.op == ">>":
                    res = z3.LShR(res, arg)
                elif expr.op == "a>>":
                    res = res >> arg
                elif expr.op == "<<<":
                    res = z3.RotateLeft(res, arg)
                elif expr.op == ">>>":
                    res = z3.RotateRight(res, arg)
                elif expr.op == "idiv":
                    res = self._idivC(res, arg)
                elif expr.op == "udiv":
                    res = z3.UDiv(res, arg)
                elif expr.op == "imod":
                    res = res - (arg * (self._idivC(res, arg)))
                elif expr.op == "umod":
                    res = z3.URem(res, arg)
                else:
                    raise NotImplementedError("Unsupported OP yet: %s" %
                                              expr.op)
        elif expr.op == 'parity':
            arg = z3.Extract(7, 0, res)
            res = z3.BitVecVal(1, 1)
            for i in xrange(8):
                res = res ^ z3.Extract(i, i, arg)
        elif expr.op == '-':
            res = -res
        elif expr.op == "cnttrailzeros":
            size = expr.size
            src = res
            res = z3.If(src == 0, size, src)
            for i in xrange(size - 1, -1, -1):
                res = z3.If((src & (1 << i)) != 0, i, res)
        elif expr.op == "cntleadzeros":
            size = expr.size
            src = res
            res = z3.If(src == 0, size, src)
            for i in xrange(size, 0, -1):
                index = -i % size
                out = size - (index + 1)
                res = z3.If((src & (1 << index)) != 0, out, res)
        elif expr.op.startswith("zeroExt"):
            arg, = expr.args
            res = z3.ZeroExt(expr.size - arg.size, self.from_expr(arg))
        elif expr.op.startswith("signExt"):
            arg, = expr.args
            res = z3.SignExt(expr.size - arg.size, self.from_expr(arg))
        else:
            raise NotImplementedError("Unsupported OP yet: %s" % expr.op)

        return res
Exemplo n.º 6
0
 def RotateLeft(self, other):
     if isinstance(other, int):
         other = BVV(other, self.size)
     else:
         assert isinstance(other, BV)
         assert self.size == other.size
     if isinstance(other, BVV):
         other_norm = other.value % self.size
         new = (((self.value << other_norm) & self._mask) |
                ((self.value >> ((self.size - other_norm) & self._mask)) & self._mask))
         return BVV(new & self._mask, self.size)
     return BVExpr(self.size, z3.RotateLeft(self.z3obj, other.z3obj), self.interval.RotateLeft(other.interval))
Exemplo n.º 7
0
    def from_ExprOp(self, expr):
        args = map(self.from_expr, expr.args)
        res = args[0]

        if len(args) > 1:
            for arg in args[1:]:
                if expr.op in self.trivial_ops:
                    res = eval("res %s arg" % expr.op)
                elif expr.op == ">>":
                    res = z3.LShR(res, arg)
                elif expr.op == "a>>":
                    res = res >> arg
                elif expr.op == "a<<":
                    res = res << arg
                elif expr.op == "<<<":
                    res = z3.RotateLeft(res, arg)
                elif expr.op == ">>>":
                    res = z3.RotateRight(res, arg)
                elif expr.op == "idiv":
                    res = res / arg
                elif expr.op == "udiv":
                    res = z3.UDiv(res, arg)
                elif expr.op == "imod":
                    res = res % arg
                elif expr.op == "umod":
                    res = z3.URem(res, arg)
                else:
                    raise NotImplementedError("Unsupported OP yet: %s" %
                                              expr.op)
        elif expr.op == 'parity':
            arg = z3.Extract(7, 0, res)
            res = z3.BitVecVal(1, 1)
            for i in xrange(8):
                res = res ^ z3.Extract(i, i, arg)
        elif expr.op == '-':
            res = -res
        elif expr.op == "bsf":
            size = expr.size
            src = res
            res = z3.If((src & (1 << (size - 1))) != 0, size - 1, src)
            for i in xrange(size - 2, -1, -1):
                res = z3.If((src & (1 << i)) != 0, i, res)
        elif expr.op == "bsr":
            size = expr.size
            src = res
            res = z3.If((src & 1) != 0, 0, src)
            for i in xrange(size - 1, 0, -1):
                index = -i % size
                res = z3.If((src & (1 << index)) != 0, index, res)
        else:
            raise NotImplementedError("Unsupported OP yet: %s" % expr.op)

        return res
Exemplo n.º 8
0
def do_LR(op, stack, state):
    #arg1, arg2 = pop_values(stack, state, 2)
    arg1_val = stack.pop()

    size = SIZE
    if z3.is_bv(arg1_val):
        arg1 = arg1_val
        size = arg1.size()
    elif type(arg1_val) == str:
        arg1 = state.registers[arg1_val]
        size = arg1.size()
    else:
        arg1 = prepare(arg1_val)

    arg2, = pop_values(stack, state, 1)

    if arg2.size() > size:
        arg2 = z3.Extract(size - 1, 0, arg2)

    stack.append(z3.RotateLeft(arg1, arg2))
Exemplo n.º 9
0
    def from_ExprOp(self, expr):
        args = map(self.from_expr, expr.args)
        res = args[0]

        if len(args) > 1:
            for arg in args[1:]:
                if expr.op in self.trivial_ops:
                    res = eval("res %s arg" % expr.op)
                elif expr.op == ">>":
                    res = z3.LShR(res, arg)
                elif expr.op == "a>>":
                    res = res >> arg
                elif expr.op == "a<<":
                    res = res << arg
                elif expr.op == "<<<":
                    res = z3.RotateLeft(res, arg)
                elif expr.op == ">>>":
                    res = z3.RotateRight(res, arg)
                elif expr.op == "idiv":
                    res = res / arg
                elif expr.op == "udiv":
                    res = z3.UDiv(res, arg)
                elif expr.op == "imod":
                    res = res % arg
                elif expr.op == "umod":
                    res = z3.URem(res, arg)
                else:
                    raise NotImplementedError("Unsupported OP yet: %s" %
                                              expr.op)
        elif expr.op == 'parity':
            arg = z3.Extract(7, 0, res)
            res = z3.BitVecVal(1, 1)
            for i in xrange(8):
                res = res ^ z3.Extract(i, i, arg)
        elif expr.op == '-':
            res = -res
        else:
            raise NotImplementedError("Unsupported OP yet: %s" % expr.op)

        return res
Exemplo n.º 10
0
 def bvrol(self, other):
     return type(self)(z3.RotateLeft(self.value, other.value))
Exemplo n.º 11
0
def rol(x,y):
    return z3.simplify(z3.RotateLeft(x,y))
Exemplo n.º 12
0
def z3RL(op):
    return z3.RotateLeft(op, 1)
Exemplo n.º 13
0
 def walk_bv_rol(self, formula, args, **kwargs):
     return z3.RotateLeft(args[0],
                          formula.bv_rotation_step())
Exemplo n.º 14
0
    def VertexOperationToSmt(self):
        assert (self.type != VertexNode.VertexType.NONE)

        if self.type == VertexNode.VertexType.VAR:
            # Possible Vertex : input Variable, name = operand1
            # input variable: there is nothing to do.
            # assigned Variable: name = operands[0]

            # It's an input variable if there is no operand :
            if self.operands == None: return None
            # otherwise, it's an assigned variable, but make sure just in case
            assert (self.operator == VertexNode.OpCode.ASSIGN)
            return self.VertexNameToSmt() == self.operands[0].VertexNameToSmt()

        elif self.type == VertexNode.VertexType.TEMP:
            # Possible Vertex : Function Call, Array Load, Binary Operation, Comparison,
            #                   Conditional Assignment, Unary Operation
            # function call: name = func_name(arguments)
            # array load: name = array[index]
            # binary operation: name = operand1 op operand2
            # comparison: name = operand1 comp operand2
            # conditional assignment: name = ite(operand1, operand2, operand3)
            # unary operation: name = op operand1

            # It's a function call
            if self.operator == VertexNode.OpCode.FUNCCALL:
                assert (self.operands[0].type == VertexNode.VertexType.FUNC)
                # There are four possible functions that can last until now:
                if self.operands[0].name == "merge":
                    args = []
                    for op in self.operands[1:]:
                        args.append(op.VertexNameToSmt())
                    return self.VertexNameToSmt() == z3.Concat(args)
                elif self.operands[0].name == "split":
                    toSplit = self.operands[1].VertexNameToSmt()
                    # Extract requires actual numerical value.
                    lowerBound = self.operands[2].value
                    upperBound = self.operands[3].value
                    return self.VertexNameToSmt() == z3.Extract(
                        upperBound, lowerBound, toSplit)
                elif self.operands[0].name == "zeroext":
                    toExtend = self.operands[1].VertexNameToSmt()
                    # ZeroExt requires actual numerical value
                    n = self.operands[2].value
                    return self.VertexNameToSmt() == z3.ZeroExt(n, toExtend)
                elif self.operands[0].name == "concat":
                    args = []
                    for op in self.operands[1:]:
                        args.append(op.VertexNameToSmt())
                    return self.VertexNameToSmt() == z3.Concat(args)

            # It's an array load
            elif self.operator == VertexNode.OpCode.LOAD:
                array = self.operands[0].VertexNameToSmt()
                arrayIndex = self.operands[1].VertexNameToSmt()
                return self.VertexNameToSmt() == z3.Select(array, arrayIndex)

            # It's a conditional statement
            elif self.operator == VertexNode.OpCode.CONDITIONAL:
                cond = self.operands[0].VertexNameToSmt()
                truePath = self.operands[1].VertexNameToSmt()
                falsePath = self.operands[2].VertexNameToSmt()
                return self.VertexNameToSmt() == z3.If(cond, truePath,
                                                       falsePath)

            # It's a comparison (x < y)
            elif VertexNode.OpCode.IsComparison(self.operator):
                lhs = self.operands[0].VertexNameToSmt()
                rhs = self.operands[1].VertexNameToSmt()
                if self.operator == VertexNode.OpCode.GT:
                    return self.VertexNameToSmt() == z3.UGT(lhs, rhs)
                elif self.operator == VertexNode.OpCode.GE:
                    return self.VertexNameToSmt() == z3.UGE(lhs, rhs)
                elif self.operator == VertexNode.OpCode.LT:
                    return self.VertexNameToSmt() == z3.ULT(lhs, rhs)
                elif self.operator == VertexNode.OpCode.LE:
                    return self.VertexNameToSmt() == z3.ULE(lhs, rhs)
                elif self.operator == VertexNode.OpCode.EQ:
                    return self.VertexNameToSmt() == (lhs == rhs)
                elif self.operator == VertexNode.OpCode.NE:
                    return self.VertexNameToSmt() == (lhs != rhs)

            # It's a binary operation
            elif VertexNode.OpCode.IsBinaryOp(self.operator):
                lhs = self.operands[0].VertexNameToSmt()
                rhs = self.operands[1].VertexNameToSmt()
                if self.operator == VertexNode.OpCode.PLUS:
                    return self.VertexNameToSmt() == (lhs + rhs)
                elif self.operator == VertexNode.OpCode.MINUS:
                    return self.VertexNameToSmt() == (lhs - rhs)
                elif self.operator == VertexNode.OpCode.AND:
                    return self.VertexNameToSmt() == (lhs & rhs)
                elif self.operator == VertexNode.OpCode.OR:
                    return self.VertexNameToSmt() == (lhs | rhs)
                elif self.operator == VertexNode.OpCode.XOR:
                    return self.VertexNameToSmt() == (lhs ^ rhs)
                elif self.operator == VertexNode.OpCode.SHL:
                    return self.VertexNameToSmt() == (lhs << rhs)
                elif self.operator == VertexNode.OpCode.SHR:
                    return self.VertexNameToSmt() == (z3.LShR(lhs, rhs))
                elif self.operator == VertexNode.OpCode.ROL:
                    return self.VertexNameToSmt() == (z3.RotateLeft(lhs, rhs))
                elif self.operator == VertexNode.OpCode.ROR:
                    return self.VertexNameToSmt() == (z3.RotateRight(lhs, rhs))
                elif self.operator == VertexNode.OpCode.MUL:
                    return self.VertexNameToSmt() == (lhs * rhs)
                elif self.operator == VertexNnode.OpCode.DIV:
                    return self.VertexNameToSmt() == (lhs / rhs)

            # It's a unary operation
            elif VertexNode.OpCode.IsUnaryOp(self.operator):
                rhs = self.operands[0].VertexNameToSmt()
                if self.operator == VertexNode.OpCode.NOT:
                    return self.VertexNameToSmt() == ~rhs

        elif self.type == VertexNode.VertexType.IMM:
            # Possible Vertex : Immediate Value
            return None
        elif self.type == VertexNode.VertexType.ARR:
            # Possible Vertex : Input array, array store
            # input array: there is nothing to do
            # array store: newarray = store(array, index, value)

            # if operator == None, it's an "input" array
            if self.operator == None: return None
            if self.operator == VertexNode.OpCode.NONE: return None
            # Otherwise, it must be an array store operation vertex
            assert (self.operator == VertexNode.OpCode.STORE)
            oldArray = self.operands[0].VertexNameToSmt()
            index = self.operands[1].VertexNameToSmt()
            value = self.operands[2].VertexNameToSmt()
            newArray = self.VertexNameToSmt()
            return newArray == z3.Store(oldArray, index, value)

        elif self.type == VertexNode.VertexType.FUNC:
            # Possible Vertex : Name of the function
            return None