예제 #1
0
def mkByteVar(op):
    locs = op.getLocations()

    if (len(locs) > 1):
        return z3.Concat(map(lambda b: z3.BitVec(str(b), 8), locs))
    else:
        return z3.BitVec(str(locs[0]), 8)
def test_dependence_map():
    # Arrange
    x = z3.BitVec("x", 256)
    y = z3.BitVec("y", 256)
    z = z3.BitVec("z", 256)
    a = z3.BitVec("a", 256)
    b = z3.BitVec("b", 256)

    conditions = [x > y, y == z, a == b]

    dependence_map = DependenceMap()

    # Act
    for condition in conditions:
        dependence_map.add_condition(condition)

    # Assert
    assert 2 == len(dependence_map.buckets)

    assert x in dependence_map.buckets[0].variables
    assert y in dependence_map.buckets[0].variables
    assert z in dependence_map.buckets[0].variables
    assert len(set(dependence_map.buckets[0].variables)) == 3

    assert conditions[0] in dependence_map.buckets[0].conditions
    assert conditions[1] in dependence_map.buckets[0].conditions

    assert a in dependence_map.buckets[1].variables
    assert b in dependence_map.buckets[1].variables
    assert len(set(dependence_map.buckets[1].variables)) == 2

    assert conditions[2] in dependence_map.buckets[1].conditions
예제 #3
0
def mkByteList(op):
    locs = op.getLocations()

    if (len(locs) > 1):
        return map(lambda b: z3.BitVec(str(b), 8), locs)
    else:
        return [z3.BitVec(str(locs[0]), 8)]
예제 #4
0
    def advance(self, n, i, first):
        # add all intermediate states for each step
        for x in range(0, n):
            p1 = z3.BitVec("part" + str(self.states), 32)
            p2 = z3.BitVec("part" + str(self.states + 1), 32)
            p3 = z3.BitVec("part" + str(self.states + 2), 32)
            self.solver.add(p1 == self.current ^ (self.current << 13))
            self.solver.add(p2 == p1 ^ z3.LShR(p1, 14))
            self.solver.add(p3 == p2 ^ (p2 << 15))
            self.states += 3
            self.current = p3

        # if this is the "leak" at the beginning, add it directly
        if first > 0:
            self.solver.add((p3 & 0xFFFF) == first)
        # if this isn't, we've stopped on a stable state and should add constraints
        else:
            """
            unsigned char n = (x & (0xFF << i)) >> i;
            if (n != 0 && n == (n & -n)) {
            """
            n = z3.LShR(self.current & (0xFF << i), i)
            self.solver.add(n != 0)
            #self.solver.add(z3.LShR(self.current & (0xFF << i), i) != 0)
            self.solver.add(n == n & -n)
            #self.solver.add(z3.LShR(self.current & (0xFF << i), i) == (z3.LShR(self.current & (0xFF << i), i) & z3.LShR((-self.current) & (0xFF << i), i)))

        # update our guess if we're still SAT
        if self.check() != z3.sat:
            raise RuntimeError("UNSAT")
        else:
            print "NEW GUESS: %d" % self.get_seed()
예제 #5
0
    def run_test_execution(self):
        for upper_bound in (0, 1, 50):
            x, y = z3.BitVec("x", 4), z3.BitVec("y", 8)
            formula: z3.BoolRef = z3.ULT(z3.ZeroExt(4, x) + y, z3.BitVecVal(upper_bound, 8))
            self.assert_eamp_edge_scheduler_execution(100, 2, 0.99, FormulaParamsZ3(formula=formula, variables=[x, y]))

        x, y = z3.BitVec("x", 8), z3.BitVec("y", 8)
        formula: z3.BoolRef = z3.ULT(y, 100)
        model_count = (2 ** 8) * 100

        for q in (1, 2, 3, 4) if RUN_MINI_BENCHMARK else (1,):
            t0 = perf_counter()

            self.assert_eamp_edge_scheduler_execution(100, q, 0.99, FormulaParamsZ3(
                formula=formula, variables=[x, y]
            ), model_count)

            print(f"Mini Benchmark {self.get_eamp_edge_scheduler_class()} q={q} took {perf_counter() - t0:.2f}")

        zs = [z3.BitVec(f"z{idx}", 1) for idx in range(50)]
        formula: z3.BoolRef = z3.And([zs[idx] == 1 for idx in range(25)])
        model_count = 2 ** 25

        self.assert_eamp_edge_scheduler_execution(
            100, 1, 0.99, FormulaParamsZ3(
                formula=formula, variables=zs
            ), model_count)
