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
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
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
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))
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
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))
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
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))
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
def bvrol(self, other): return type(self)(z3.RotateLeft(self.value, other.value))
def rol(x,y): return z3.simplify(z3.RotateLeft(x,y))
def z3RL(op): return z3.RotateLeft(op, 1)
def walk_bv_rol(self, formula, args, **kwargs): return z3.RotateLeft(args[0], formula.bv_rotation_step())
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