def test_some_vector_ops(): from simuvex.vex.irop import translate s = SimState() a = s.BVV(0xffff0000000100020003000400050006, 128) b = s.BVV(0x00020002000200020002000200020002, 128) calc_result = translate(s, 'Iop_Sub16x8', (a, b)) correct_result = s.BVV(0xfffdfffeffff00000001000200030004, 128) nose.tools.assert_true(s.se.is_true(calc_result == correct_result)) calc_result = translate(s, 'Iop_CmpEQ16x8', (a, b)) correct_result = s.BVV(0x000000000000ffff0000000000000000, 128) nose.tools.assert_true(s.se.is_true(calc_result == correct_result)) calc_result = translate(s, 'Iop_CmpEQ8x16', (a, b)) correct_result = s.BVV(0x0000ff00ff00ffffff00ff00ff00ff00, 128) nose.tools.assert_true(s.se.is_true(calc_result == correct_result)) calc_result = translate(s, 'Iop_CmpGT16Sx8', (a, b)) correct_result = s.BVV(0x0000000000000000ffffffffffffffff, 128) nose.tools.assert_true(s.se.is_true(calc_result == correct_result)) calc_result = translate(s, 'Iop_CmpGT16Ux8', (a, b)) correct_result = s.BVV(0xffff000000000000ffffffffffffffff, 128) nose.tools.assert_true(s.se.is_true(calc_result == correct_result)) calc_result = translate(s, 'Iop_InterleaveLO16x8', (a, b)) correct_result = s.BVV(0x00030002000400020005000200060002, 128) nose.tools.assert_true(s.se.is_true(calc_result == correct_result)) calc_result = translate(s, 'Iop_InterleaveLO8x16', (a, b)) correct_result = s.BVV(0x00000302000004020000050200000602, 128) nose.tools.assert_true(s.se.is_true(calc_result == correct_result)) calc_result = translate(s, 'Iop_Min8Ux16', (a, b)) correct_result = s.BVV(0x00020000000100020002000200020002, 128) nose.tools.assert_true(s.se.is_true(calc_result == correct_result)) calc_result = translate(s, 'Iop_Min8Sx16', (a, b)) correct_result = s.BVV(0xffff0000000100020002000200020002, 128) nose.tools.assert_true(s.se.is_true(calc_result == correct_result)) c = s.BVV(0xff008877, 32) d = s.BVV(0x11111111, 32) calc_result = translate(s, 'Iop_HAdd8Sx4', (c, d)) correct_result = s.BVV(0x0808cc44, 32) nose.tools.assert_true(s.se.is_true(calc_result == correct_result)) calc_result = translate(s, 'Iop_QAdd8Sx4', (c, d)) correct_result = s.BVV(0x1011997f, 32) nose.tools.assert_true(s.se.is_true(calc_result == correct_result)) calc_result = translate(s, 'Iop_QAdd8Ux4', (c, d)) correct_result = s.BVV(0xff119988, 32) nose.tools.assert_true(s.se.is_true(calc_result == correct_result)) calc_result = translate(s, 'Iop_QSub8Sx4', (c, d)) correct_result = s.BVV(0xeeef8066, 32) nose.tools.assert_true(s.se.is_true(calc_result == correct_result)) calc_result = translate(s, 'Iop_QSub8Ux4', (c, d)) correct_result = s.BVV(0xee007766, 32) nose.tools.assert_true(s.se.is_true(calc_result == correct_result))
def test_cased_store(): initial_memory = {0: 'A', 1: 'A', 2: 'A', 3: 'A'} so = SimState(arch="AMD64", memory_backer=initial_memory) # sanity check nose.tools.assert_equal(so.se.any_n_str(so.memory.load(0, 4), 2), ['AAAA']) # the values values = [None, so.BVV('B'), so.BVV('CC'), so.BVV('DDD'), so.BVV('EEEE')] # try the write s = so.copy() x = s.se.BV('x', 32) s.memory.store_cases(0, values, [x == i for i in range(len(values))]) for i, v in enumerate(values): v = '' if v is None else s.se.any_str(v) w = s.se.any_n_str(s.memory.load(0, 4), 2, extra_constraints=[x == i]) nose.tools.assert_equal(w, [v.ljust(4, 'A')]) # and now with a fallback y = s.se.BV('y', 32) s.memory.store_cases(0, values, [y == i for i in range(len(values))], fallback=s.BVV('XXXX')) for i, v in enumerate(values): v = '' if v is None else s.se.any_str(v) w = s.se.any_n_str(s.memory.load(0, 4), 2, extra_constraints=[y == i]) nose.tools.assert_equal(w, [v.ljust(4, 'X')]) # and now with endness y = s.se.BV('y', 32) s.memory.store_cases(0, values, [y == i for i in range(len(values))], fallback=s.BVV('XXXX'), endness="Iend_LE") for i, v in enumerate(values): v = '' if v is None else s.se.any_str(v) w = s.se.any_n_str(s.memory.load(0, 4), 2, extra_constraints=[y == i]) print w, v.rjust(4, 'X') nose.tools.assert_equal(w, [v.rjust(4, 'X')]) # and write all Nones s = so.copy() z = s.se.BV('z', 32) s.memory.store_cases(0, [None, None, None], [z == 0, z == 1, z == 2]) for i in range(len(values)): w = s.se.any_n_str(s.memory.load(0, 4), 2, extra_constraints=[z == i]) nose.tools.assert_equal(w, ['AAAA']) # and all Nones with a fallback u = s.se.BV('w', 32) s.memory.store_cases(0, [None, None, None], [u == 0, u == 1, u == 2], fallback=s.BVV('WWWW')) for i, v in enumerate(values): w = s.se.any_n_str(s.memory.load(0, 4), 2, extra_constraints=[u == i]) nose.tools.assert_equal(w, ['WWWW']) # and all identical values s = so.copy() #t = s.se.BV('t', 32) s.memory.store_cases( 0, [s.BVV('AA'), s.BVV('AA'), s.BVV('AA')], [u == 0, u == 1, u == 2], fallback=s.BVV('AA')) r = s.memory.load(0, 2) nose.tools.assert_equal(r.op, 'I') nose.tools.assert_equal(s.se.any_n_str(r, 2), ['AA']) # and all identical values, with varying fallback s = so.copy() #t = s.se.BV('t', 32) s.memory.store_cases( 0, [s.BVV('AA'), s.BVV('AA'), s.BVV('AA')], [u == 0, u == 1, u == 2], fallback=s.BVV('XX')) r = s.memory.load(0, 2) nose.tools.assert_equal(s.se.any_n_str(r, 3), ['AA', 'XX']) # and some identical values s = so.copy() #q = s.se.BV('q', 32) values = ['AA', 'BB', 'AA'] s.memory.store_cases(0, [s.BVV(v) for v in values], [u == i for i in range(len(values))], fallback=s.BVV('XX')) r = s.memory.load(0, 2) for i, v in enumerate(values + ['XX']): w = s.se.any_n_str(s.memory.load(0, 2), 2, extra_constraints=[u == i]) nose.tools.assert_equal(w, [(values + ['XX'])[i]])
def test_memory(): initial_memory = {0: 'A', 1: 'A', 2: 'A', 3: 'A', 10: 'B'} s = SimState(arch="AMD64", memory_backer=initial_memory, add_options={ simuvex.o.REVERSE_MEMORY_NAME_MAP, simuvex.o.REVERSE_MEMORY_HASH_MAP }) # Store a 4-byte variable to memory directly... s.memory.store(100, s.se.BitVecVal(0x1337, 32)) # ... then load it expr = s.memory.load(100, 4) nose.tools.assert_equal(expr.model, s.se.BitVecVal(0x1337, 32).model) expr = s.memory.load(100, 2) nose.tools.assert_equal(expr.model, s.se.BitVecVal(0, 16).model) expr = s.memory.load(102, 2) nose.tools.assert_equal(expr.model, s.se.BitVecVal(0x1337, 16).model) # concrete address and partially symbolic result expr = s.memory.load(2, 4) expr = s.memory.load(2, 4) expr = s.memory.load(2, 4) expr = s.memory.load(2, 4) nose.tools.assert_true(s.se.symbolic(expr)) nose.tools.assert_false(s.se.unique(expr)) nose.tools.assert_greater_equal(s.se.any_int(expr), 0x41410000) nose.tools.assert_less_equal(s.se.any_int(expr), 0x41420000) nose.tools.assert_equal(s.se.min_int(expr), 0x41410000) nose.tools.assert_equal(s.se.max_int(expr), 0x4141ffff) # concrete address and concrete result expr = s.memory.load(0, 4) # Returns: a z3 BitVec representing 0x41414141 nose.tools.assert_false(s.se.symbolic(expr)) nose.tools.assert_equal(s.se.any_int(expr), 0x41414141) # symbolicize v = s.memory.make_symbolic("asdf", 0, length=4) nose.tools.assert_equal(v.size(), 32) nose.tools.assert_true(s.se.unique(v)) nose.tools.assert_equal(s.se.any_int(v), 0x41414141) expr = s.memory.load(0, 4) # Returns: a z3 BitVec representing 0x41414141 nose.tools.assert_true(s.se.symbolic(expr)) nose.tools.assert_equal(s.se.any_int(expr), 0x41414141) nose.tools.assert_true(s.se.unique(expr)) c = s.BV('condition', 8) expr = s.memory.load(10, 1, condition=c == 1, fallback=s.BVV('X')) nose.tools.assert_equal( s.se.any_n_str(expr, 10, extra_constraints=[c == 1]), ['B']) nose.tools.assert_equal( s.se.any_n_str(expr, 10, extra_constraints=[c != 1]), ['X']) x = s.BV('ref_test', 16, explicit_name=True) s.memory.store(0x1000, x) s.memory.store(0x2000, x) nose.tools.assert_equal(set(s.memory.addrs_for_name('ref_test')), set((0x1000, 0x1001, 0x2000, 0x2001))) nose.tools.assert_equal(set(s.memory.addrs_for_hash(hash(x))), set((0x1000, 0x1001, 0x2000, 0x2001))) s2 = s.copy() y = s2.BV('ref_test2', 16, explicit_name=True) s2.memory.store(0x2000, y) nose.tools.assert_equal(set(s.memory.addrs_for_name('ref_test')), set((0x1000, 0x1001, 0x2000, 0x2001))) nose.tools.assert_equal(set(s.memory.addrs_for_hash(hash(x))), set((0x1000, 0x1001, 0x2000, 0x2001))) nose.tools.assert_equal(set(s2.memory.addrs_for_name('ref_test')), set((0x1000, 0x1001))) nose.tools.assert_equal(set(s2.memory.addrs_for_hash(hash(x))), set((0x1000, 0x1001))) nose.tools.assert_equal(set(s2.memory.addrs_for_name('ref_test2')), set((0x2000, 0x2001))) nose.tools.assert_equal(set(s2.memory.addrs_for_hash(hash(y))), set((0x2000, 0x2001))) s.memory.store(0x3000, s.BV('replace_old', 32, explicit_name=True)) s.memory.store(0x3001, s.BVV('AB')) nose.tools.assert_equal(set(s.memory.addrs_for_name('replace_old')), set((0x3000, 0x3003))) nose.tools.assert_equal(s.se.any_n_str(s.memory.load(0x3001, 2), 10), ["AB"]) n = s.BV('replace_new', 32, explicit_name=True) c = s.BV('replace_cool', 32, explicit_name=True) mo = s.memory.memory_objects_for_name('replace_old') nose.tools.assert_equal(len(mo), 1) s.memory.replace_memory_object(next(iter(mo)), n) nose.tools.assert_equal(set(s.memory.addrs_for_name('replace_old')), set()) nose.tools.assert_equal(set(s.memory.addrs_for_name('replace_new')), set((0x3000, 0x3003))) nose.tools.assert_equal(s.se.any_n_str(s.memory.load(0x3001, 2), 10), ["AB"]) s.memory.store(0x4000, s.se.If(n == 0, n + 10, n + 20)) nose.tools.assert_equal( set(s.memory.addrs_for_name('replace_new')), set((0x3000, 0x3003, 0x4000, 0x4001, 0x4002, 0x4003))) s.memory.replace_all(n, c) nose.tools.assert_equal(set(s.memory.addrs_for_name('replace_old')), set()) nose.tools.assert_equal(set(s.memory.addrs_for_name('replace_new')), set()) nose.tools.assert_equal( set(s.memory.addrs_for_name('replace_cool')), set((0x3000, 0x3003, 0x4000, 0x4001, 0x4002, 0x4003))) nose.tools.assert_equal(s.se.any_n_str(s.memory.load(0x3001, 2), 10), ["AB"]) z = s.BVV(0, 32) s.memory.replace_all(c, z) nose.tools.assert_equal(set(s.memory.addrs_for_name('replace_old')), set()) nose.tools.assert_equal(set(s.memory.addrs_for_name('replace_new')), set()) nose.tools.assert_equal(set(s.memory.addrs_for_name('replace_cool')), set()) nose.tools.assert_equal(s.se.any_n_str(s.memory.load(0x3001, 2), 10), ["AB"]) nose.tools.assert_equal(s.se.any_n_int(s.memory.load(0x3000, 4), 10), [0x00414200]) nose.tools.assert_equal(s.se.any_n_int(s.memory.load(0x4000, 4), 10), [0x0000000a]) # symbolic length x = s.BVV(0x11223344, 32) y = s.BVV(0xAABBCCDD, 32) n = s.BV('size', 32) s.memory.store(0x5000, x) s.memory.store(0x5000, y, size=n) nose.tools.assert_equal( set(s.se.any_n_int(s.memory.load(0x5000, 4), 10)), {0x11223344, 0xAA223344, 0xAABB3344, 0xAABBCC44, 0xAABBCCDD}) s1 = s.copy() s1.add_constraints(n == 1) nose.tools.assert_equal( set(s1.se.any_n_int(s1.memory.load(0x5000, 4), 10)), {0xAA223344}) s4 = s.copy() s4.add_constraints(n == 4) nose.tools.assert_equal( set(s4.se.any_n_int(s4.memory.load(0x5000, 4), 10)), {0xAABBCCDD}) # condition without fallback x = s.BVV(0x11223344, 32) y = s.BVV(0xAABBCCDD, 32) c = s.BV('condition', 32) s.memory.store(0x6000, x) s.memory.store(0x6000, y, condition=c == 1) nose.tools.assert_equal(set(s.se.any_n_int(s.memory.load(0x6000, 4), 10)), {0x11223344, 0xAABBCCDD}) s0 = s.copy() s0.add_constraints(c == 0) nose.tools.assert_equal( set(s0.se.any_n_int(s0.memory.load(0x6000, 4), 10)), {0x11223344}) s1 = s.copy() s1.add_constraints(c == 1) nose.tools.assert_equal( set(s1.se.any_n_int(s1.memory.load(0x6000, 4), 10)), {0xAABBCCDD}) # condition with symbolic size x = s.BVV(0x11223344, 32) y = s.BVV(0xAABBCCDD, 32) c = s.BV('condition', 32) n = s.BV('size', 32) s.memory.store(0x8000, x) s.memory.store(0x8000, y, condition=c == 1, size=n) s0 = s.copy() s0.add_constraints(c == 0) nose.tools.assert_equal( set(s0.se.any_n_int(s0.memory.load(0x8000, 4), 10)), {0x11223344}) s1 = s.copy() s1.add_constraints(c == 1) nose.tools.assert_equal( set(s1.se.any_n_int(s1.memory.load(0x8000, 4), 10)), {0x11223344, 0xAA223344, 0xAABB3344, 0xAABBCC44, 0xAABBCCDD})
def test_memcmp(): l.info("concrete src, concrete dst, concrete len") l.debug("... full cmp") s = SimState(arch="AMD64", mode="symbolic") dst = s.se.BitVecVal(0x41414141, 32) dst_addr = s.se.BitVecVal(0x1000, 64) src = s.se.BitVecVal(0x42424242, 32) src_addr = s.se.BitVecVal(0x2000, 64) s.memory.store(dst_addr, dst) s.memory.store(src_addr, src) r = memcmp(s, inline=True, arguments=[dst_addr, src_addr, s.BVV(4, 64)]).ret_expr nose.tools.assert_true(s.satisfiable()) s_pos = s.copy() s_pos.add_constraints(r.SGE(0)) nose.tools.assert_false(s_pos.satisfiable()) s_neg = s.copy() s_neg.add_constraints(r.SLT(0)) nose.tools.assert_true(s_neg.satisfiable()) l.debug("... zero cmp") s = SimState(arch="AMD64", mode="symbolic") s.memory.store(dst_addr, dst) s.memory.store(src_addr, src) r = memcmp(s, inline=True, arguments=[dst_addr, src_addr, s.se.BitVecVal(0, 64)]).ret_expr nose.tools.assert_equals(s.se.any_n_int(r, 2), [0]) l.info("symbolic src, concrete dst, concrete len") s = SimState(arch="AMD64", mode="symbolic") dst = s.se.BitVecVal(0x41414141, 32) dst_addr = s.se.BitVecVal(0x1000, 64) src = s.BV("src", 32) src_addr = s.se.BitVecVal(0x2000, 64) s.memory.store(dst_addr, dst) s.memory.store(src_addr, src) # make sure it copies it all r = memcmp(s, inline=True, arguments=[dst_addr, src_addr, s.se.BitVecVal(4, 64)]).ret_expr s_match = s.copy() s_match.add_constraints(r == 0) m = s_match.memory.load(src_addr, 4) nose.tools.assert_equal(s_match.se.any_n_int(m, 2), [0x41414141]) s_nomatch = s.copy() s_nomatch.add_constraints(r != 0) m = s_nomatch.memory.load(src_addr, 4) nose.tools.assert_false(s_nomatch.se.solution(m, 0x41414141)) l.info("symbolic src, concrete dst, symbolic len") s = SimState(arch="AMD64", mode="symbolic") dst = s.se.BitVecVal(0x41414141, 32) dst_addr = s.se.BitVecVal(0x1000, 64) src = s.BV("src", 32) src_addr = s.se.BitVecVal(0x2000, 64) cmplen = s.BV("len", 64) s.memory.store(dst_addr, dst) s.memory.store(src_addr, src) r = memcmp(s, inline=True, arguments=[dst_addr, src_addr, cmplen]).ret_expr # look at effects of different lengths s1 = s.copy() s1.add_constraints(cmplen == 1) s1.add_constraints(r == 0) l.debug("... simplifying") s1.se._solver.simplify() l.debug("... solving") nose.tools.assert_equals(s1.se.any_n_int(src[31:24], 2), [0x41]) nose.tools.assert_false(s1.se.unique(src[31:16])) l.debug("... solved") s2 = s.copy() s2.add_constraints(cmplen == 2) s2.add_constraints(r == 0) nose.tools.assert_equals(s2.se.any_n_int(s2.memory.load(src_addr, 2), 2), [0x4141]) nose.tools.assert_false(s2.se.unique(s2.memory.load(src_addr, 3))) s2u = s.copy() s2u.add_constraints(cmplen == 2) s2u.add_constraints(r == 1) nose.tools.assert_false( s2u.se.solution(s2u.memory.load(src_addr, 2), 0x4141))