예제 #6
0
    def _constraints_to_z3(self):
        across_variables = {k: (z3.BitVec("{}-across({})".format(k, len(v)), len(self.words_by_length[len(v)])), v) for k, v in self.acrosses.items()}
        down_variables = {k: (z3.BitVec("{}-down({})".format(k, len(v)), len(self.words_by_length[len(v)])), v) for k, v in self.downs.items()}
        self.s = z3.Solver()
        for variable, info in list(across_variables.values()) + list(down_variables.values()):

            # n & -n == n iff n has exactly one bit set. So this constraint just says
            # each variable represents one exactly one index into the lexicographic ordering.
            # of words of that length.
            self.s.add(variable & -variable == variable)

        for restriction, indices in self.restrictions.items():
            across, across_info = across_variables[restriction[0]]
            down, down_info = down_variables[restriction[1]]
            across_ix, down_ix = indices

            across_letters = []
            down_letters = []
            for letter in string.ascii_uppercase:
                across_bitarray = self.lexicon_bitarrays[len(across_info)][across_ix][letter]
                across_ok = z3.BVRedOr(across_bitarray & across) #) != 0  # TODO check if n & -n == n is faster since we know there is exactly one or 0 set
                down_bitarray = self.lexicon_bitarrays[len(down_info)][down_ix][letter]
                down_ok = z3.BVRedOr(down_bitarray & down) # != 0 # z3.BVRedOr(down_bitarray & down)
                across_letters.append(across_ok)
                down_letters.append(down_ok)

            # for each restriction, the bitarray representing the letter
            # chosen must be the same.
            self.s.add(z3.Concat(across_letters) & z3.Concat(down_letters) != 0)
예제 #7
0
def solve(mask, compromise):

    shiftlen = 64 - popcount(mask) - compromise

    bb = z3.BitVec("bb", 64)
    masked_bb = [z3.BitVec(f"masked_bb_{i}", 64) for i in range(2 ** popcount(mask))]
    magic_number = z3.BitVec("magic_number", 64)
    imul_tmp = [z3.BitVec(f"imul_tmp_{i}", 64) for i in range(2 ** popcount(mask))]
    result_index_short = [z3.BitVec(f"result_index_{i}", popcount(mask) + compromise) for i in range(2 ** popcount(mask))]
    
    s = z3.Solver()
    for i in range(2 ** popcount(mask)):
        s.add(masked_bb[i] == pdep(i, mask))
        s.add(imul_tmp[i] == masked_bb[i] * magic_number)
        s.add(result_index_short[i] == z3.Extract(63, 63 - popcount(mask) - compromise + 1, imul_tmp[i]))
    s.add(z3.Distinct(result_index_short))
    # for i in range(2 ** popcount(mask)):
    #     for j in range(i + 1, 2 ** popcount(mask)):
    #         s.add(result_index_short[i] != result_index_short[j])
    s.add(magic_number >= 1)
    time_start = time.time()
    result = s.check()
    time_end = time.time()

    print(f"mask = {hex64(mask)}")
    print(f"compromise = {compromise}")
    print(f"result = {result}")
    print(f"elapsed time = {int(time_end - time_start)} second")

    if result == z3.unsat:
        return False

    print(f"magic_number = {hex64(s.model()[magic_number].as_long())}")

    return True
