def test_aarch64_32bit_ccalls(): # GitHub issue #1238 s = SimState(arch="AArch64") x = s.solver.BVS("x", 32) # A normal operation flag_z, _ = s_ccall.arm64g_calculate_flag_z(s, s_ccall.ARM64G_CC_OP_ADD32, x, s.solver.BVV(1, 32), 0) nose.tools.assert_true(s.satisfiable(extra_constraints=(flag_z == 0,))) nose.tools.assert_true(s.satisfiable(extra_constraints=(flag_z == 1,))) # What VEX does flag_z, _ = s_ccall.arm64g_calculate_flag_z(s, s_ccall.ARM64G_CC_OP_ADD32, x.zero_extend(32), s.solver.BVV(1, 64), 0) nose.tools.assert_true(s.satisfiable(extra_constraints=(flag_z == 0,))) nose.tools.assert_true(s.satisfiable(extra_constraints=(flag_z == 1,)))
def test_aarch64_32bit_ccalls(): # GitHub issue #1238 s = SimState(arch="AArch64") x = s.solver.BVS("x", 32) # A normal operation flag_z = s_ccall.arm64g_calculate_flag_z(s, s_ccall.ARM64G_CC_OP_ADD32, x, s.solver.BVV(1, 32), 0) nose.tools.assert_true(s.satisfiable(extra_constraints=(flag_z == 0,))) nose.tools.assert_true(s.satisfiable(extra_constraints=(flag_z == 1,))) # What VEX does flag_z = s_ccall.arm64g_calculate_flag_z(s, s_ccall.ARM64G_CC_OP_ADD32, x.zero_extend(32), s.solver.BVV(1, 64), 0) nose.tools.assert_true(s.satisfiable(extra_constraints=(flag_z == 0,))) nose.tools.assert_true(s.satisfiable(extra_constraints=(flag_z == 1,)))
def test_inline_strncmp(): l.info("symbolic left, symbolic right, symbolic len") s = SimState(arch="AMD64", mode="symbolic") left = s.solver.BVS("left", 32) left_addr = s.solver.BVV(0x1000, 64) right = s.solver.BVS("right", 32) right_addr = s.solver.BVV(0x2000, 64) maxlen = s.solver.BVS("len", 64) s.memory.store(left_addr, left) s.memory.store(right_addr, right) s.add_constraints(strlen(s, arguments=[left_addr]) == 3) s.add_constraints(strlen(s, arguments=[right_addr]) == 0) s.add_constraints(maxlen != 0) c = strncmp(s, arguments=[left_addr, right_addr, maxlen]) s_match = s.copy() s_match.add_constraints(c == 0) nose.tools.assert_false(s_match.satisfiable()) #nose.tools.assert_equal(s_match.solver.min_int(maxlen), 3) s_nomatch = s.copy() s_nomatch.add_constraints(c != 0) nose.tools.assert_true(s_nomatch.satisfiable()) #nose.tools.assert_equal(s_nomatch.solver.max_int(maxlen), 2) l.info("zero-length") s = SimState(arch="AMD64", mode="symbolic") left = s.solver.BVS("left", 32) left_addr = s.solver.BVV(0x1000, 64) right = s.solver.BVS("right", 32) right_addr = s.solver.BVV(0x2000, 64) maxlen = s.solver.BVS("len", 64) left_len = strlen(s, arguments=[left_addr]) right_len = strlen(s, arguments=[right_addr]) c = strncmp(s, arguments=[left_addr, right_addr, maxlen]) s.add_constraints(right_len == 0) s.add_constraints(left_len == 0) #s.add_constraints(c == 0) s.add_constraints(maxlen == 0) nose.tools.assert_true(s.satisfiable())
def test_inline_strncmp(): l.info("symbolic left, symbolic right, symbolic len") s = SimState(arch="AMD64", mode="symbolic") left = s.solver.BVS("left", 32) left_addr = s.solver.BVV(0x1000, 64) right = s.solver.BVS("right", 32) right_addr = s.solver.BVV(0x2000, 64) maxlen = s.solver.BVS("len", 64) s.memory.store(left_addr, left) s.memory.store(right_addr, right) s.add_constraints(strlen(s, arguments=[left_addr]) == 3) s.add_constraints(strlen(s, arguments=[right_addr]) == 0) s.add_constraints(maxlen != 0) c = strncmp(s, arguments=[left_addr, right_addr, maxlen]) s_match = s.copy() s_match.add_constraints(c == 0) nose.tools.assert_false(s_match.satisfiable()) #nose.tools.assert_equal(s_match.solver.min_int(maxlen), 3) s_nomatch = s.copy() s_nomatch.add_constraints(c != 0) nose.tools.assert_true(s_nomatch.satisfiable()) #nose.tools.assert_equal(s_nomatch.solver.max_int(maxlen), 2) l.info("zero-length") s = SimState(arch="AMD64", mode="symbolic") left = s.solver.BVS("left", 32) left_addr = s.solver.BVV(0x1000, 64) right = s.solver.BVS("right", 32) right_addr = s.solver.BVV(0x2000, 64) maxlen = s.solver.BVS("len", 64) left_len = strlen(s, arguments=[left_addr]) right_len = strlen(s, arguments=[right_addr]) c = strncmp(s, arguments=[left_addr, right_addr, maxlen]) s.add_constraints(right_len == 0) s.add_constraints(left_len == 0) #s.add_constraints(c == 0) s.add_constraints(maxlen == 0) nose.tools.assert_true(s.satisfiable())
def test_strstr_inconsistency(): l.info("symbolic haystack, symbolic needle") s = SimState(arch="AMD64", mode="symbolic") s.libc.buf_symbolic_bytes = 2 addr_haystack = s.solver.BVV(0x10, 64) addr_needle = s.solver.BVV(0xb0, 64) #len_needle = strlen(s, inline=True, arguments=[addr_needle]) ss_res = strstr(s, arguments=[addr_haystack, addr_needle]) #slh_res = strlen(s, inline=True, arguments=[addr_haystack]) #sln_res = strlen(s, inline=True, arguments=[addr_needle]) #print "LENH:", s.solver.eval_upto(slh_res, 100) #print "LENN:", s.solver.eval_upto(sln_res, 100) assert not s.solver.unique(ss_res) assert sorted(s.solver.eval_upto(ss_res, 100)) == [0] + list(range(0x10, 0x10 + s.libc.buf_symbolic_bytes - 1)) s.add_constraints(ss_res != 0) ss2 = strstr(s, arguments=[addr_haystack, addr_needle]) s.add_constraints(ss2 == 0) assert not s.satisfiable()
def test_strstr_inconsistency(): l.info("symbolic haystack, symbolic needle") s = SimState(arch="AMD64", mode="symbolic") s.libc.buf_symbolic_bytes = 2 addr_haystack = s.solver.BVV(0x10, 64) addr_needle = s.solver.BVV(0xb0, 64) #len_needle = strlen(s, inline=True, arguments=[addr_needle]) ss_res = strstr(s, arguments=[addr_haystack, addr_needle]) #slh_res = strlen(s, inline=True, arguments=[addr_haystack]) #sln_res = strlen(s, inline=True, arguments=[addr_needle]) #print "LENH:", s.solver.eval_upto(slh_res, 100) #print "LENN:", s.solver.eval_upto(sln_res, 100) nose.tools.assert_false(s.solver.unique(ss_res)) nose.tools.assert_sequence_equal(sorted(s.solver.eval_upto(ss_res, 100)), [0] + list(range(0x10, 0x10 + s.libc.buf_symbolic_bytes - 1))) s.add_constraints(ss_res != 0) ss2 = strstr(s, arguments=[addr_haystack, addr_needle]) s.add_constraints(ss2 == 0) nose.tools.assert_false(s.satisfiable())
def test_strstr_inconsistency(n=2): l.info("symbolic haystack, symbolic needle") s = SimState(arch="AMD64", mode="symbolic") s.libc.buf_symbolic_bytes = n addr_haystack = s.se.BVV(0x10, 64) addr_needle = s.se.BVV(0xb0, 64) #len_needle = strlen(s, inline=True, arguments=[addr_needle]) ss_res = strstr(s, arguments=[addr_haystack, addr_needle]).ret_expr #slh_res = strlen(s, inline=True, arguments=[addr_haystack]).ret_expr #sln_res = strlen(s, inline=True, arguments=[addr_needle]).ret_expr #print "LENH:", s.se.any_n_int(slh_res, 100) #print "LENN:", s.se.any_n_int(sln_res, 100) nose.tools.assert_false(s.se.unique(ss_res)) nose.tools.assert_items_equal(s.se.any_n_int( ss_res, 100), [0] + range(0x10, 0x10 + s.libc.buf_symbolic_bytes - 1)) s.add_constraints(ss_res != 0) ss2 = strstr(s, arguments=[addr_haystack, addr_needle]).ret_expr s.add_constraints(ss2 == 0) nose.tools.assert_false(s.satisfiable())
def test_strncpy(): l.info("concrete src, concrete dst, concrete len") l.debug("... full copy") s = SimState(arch="AMD64", mode="symbolic") dst = s.solver.BVV(0x41414100, 32) dst_addr = s.solver.BVV(0x1000, 64) src = s.solver.BVV(0x42420000, 32) src_addr = s.solver.BVV(0x2000, 64) s.memory.store(dst_addr, dst) s.memory.store(src_addr, src) strncpy(s, arguments=[dst_addr, src_addr, s.solver.BVV(3, 64)]) new_dst = s.memory.load(dst_addr, 4, endness='Iend_BE') nose.tools.assert_equal(s.solver.eval(new_dst, cast_to=bytes), b"BB\x00\x00") l.debug("... partial copy") s = SimState(arch="AMD64", mode="symbolic") s.memory.store(dst_addr, dst) s.memory.store(src_addr, src) strncpy(s, arguments=[dst_addr, src_addr, s.solver.BVV(2, 64)]) new_dst = s.memory.load(dst_addr, 4, endness='Iend_BE') nose.tools.assert_equal(s.solver.eval_upto(new_dst, 2, cast_to=bytes), [b"BBA\x00"]) l.info("symbolic src, concrete dst, concrete len") s = SimState(arch="AMD64", mode="symbolic") dst = s.solver.BVV(0x41414100, 32) dst_addr = s.solver.BVV(0x1000, 64) src = s.solver.BVS("src", 32) src_addr = s.solver.BVV(0x2000, 64) s.memory.store(dst_addr, dst) s.memory.store(src_addr, src) # make sure it copies it all s.add_constraints(strlen(s, arguments=[src_addr]) == 2) # sanity check s_false = s.copy() s_false.add_constraints(strlen(s_false, arguments=[src_addr]) == 3) nose.tools.assert_false(s_false.satisfiable()) strncpy(s, arguments=[dst_addr, src_addr, 3]) nose.tools.assert_true(s.satisfiable()) c = strcmp(s, arguments=[dst_addr, src_addr]) nose.tools.assert_sequence_equal(s.solver.eval_upto(c, 10), [0]) l.info("symbolic src, concrete dst, symbolic len") s = SimState(arch="AMD64", mode="symbolic") dst = s.solver.BVV(0x41414100, 32) dst_addr = s.solver.BVV(0x1000, 64) src = s.solver.BVS("src", 32) src_addr = s.solver.BVV(0x2000, 64) maxlen = s.solver.BVS("len", 64) s.memory.store(dst_addr, dst) s.memory.store(src_addr, src) # make sure it copies it all s.add_constraints(strlen(s, arguments=[src_addr]) == 2) strncpy(s, arguments=[dst_addr, src_addr, maxlen]) c = strcmp(s, arguments=[dst_addr, src_addr]) s_match = s.copy() s_match.add_constraints(c == 0) nose.tools.assert_equal(s_match.solver.min_int(maxlen), 3) s_nomatch = s.copy() s_nomatch.add_constraints(c != 0) nose.tools.assert_equal(s_nomatch.solver.max_int(maxlen), 2) l.info("concrete src, concrete dst, symbolic len") l.debug("... full copy") s = SimState(arch="AMD64", mode="symbolic") dst = s.solver.BVV(0x41414100, 32) dst_addr = s.solver.BVV(0x1000, 64) src = s.solver.BVV(0x42420000, 32) src_addr = s.solver.BVV(0x2000, 64) maxlen = s.solver.BVS("len", 64) s.memory.store(dst_addr, dst) s.memory.store(src_addr, src) strncpy(s, arguments=[dst_addr, src_addr, maxlen]) r = s.memory.load(dst_addr, 4, endness='Iend_BE') #print repr(r.solver.eval_upto(r, 10, cast_to=bytes)) nose.tools.assert_sequence_equal( sorted(s.solver.eval_upto(r, 10, cast_to=bytes)), [b"AAA\x00", b'BAA\x00', b'BB\x00\x00', b'BBA\x00'])
def test_memcmp(): l.info("concrete src, concrete dst, concrete len") l.debug("... full cmp") s = SimState(arch="AMD64", mode="symbolic") dst = s.solver.BVV(0x41414141, 32) dst_addr = s.solver.BVV(0x1000, 64) src = s.solver.BVV(0x42424242, 32) src_addr = s.solver.BVV(0x2000, 64) s.memory.store(dst_addr, dst) s.memory.store(src_addr, src) r = memcmp(s, arguments=[dst_addr, src_addr, s.solver.BVV(4, 64)]) 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, arguments=[dst_addr, src_addr, s.solver.BVV(0, 64)]) nose.tools.assert_equal(s.solver.eval_upto(r, 2), [0]) l.info("symbolic src, concrete dst, concrete len") s = SimState(arch="AMD64", mode="symbolic") dst = s.solver.BVV(0x41414141, 32) dst_addr = s.solver.BVV(0x1000, 64) src = s.solver.BVS("src", 32) src_addr = s.solver.BVV(0x2000, 64) s.memory.store(dst_addr, dst) s.memory.store(src_addr, src) # make sure it copies it all r = memcmp(s, arguments=[dst_addr, src_addr, s.solver.BVV(4, 64)]) s_match = s.copy() s_match.add_constraints(r == 0) m = s_match.memory.load(src_addr, 4) nose.tools.assert_equal(s_match.solver.eval_upto(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.solver.solution(m, 0x41414141)) l.info("symbolic src, concrete dst, symbolic len") s = SimState(arch="AMD64", mode="symbolic") dst = s.solver.BVV(0x41414141, 32) dst_addr = s.solver.BVV(0x1000, 64) src = s.solver.BVS("src", 32) src_addr = s.solver.BVV(0x2000, 64) cmplen = s.solver.BVS("len", 64) s.memory.store(dst_addr, dst) s.memory.store(src_addr, src) r = memcmp(s, arguments=[dst_addr, src_addr, cmplen]) # look at effects of different lengths s1 = s.copy() s1.add_constraints(cmplen == 1) s1.add_constraints(r == 0) l.debug("... simplifying") s1.solver._solver.simplify() l.debug("... solving") nose.tools.assert_equal(s1.solver.eval_upto(src[31:24], 2), [0x41]) nose.tools.assert_false(s1.solver.unique(src[31:16])) l.debug("... solved") s2 = s.copy() s2.add_constraints(cmplen == 2) s2.add_constraints(r == 0) nose.tools.assert_equal( s2.solver.eval_upto(s2.memory.load(src_addr, 2), 2), [0x4141]) nose.tools.assert_false(s2.solver.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.solver.solution(s2u.memory.load(src_addr, 2), 0x4141))
def test_memcpy(): l.info("concrete src, concrete dst, concrete len") l.debug("... full copy") s = SimState(arch="AMD64", mode="symbolic") dst = s.solver.BVV(0x41414141, 32) dst_addr = s.solver.BVV(0x1000, 64) src = s.solver.BVV(0x42424242, 32) src_addr = s.solver.BVV(0x2000, 64) s.memory.store(dst_addr, dst) s.memory.store(src_addr, src) memcpy(s, arguments=[dst_addr, src_addr, s.solver.BVV(4, 64)]) new_dst = s.memory.load(dst_addr, 4, endness='Iend_BE') nose.tools.assert_equal(s.solver.eval_upto(new_dst, 2, cast_to=bytes), [b"BBBB"]) l.info("giant copy") s = SimState(arch="AMD64", mode="symbolic", remove_options=angr.options.simplification) s.memory._maximum_symbolic_size = 0x2000000 size = s.solver.BVV(0x1000000, 64) data = s.solver.BVS('giant', 8 * 0x1000000) dst_addr = s.solver.BVV(0x2000000, 64) src_addr = s.solver.BVV(0x4000000, 64) s.memory.store(src_addr, data) memcpy(s, arguments=[dst_addr, src_addr, size]) nose.tools.assert_is(s.memory.load(dst_addr, size), s.memory.load(src_addr, size)) l.debug("... partial copy") s = SimState(arch="AMD64", mode="symbolic") s.memory.store(dst_addr, dst) s.memory.store(src_addr, src) memcpy(s, arguments=[dst_addr, src_addr, s.solver.BVV(2, 64)]) new_dst = s.memory.load(dst_addr, 4, endness='Iend_BE') nose.tools.assert_equal(s.solver.eval_upto(new_dst, 2, cast_to=bytes), [b"BBAA"]) l.info("symbolic src, concrete dst, concrete len") s = SimState(arch="AMD64", mode="symbolic") dst = s.solver.BVV(0x41414141, 32) dst_addr = s.solver.BVV(0x1000, 64) src = s.solver.BVS("src", 32) src_addr = s.solver.BVV(0x2000, 64) s.memory.store(dst_addr, dst) s.memory.store(src_addr, src) # make sure it copies it all memcpy(s, arguments=[dst_addr, src_addr, s.solver.BVV(4, 64)]) nose.tools.assert_true(s.satisfiable()) s.add_constraints(src != s.memory.load(dst_addr, 4)) nose.tools.assert_false(s.satisfiable()) l.info("symbolic src, concrete dst, symbolic len") s = SimState(arch="AMD64", mode="symbolic") dst = s.solver.BVV(0x41414141, 32) dst_addr = s.solver.BVV(0x1000, 64) src = s.solver.BVS("src", 32) src_addr = s.solver.BVV(0x2000, 64) cpylen = s.solver.BVS("len", 64) s.memory.store(dst_addr, dst) s.memory.store(src_addr, src) s.add_constraints(cpylen < 10) memcpy(s, arguments=[dst_addr, src_addr, cpylen]) result = s.memory.load(dst_addr, 4, endness='Iend_BE') # make sure it copies it all s1 = s.copy() s1.add_constraints(cpylen == 1) nose.tools.assert_true(s1.solver.unique(s1.memory.load(dst_addr + 1, 3))) nose.tools.assert_equal( len(s1.solver.eval_upto(s1.memory.load(dst_addr, 1), 300)), 256) s2 = s.copy() s2.add_constraints(cpylen == 2) nose.tools.assert_equal(len(s2.solver.eval_upto(result[31:24], 300)), 256) nose.tools.assert_equal(len(s2.solver.eval_upto(result[23:16], 300)), 256) nose.tools.assert_equal( s2.solver.eval_upto(result[15:0], 300, cast_to=bytes), [b'AA']) l.info("concrete src, concrete dst, symbolic len") dst = s2.solver.BVV(0x41414141, 32) dst_addr = s2.solver.BVV(0x1000, 64) src = s2.solver.BVV(0x42424242, 32) src_addr = s2.solver.BVV(0x2000, 64) s = SimState(arch="AMD64", mode="symbolic") s.memory.store(dst_addr, dst) s.memory.store(src_addr, src) cpylen = s.solver.BVS("len", 64) s.add_constraints(s.solver.ULE(cpylen, 4)) memcpy(s, arguments=[dst_addr, src_addr, cpylen]) new_dst = s.memory.load(dst_addr, 4, endness='Iend_BE') nose.tools.assert_sequence_equal( sorted(s.solver.eval_upto(new_dst, 300, cast_to=bytes)), [b'AAAA', b'BAAA', b'BBAA', b'BBBA', b'BBBB'])
def test_strncpy(): l.info("concrete src, concrete dst, concrete len") l.debug("... full copy") s = SimState(arch="AMD64", mode="symbolic") dst = s.solver.BVV(0x41414100, 32) dst_addr = s.solver.BVV(0x1000, 64) src = s.solver.BVV(0x42420000, 32) src_addr = s.solver.BVV(0x2000, 64) s.memory.store(dst_addr, dst) s.memory.store(src_addr, src) strncpy(s, arguments=[dst_addr, src_addr, s.solver.BVV(3, 64)]) new_dst = s.memory.load(dst_addr, 4, endness='Iend_BE') nose.tools.assert_equal(s.solver.eval(new_dst, cast_to=bytes), b"BB\x00\x00") l.debug("... partial copy") s = SimState(arch="AMD64", mode="symbolic") s.memory.store(dst_addr, dst) s.memory.store(src_addr, src) strncpy(s, arguments=[dst_addr, src_addr, s.solver.BVV(2, 64)]) new_dst = s.memory.load(dst_addr, 4, endness='Iend_BE') nose.tools.assert_equal(s.solver.eval_upto(new_dst, 2, cast_to=bytes), [ b"BBA\x00" ]) l.info("symbolic src, concrete dst, concrete len") s = SimState(arch="AMD64", mode="symbolic") dst = s.solver.BVV(0x41414100, 32) dst_addr = s.solver.BVV(0x1000, 64) src = s.solver.BVS("src", 32) src_addr = s.solver.BVV(0x2000, 64) s.memory.store(dst_addr, dst) s.memory.store(src_addr, src) # make sure it copies it all s.add_constraints(strlen(s, arguments=[src_addr]) == 2) # sanity check s_false = s.copy() s_false.add_constraints(strlen(s_false, arguments=[src_addr]) == 3) nose.tools.assert_false(s_false.satisfiable()) strncpy(s, arguments=[dst_addr, src_addr, 3]) nose.tools.assert_true(s.satisfiable()) c = strcmp(s, arguments=[dst_addr, src_addr]) nose.tools.assert_sequence_equal(s.solver.eval_upto(c, 10), [0]) l.info("symbolic src, concrete dst, symbolic len") s = SimState(arch="AMD64", mode="symbolic") dst = s.solver.BVV(0x41414100, 32) dst_addr = s.solver.BVV(0x1000, 64) src = s.solver.BVS("src", 32) src_addr = s.solver.BVV(0x2000, 64) maxlen = s.solver.BVS("len", 64) s.memory.store(dst_addr, dst) s.memory.store(src_addr, src) # make sure it copies it all s.add_constraints(strlen(s, arguments=[src_addr]) == 2) strncpy(s, arguments=[dst_addr, src_addr, maxlen]) c = strcmp(s, arguments=[dst_addr, src_addr]) s_match = s.copy() s_match.add_constraints(c == 0) nose.tools.assert_equal(s_match.solver.min_int(maxlen), 3) s_nomatch = s.copy() s_nomatch.add_constraints(c != 0) nose.tools.assert_equal(s_nomatch.solver.max_int(maxlen), 2) l.info("concrete src, concrete dst, symbolic len") l.debug("... full copy") s = SimState(arch="AMD64", mode="symbolic") dst = s.solver.BVV(0x41414100, 32) dst_addr = s.solver.BVV(0x1000, 64) src = s.solver.BVV(0x42420000, 32) src_addr = s.solver.BVV(0x2000, 64) maxlen = s.solver.BVS("len", 64) s.memory.store(dst_addr, dst) s.memory.store(src_addr, src) strncpy(s, arguments=[dst_addr, src_addr, maxlen]) r = s.memory.load(dst_addr, 4, endness='Iend_BE') #print repr(r.solver.eval_upto(r, 10, cast_to=bytes)) nose.tools.assert_sequence_equal(sorted(s.solver.eval_upto(r, 10, cast_to=bytes)), [ b"AAA\x00", b'BAA\x00', b'BB\x00\x00', b'BBA\x00' ] )
def test_memcmp(): l.info("concrete src, concrete dst, concrete len") l.debug("... full cmp") s = SimState(arch="AMD64", mode="symbolic") dst = s.solver.BVV(0x41414141, 32) dst_addr = s.solver.BVV(0x1000, 64) src = s.solver.BVV(0x42424242, 32) src_addr = s.solver.BVV(0x2000, 64) s.memory.store(dst_addr, dst) s.memory.store(src_addr, src) r = memcmp(s, arguments=[dst_addr, src_addr, s.solver.BVV(4, 64)]) 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, arguments=[dst_addr, src_addr, s.solver.BVV(0, 64)]) nose.tools.assert_equal(s.solver.eval_upto(r, 2), [ 0 ]) l.info("symbolic src, concrete dst, concrete len") s = SimState(arch="AMD64", mode="symbolic") dst = s.solver.BVV(0x41414141, 32) dst_addr = s.solver.BVV(0x1000, 64) src = s.solver.BVS("src", 32) src_addr = s.solver.BVV(0x2000, 64) s.memory.store(dst_addr, dst) s.memory.store(src_addr, src) # make sure it copies it all r = memcmp(s, arguments=[dst_addr, src_addr, s.solver.BVV(4, 64)]) s_match = s.copy() s_match.add_constraints(r == 0) m = s_match.memory.load(src_addr, 4) nose.tools.assert_equal(s_match.solver.eval_upto(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.solver.solution(m, 0x41414141)) l.info("symbolic src, concrete dst, symbolic len") s = SimState(arch="AMD64", mode="symbolic") dst = s.solver.BVV(0x41414141, 32) dst_addr = s.solver.BVV(0x1000, 64) src = s.solver.BVS("src", 32) src_addr = s.solver.BVV(0x2000, 64) cmplen = s.solver.BVS("len", 64) s.memory.store(dst_addr, dst) s.memory.store(src_addr, src) r = memcmp(s, arguments=[dst_addr, src_addr, cmplen]) # look at effects of different lengths s1 = s.copy() s1.add_constraints(cmplen == 1) s1.add_constraints(r == 0) l.debug("... simplifying") s1.solver._solver.simplify() l.debug("... solving") nose.tools.assert_equal(s1.solver.eval_upto(src[31:24], 2), [ 0x41 ]) nose.tools.assert_false(s1.solver.unique(src[31:16])) l.debug("... solved") s2 = s.copy() s2.add_constraints(cmplen == 2) s2.add_constraints(r == 0) nose.tools.assert_equal(s2.solver.eval_upto(s2.memory.load(src_addr, 2), 2), [ 0x4141 ]) nose.tools.assert_false(s2.solver.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.solver.solution(s2u.memory.load(src_addr, 2), 0x4141))
def test_memcpy(): l.info("concrete src, concrete dst, concrete len") l.debug("... full copy") s = SimState(arch="AMD64", mode="symbolic") dst = s.solver.BVV(0x41414141, 32) dst_addr = s.solver.BVV(0x1000, 64) src = s.solver.BVV(0x42424242, 32) src_addr = s.solver.BVV(0x2000, 64) s.memory.store(dst_addr, dst) s.memory.store(src_addr, src) memcpy(s, arguments=[dst_addr, src_addr, s.solver.BVV(4, 64)]) new_dst = s.memory.load(dst_addr, 4, endness='Iend_BE') nose.tools.assert_equal(s.solver.eval_upto(new_dst, 2, cast_to=bytes), [ b"BBBB" ]) l.info("giant copy") s = SimState(arch="AMD64", mode="symbolic", remove_options=angr.options.simplification) s.memory._maximum_symbolic_size = 0x2000000 size = s.solver.BVV(0x1000000, 64) dst_addr = s.solver.BVV(0x2000000, 64) src_addr = s.solver.BVV(0x4000000, 64) memcpy(s, arguments=[dst_addr, src_addr, size]) nose.tools.assert_is(s.memory.load(dst_addr, size), s.memory.load(src_addr, size)) l.debug("... partial copy") s = SimState(arch="AMD64", mode="symbolic") s.memory.store(dst_addr, dst) s.memory.store(src_addr, src) memcpy(s, arguments=[dst_addr, src_addr, s.solver.BVV(2, 64)]) new_dst = s.memory.load(dst_addr, 4, endness='Iend_BE') nose.tools.assert_equal(s.solver.eval_upto(new_dst, 2, cast_to=bytes), [ b"BBAA" ]) l.info("symbolic src, concrete dst, concrete len") s = SimState(arch="AMD64", mode="symbolic") dst = s.solver.BVV(0x41414141, 32) dst_addr = s.solver.BVV(0x1000, 64) src = s.solver.BVS("src", 32) src_addr = s.solver.BVV(0x2000, 64) s.memory.store(dst_addr, dst) s.memory.store(src_addr, src) # make sure it copies it all memcpy(s, arguments=[dst_addr, src_addr, s.solver.BVV(4, 64)]) nose.tools.assert_true(s.satisfiable()) s.add_constraints(src != s.memory.load(dst_addr, 4)) nose.tools.assert_false(s.satisfiable()) l.info("symbolic src, concrete dst, symbolic len") s = SimState(arch="AMD64", mode="symbolic") dst = s.solver.BVV(0x41414141, 32) dst_addr = s.solver.BVV(0x1000, 64) src = s.solver.BVS("src", 32) src_addr = s.solver.BVV(0x2000, 64) cpylen = s.solver.BVS("len", 64) s.memory.store(dst_addr, dst) s.memory.store(src_addr, src) memcpy(s, arguments=[dst_addr, src_addr, cpylen]) result = s.memory.load(dst_addr, 4, endness='Iend_BE') # make sure it copies it all s1 = s.copy() s1.add_constraints(cpylen == 1) nose.tools.assert_true(s1.solver.unique(s1.memory.load(dst_addr+1, 3))) nose.tools.assert_equal(len(s1.solver.eval_upto(s1.memory.load(dst_addr, 1), 300)), 256) s2 = s.copy() s2.add_constraints(cpylen == 2) nose.tools.assert_equal(len(s2.solver.eval_upto(result[31:24], 300)), 256) nose.tools.assert_equal(len(s2.solver.eval_upto(result[23:16], 300)), 256) nose.tools.assert_equal(s2.solver.eval_upto(result[15:0], 300, cast_to=bytes), [ b'AA' ]) l.info("concrete src, concrete dst, symbolic len") dst = s2.solver.BVV(0x41414141, 32) dst_addr = s2.solver.BVV(0x1000, 64) src = s2.solver.BVV(0x42424242, 32) src_addr = s2.solver.BVV(0x2000, 64) s = SimState(arch="AMD64", mode="symbolic") s.memory.store(dst_addr, dst) s.memory.store(src_addr, src) cpylen = s.solver.BVS("len", 64) s.add_constraints(s.solver.ULE(cpylen, 4)) memcpy(s, arguments=[dst_addr, src_addr, cpylen]) new_dst = s.memory.load(dst_addr, 4, endness='Iend_BE') nose.tools.assert_sequence_equal(sorted(s.solver.eval_upto(new_dst, 300, cast_to=bytes)), [ b'AAAA', b'BAAA', b'BBAA', b'BBBA', b'BBBB' ])