예제 #8
0
def main():
    x = z3.BitVec('x', 8)
    y = z3.BitVec('y', 8)

    s = z3.Solver()
    s.add(((x << 2) + (3 * y)) == z3.BitVecVal(0x41, 8))
    s.add(((x >> 4) - (y << 2)) > z3.BitVecVal(0x10, 8))
    s.add(((x * 5) - (y * 2)) > z3.BitVecVal(0x42, 8))
    s.add(x != z3.BitVecVal(0, 8))
    s.add(y != z3.BitVecVal(0, 8))

    while s.check() == z3.sat:
        # Get a model satisfying the rules.
        model = s.model()

        # Do something with the model
        print model

        # Prevent the same model from showing up again.
        block = []
        for instance in model:
            if instance.arity() > 0:
                raise z3.Z3Exception(
                    "uninterpreted functions are not supported")
            constant = instance()
            if z3.is_array(constant) or constant.sort().kind(
            ) == z3.Z3_UNINTERPRETED_SORT:
                raise Z3Exception(
                    "arrays and uninterpreted sorts are not supported")
            block.append(constant == model[instance])
        inverted_block = z3.Not(z3.And(block))
        s.add(inverted_block)
예제 #9
0
def make_constraints_next(n_constraints: int,
                          slope: int = 0x5DEECE66D,
                          intercept: int = 0xB,
                          gen_bits=31):
    # Define some constants
    addend = z.BitVecVal(intercept, 64)
    multiplier = z.BitVecVal(slope, 64)
    mask = z.BitVecVal((1 << 48) - 1, 64)

    # Define symbolic variables for the seed variable
    seeds = {
        f'seed_{i}': z.BitVec(f'seed_{i}', 64)
        for i in range(n_constraints)
    }

    constraints = []

    # Build constraints for the relation in row 175
    for i in range(1, n_constraints):
        constraints.append(seeds[f'seed_{i}'] == z.simplify(
            (seeds[f'seed_{i - 1}'] * multiplier + addend) & mask))

    # Define symbolic variables for the output from next()
    next_outputs = {
        f'next_output_{i}': z.BitVec(f'output{i}', 32)
        for i in range(1, n_constraints)
    }

    # Build the constraints for the relation in row 176
    for i in range(1, n_constraints):
        constraints.append(next_outputs[f'next_output_{i}'] == z.simplify(
            z.Extract(31, 0, z.LShR(seeds[f'seed_{i}'], 48 - gen_bits))))

    return constraints, seeds, next_outputs
예제 #10
0
def break_rand(nums: list, next_num: int):
    n_nums = len(nums)
    # print(f'len nums: {n_nums}')

    states = {
        f'state_{i}': z.BitVec(f'state_{i}', 32)
        for i in range(1, n_nums + 2)
    }
    # print(states)
    output_next = z.BitVec('output_next', 32)

    s = z.Solver()

    for i in range(2, n_nums + 2):
        s.add(states[f'state_{i}'] == states[f'state_{i - 1}'] * 214013 +
              2531011)

    for i in range(1, n_nums + 1):
        s.add(
            z.URem((states[f'state_{i}'] >> 16) & 0x7FFF, 100) == nums[i - 1])

    s.add(output_next == z.URem((states[f'state_{n_nums + 1}'] >> 16)
                                & 0x7FFF, 100))

    # print(s)

    if s.check() == z.sat:
        print(f'For the sequence: {nums}, problem is satisfiable')
        print(
            f'We were expecting: {next_num} and got: {s.model()[output_next]}\n'
        )
    else:
        print(f'For the sequence: {nums}, problem is unsatisfiable')

    return s, states, output_next
예제 #11
0
파일: SMT.py 프로젝트: rongqinglee/SEA
    def __getitem__(self, op):

        if (op | iss | InputOp):
            r = ""
            for loc in op.getLocations():
                var = z3.BitVec(str(loc), 8)
                var = self.m[var]
                r = r + ("\\x%.2x" % var.as_long())
            return r

        if (op | iss | RegOp):
            var = map(lambda b: z3.BitVec(str(b), 8), op.getLocations())
            var = map(lambda b: self.m[b], var)
            if (len(var) > 1):
                return z3.simplify(z3.Concat(var)).as_signed_long()
            else:
                return z3.simplify(var[0]).as_signed_long()
        elif (op.isMem()):
            array = z3.Array(op.name, z3.BitVecSort(16), z3.BitVecSort(8))
            f = self.m[array]

            #print self.m

            es = f.as_list()[:-1]

            var = []

            for loc in op.getLocations():
                byte = None
                for entry in es:
                    #print entry
                    if loc.getIndex() == entry[0].as_signed_long():
                        byte = entry[1]  #.as_signed_long()
                        break

                if (byte == None):
                    byte = f.else_value()

                var.append(byte)
            r = ""
            for v in var:
                r = r + ("\\x%.2x" % v.as_long())

            return r

            #var.reverse()

            #if (len(var) > 1):
            #  return z3.simplify(z3.Concat(var)).as_signed_long()
            #else:
            #  return z3.simplify(var[0]).as_signed_long()
        else:
            assert (0)

        r = []
        for loc in i.getLocations():
            r.append(self.vars[str(loc)])
        return r
예제 #12
0
파일: ex1.py 프로젝트: tedbauer/minisynth
def ex1_goal():
    x = z3.BitVec('x', 8)
    y = z3.BitVec('y', 8)
    h = z3.BitVec('h', 8)

    phi_n = (y == x * 4)
    phi_s = (y == x << h)

    return (z3.ForAll([x, y], phi_n == phi_s))
예제 #13
0
    def __init__(self, known_values):
        self.s0 = z3.BitVec('s0', 64)
        self.s1 = z3.BitVec('s1', 64)
        self.state = [self.s0, self.s1]

        self.solver = z3.Solver()

        # The known variable will contain the values that we generated in Firefox
        self.known = known_values
예제 #14
0
def z3_new_state(arch):
    state = {
        "stack": z3.BitVec(unique("stack"), arch.page_size*8),
        "constraints": []
    }

    for reg in arch.regs:
        state[reg] = z3.BitVec(unique(reg), arch.bits)

    return state
예제 #15
0
def gen_symbolic_value(var_type, name):
    if var_type == bin_format.i32:
        return z3.BitVec(name, 32)
    if var_type == bin_format.i64:
        return z3.BitVec(name, 64)
    if var_type == bin_format.f32:
        return z3.FP(f'f32_{i}', z3.Float32())
    if var_type == bin_format.f64:
        return z3.FP(name, z3.Float64())
    raise TypeError('Unsupported variable type')
예제 #16
0
def gen_collision():
    qword1_expr = z3.BitVec("qword1", 64)
    qword2_expr = z3.BitVec("qword2", 64)
    z3_hash = hash_bytes([qword1_expr, qword2_expr])
    solver = z3.Solver()
    solver.append(z3_hash == HASH)
    result = solver.check()
    assert str(result) == "sat", result
    model = solver.model()
    return model[qword1_expr].as_long(), model[qword2_expr].as_long()
예제 #17
0
 def make_value_vars(prefix):
     vInput = list(
         z3.BitVecs(id_arr(f'{prefix}_valInput', nInput), 32, ctx))
     vPR = [(list(
         z3.BitVecs(id_arr(f'{prefix}_valParam_{i}', comp.arity), 32,
                    ctx)), z3.BitVec(f'{prefix}_valReturn_{i}', 32,
                                     ctx))
            for i, comp in enumerate(lib)]
     vOutput = z3.BitVec(f'{prefix}_valOutput', 32, ctx)
     return vInput, vPR, vOutput
예제 #18
0
 def from_ExprLoc(self, expr):
     if self.loc_db is None:
         # No loc_db, fallback to default name
         return z3.BitVec(str(expr), expr.size)
     loc_key = expr.loc_key
     offset = self.loc_db.get_location_offset(loc_key)
     if offset is not None:
         return z3.BitVecVal(offset, expr.size)
     # fallback to default name
     return z3.BitVec(str(loc_key), expr.size)
예제 #19
0
 def abstract(self, label_suffix):
     old_storage = self.storage
     self.storage = AbstractStorage(f'abstract_storage{label_suffix}')
     for map_id in self.mapping_id_to_sum:
         if svm_utils.is_bv_concrete(map_id):
             map_id_string = svm_utils.get_concrete_int(map_id)
         else:
             map_id_string = str(z3.simplify(map_id))
             raise Exception("pdb")
         label = f'abstract_sum_{map_id_string}{label_suffix}'
         self.mapping_id_to_sum[map_id] = z3.BitVec(label, 256)
     self.balance = z3.BitVec(f'gstate_balance{label_suffix}', 256)
예제 #20
0
    def add_register(self, reg: Dict):
        start = reg["offset"]
        end = reg["offset"] + reg["size"]
        size = reg["size"]

        reg["start"] = start
        reg["end"] = end
        self._registers[reg["name"]] = reg

        key = (start, end)

        reg_value = self.get_register_from_bounds(reg)

        if reg_value != None:
            # this shouldnt happen idk
            if reg_value["size"] < size:
                reg_value["size"] = size
                reg_value["start"] = start
                reg_value["end"] = end

                if self.pure_symbolic and reg["name"] != self.aliases["PC"][
                        "reg"] and reg["type_str"] != "flg":
                    reg.pop("value")
                    reg_value["bv"] = z3.BitVec(reg["name"], size)
                else:
                    reg_value["bv"] = z3.BitVecVal(reg.pop("value"), size)

                reg_value["bounds"] = key
                self.offset_dictionary[key] = reg_value

            reg["bounds"] = reg_value["bounds"]
            reg["sub"] = True

        else:
            reg_value = {
                "type": reg["type"],
                "size": size,
                "start": start,
                "end": end
            }
            if "value" in reg and (not self.pure_symbolic
                                   or reg["name"] == self.aliases["PC"]["reg"]
                                   or reg["type_str"] == "flg"):
                reg_value["bv"] = z3.BitVecVal(reg.pop("value"), size)
            else:
                reg.pop("value")
                reg_value["bv"] = z3.BitVec(reg["name"], size)

            reg_value["bounds"] = key
            self.offset_dictionary[key] = reg_value

            reg["bounds"] = key
            reg["sub"] = False
예제 #21
0
 def __init__(self, nbits, key):
     self.nbits = nbits
     self.slvr = z3.Goal()
     self.init = z3.BitVec('init', nbits)
     tmp = z3.BitVec('tmp', nbits)
     # make sure Goal() start with `init` (at step 2)
     for i in range(nbits):
         self.slvr.add(z3.Extract(i, i, tmp) == z3.Extract(i, i, self.init))
     self.state = self.init
     self.poly = z3.BitVecVal(key, nbits)
     self.zero = z3.BitVecVal(0, nbits)
     self.one = z3.BitVecVal(1, nbits)
예제 #22
0
 def from_ExprLoc(self, expr):
     if self.symbol_pool is None:
         # No symbol_pool, fallback to default name
         return z3.BitVec(str(expr), expr.size)
     loc_key = expr.loc_key
     offset = self.symbol_pool.loc_key_to_offset(loc_key)
     name = self.symbol_pool.loc_key_to_name(loc_key)
     if offset is not None:
         return z3.BitVecVal(offset, expr.size)
     if name is not None:
         return z3.BitVec(name, expr.size)
     # fallback to default name
     return z3.BitVec(str(loc_key), expr.size)
def replace_bv_sequences_with_conjectures(z3from, prefix):
    """ Returns a modified z3 expression substituting conjectures in place of sequences"""
    concat_sequences = find_symbolic_byte_concat_sequences(z3from, prefix)
    also = find_symbolic_variables_in_numerical_expressions(z3from)
    #the idea here is that any concat sequence of length 4 will be replaced with
    #an integer conjecture... if the variables in that integer conjecture are also
    #involved in numerical expressions, we strengthen the conjecture
    modified_z3 = z3from
    for s in concat_sequences:
        if abs(s[1] - s[0]) + 1 == 4:
            if all_in_sequence_in_set(s, also, prefix):
                conjecture_label = "?"
            else:
                conjecture_label = "??"
            if s[0] < s[1]:
                #it is a sequence like sym_0, sym_1, sym_2, sym_3
                s0 = z3.BitVec(prefix + str(s[0]), 8)
                s1 = z3.BitVec(prefix + str(s[0] + 1), 8)
                s2 = z3.BitVec(prefix + str(s[0] + 2), 8)
                s3 = z3.BitVec(prefix + str(s[0] + 3), 8)
                s32 = z3.BitVec(
                    prefix + "[" + str(s[0]) + "-" + str(s[1]) + "]-" +
                    conjecture_label + "_intbe:32", 32)
                modified_z3 = z3.substitute(modified_z3,
                                            (s0, z3.Extract(31, 24, s32)))
                modified_z3 = z3.substitute(modified_z3,
                                            (s1, z3.Extract(23, 16, s32)))
                modified_z3 = z3.substitute(modified_z3,
                                            (s2, z3.Extract(15, 8, s32)))
                modified_z3 = z3.substitute(modified_z3,
                                            (s3, z3.Extract(7, 0, s32)))
            else:
                # it is a sequence like sym_3, sym_2, sym_1, sym_0
                s3 = z3.BitVec(prefix + str(s[0]), 8)
                s2 = z3.BitVec(prefix + str(s[0] - 1), 8)
                s1 = z3.BitVec(prefix + str(s[0] - 2), 8)
                s0 = z3.BitVec(prefix + str(s[0] - 3), 8)
                s32 = z3.BitVec(
                    prefix + "[" + str(s[1]) + "-" + str(s[0]) + "]-" +
                    conjecture_label + "_intle:32", 32)
                modified_z3 = z3.substitute(modified_z3,
                                            (s0, z3.Extract(31, 24, s32)))
                modified_z3 = z3.substitute(modified_z3,
                                            (s1, z3.Extract(23, 16, s32)))
                modified_z3 = z3.substitute(modified_z3,
                                            (s2, z3.Extract(15, 8, s32)))
                modified_z3 = z3.substitute(modified_z3,
                                            (s3, z3.Extract(7, 0, s32)))
            #more type conjectures needed for different types and sizes
    return modified_z3
예제 #24
0
def solve(n, keylen):
    mlen = len(ct)
    total = mlen * 8
    nytes = total // n

    s = z3.Solver()

    pt = z3.BitVec("pt", total)
    key = z3.BitVec("key", total)
    cipher = z3.BitVec("ct", total)

    def nyte(bitvec, n, i):
        """Extract the i'th n-bit value from bitvec."""
        start = bitvec.size() - n - (i * n)
        return z3.Extract(start + n - 1, start, bitvec)

    # Plaintext is ascii
    for i in xrange(mlen):
        s.add(nyte(pt, 8, i) >= 0x20)
        s.add(nyte(pt, 8, i) <= 0x7e)

    # Plaintext starts with "flag{" and ends with "}"
    for i, c in enumerate("flag{"):
        s.add(nyte(pt, 8, i) == ord(c))
    s.add(nyte(pt, 8, mlen - 1) == ord("}"))

    # Key is repeating
    for i in xrange(keylen, mlen):
        s.add(nyte(key, 8, i) == nyte(key, 8, i % keylen))

    # Known ciphertext
    for i, c in enumerate(ct):
        s.add(nyte(cipher, 8, i) == ord(c))

    # Transformation
    for i in xrange(nytes):
        m = nyte(pt, n, i)
        k = nyte(key, n, i)
        c = nyte(cipher, n, i)
        s.add(c == (m + k) & ((1 << n) - 1))

    cnt = 0
    while z3.sat == s.check():
        if cnt > 5:
            return
        cnt += 1
        plaintext = s.model()[pt].as_long()
        flag = hex(plaintext)[2:-1].decode("hex")
        print "[*] {:s}".format(flag)
        s.add(pt != plaintext)
예제 #25
0
파일: Condition.py 프로젝트: getwindow/SEA
    def getOperands(self, ops, concat=True):

        rops = []
        for op in ops:
            if (op.isVar()):
                if (op.size > 1):
                    rops.append(
                        z3.Concat(
                            map(lambda b: z3.BitVec(b, 8), op.get_bytes())))
                else:
                    rops.append(z3.BitVec(op.get_bytes()[0], 8))
            else:
                rops.append(z3.BitVecVal(op.getValue(), 8 * op.size))

        return rops
예제 #26
0
def untemper(y):
    y0 = z3.BitVec('y0', 32)
    y1 = z3.BitVec('y1', 32)
    y2 = z3.BitVec('y2', 32)
    y3 = z3.BitVec('y3', 32)

    equ = [
        y1 == y0 ^ ((z3.LShR(y0, 11)) & 0xffffffff),
        y2 == y1 ^ ((y1 << 7) & 0x9d2c5680),
        y3 == y2 ^ ((y2 << 15) & 0xefc60000), y == y3 ^ (z3.LShR(y3, 18))
    ]

    solver = z3.Solver()
    solver.add(equ)
    assert solver.check() == z3.z3.CheckSatResult(z3.Z3_L_TRUE)
    return solver.model()[y0].as_long()
예제 #27
0
 def gen_input_symbol(self):
     name = 'input%d' % self.input_idx
     self.input_idx += 1
     var = z3.BitVec(name, 8)
     if debug > 0:
         print(GREEN + 'created symbolic variable: %s' % var + NORMAL)
     return var
def test_get_expr_variables():
    # Arrange
    x = z3.Bool("x")
    y = z3.BitVec("y", 256)
    z = z3.BitVec("z", 256)
    b = z3.BitVec("b", 256)
    expression = z3.If(x, y, z + b)

    # Act
    variables = list(map(str, _get_expr_variables(expression)))

    # Assert
    assert str(x) in variables
    assert str(y) in variables
    assert str(z) in variables
    assert str(b) in variables
예제 #29
0
def test_multi32():
    r2p = r2pipe.open("test/tests/multi32", flags=["-2"])
    r2p.cmd("s sym.check; aei; aeim; wv 162517261 @ 0x00178004")

    esilsolver = ESILSolver(r2p, debug=False, trace=False)
    #esilsolver.initVM()
    state = esilsolver.init_state()
    state.memory.write_bv(0x00178004, z3.BitVec("arg1", 32), 4)

    state = esilsolver.run(target=0x0000052d)
    eax = state.registers["eax"]

    state = esilsolver.run(target=0x00000558)
    state.solver.add(state.registers["zf"] == 1)

    state = esilsolver.run(target=0x00000588)
    print(state.registers["zf"])
    state.solver.add(state.registers["zf"] == 1)

    print("solving")
    sat = state.solver.check()
    print(sat)

    m = state.solver.model()
    print(m.eval(eax))
예제 #30
0
 def convert_to_z3(self, variables):
     if self.operation == Node.CONSTANT:
         return z3.BitVecVal(self.left, self.target_width)
     elif self.operation == Node.VARIABLE:
         if self.left in variables:
             return variables[self.left]
         else:
             var = z3.BitVec(self.left, self.variable_width)
             ext_var = z3.ZeroExt(self.target_width - self.variable_width,
                                  var)
             variables[self.left] = ext_var
             return ext_var
     else:  # operation
         left = self.left.convert_to_z3(variables)
         right = self.right.convert_to_z3(variables)
         if self.operation == Node.ADDITION:
             return left + right
         elif self.operation == Node.SUBTRACTION:
             return left - right
         elif self.operation == Node.MULTIPLICATION:
             return left * right
         elif self.operation == Node.DIVISION:
             return left / right
         elif self.operation == Node.LEFT_SHIFT:
             return left << right
         elif self.operation == Node.RIGHT_SHIFT:
             return left >> right
         elif self.operation == Node.AND:
             return left & right
         elif self.operation == Node.OR:
             return left | right
         elif self.operation == Node.XOR:
             return left ^ right
     raise LookupError('Unknown operation: %s' % str(self.operation))