예제 #1
0
def test_concrete_memset():
    def _individual_test(state, base, val, size):
        # time it
        start = time.time()
        memset = simuvex.SimProcedures['libc.so.6']['memset'](
            0x100000,
            state.arch).execute(state,
                                arguments=[base,
                                           state.se.BVV(val, 8), size])
        elapsed = time.time() - start

        # should be done within 1 second
        nose.tools.assert_less_equal(elapsed, 5)
        # the result should be good
        byt_0 = memset.state.memory.load(base, 1)
        nose.tools.assert_equal(s.se.any_n_int(byt_0, 10), [val])
        byt_1 = memset.state.memory.load(base + 1, 1)
        nose.tools.assert_equal(s.se.any_n_int(byt_1, 10), [val])
        byt_2 = memset.state.memory.load(base + size - 1, 1)
        nose.tools.assert_equal(s.se.any_n_int(byt_2, 10), [val])

    BASE = 0x800000
    SIZE = 0x200000

    # Writes many zeros
    VAL = 0
    s = simuvex.SimState(arch='AMD64')
    _individual_test(s, BASE, VAL, SIZE)

    # Writes many ones
    VAL = 1
    s = simuvex.SimState(arch='AMD64')
    _individual_test(s, BASE, VAL, SIZE)
예제 #2
0
def test_fullpage_write():
    s = simuvex.SimState(arch='AMD64')
    a = s.se.BVV('A' * 0x2000)
    s.memory.store(0, a)
    #assert len(s.memory.mem._pages) == 2
    #assert len(s.memory.mem._pages[0].keys()) == 0
    #assert len(s.memory.mem._pages[1].keys()) == 0
    assert s.memory.load(0, 0x2000) is a
    assert a.variables != s.memory.load(0x2000, 1).variables

    s = simuvex.SimState(arch='AMD64')
    a = s.se.BVV('A' * 2)
    s.memory.store(0x1000, a)
    s.memory.store(0x2000, a)
    assert a.variables == s.memory.load(0x2000, 1).variables
    assert a.variables == s.memory.load(0x2001, 1).variables
    assert a.variables != s.memory.load(0x2002, 1).variables

    s = simuvex.SimState(arch='AMD64')
    x = s.se.BVV('X')
    a = s.se.BVV('A' * 0x1000)
    s.memory.store(1, x)
    s2 = s.copy()
    s2.memory.store(0, a)
    assert len(s.memory.changed_bytes(s2.memory)) == 0x1000

    s = simuvex.SimState(arch='AMD64')
    s.memory._maximum_symbolic_size = 0x2000000
    a = s.se.BVS('A', 0x1000000 * 8)
    s.memory.store(0, a)
    b = s.memory.load(0, 0x1000000)
    assert b is a
예제 #3
0
def test_files():
    s = simuvex.SimState()
    s.posix.write(0, "HELLO", 5)
    s.posix.write(0, "WORLD", 5)
    assert s.posix.dumps(0) == "HELLOWORLD"

    s = simuvex.SimState()
    s.posix.write(0, "A" * 0x1000, 0x1000)
    assert s.posix.dumps(0) == "A" * 0x1000
예제 #4
0
    def static_exits(self, blocks):
        # Execute those blocks with a blank state, and then dump the arguments
        blank_state = simuvex.SimState(arch=self.arch, mode="fastpath")

        # Execute each block
        state = blank_state
        for b in blocks:
            irsb = simuvex.SimEngineVEX().process(
                state,
                b,
                force_addr=next(
                    iter(stmt for stmt in b.statements
                         if isinstance(stmt, pyvex.IRStmt.IMark))).addr)
            if irsb.successors:
                state = irsb.successors[0]
            else:
                break

        cc = simuvex.DefaultCC[self.arch.name](self.arch)
        callfunc = cc.arg(state, 2)
        retaddr = state.memory.load(state.regs.sp, self.arch.bytes)

        all_exits = [(callfunc, 'Ijk_Call'), (retaddr, 'Ijk_Ret')]

        return all_exits
예제 #5
0
def test_inspect_exit():
    class counts: #pylint:disable=no-init
        exit_before = 0
        exit_after = 0

    def handle_exit_before(state):
        counts.exit_before += 1
        exit_target = state.inspect.exit_target
        nose.tools.assert_equal(state.se.any_int(exit_target), 0x3f8)
        # change exit target
        state.inspect.exit_target = 0x41414141
        nose.tools.assert_equal(state.inspect.exit_jumpkind, "Ijk_Boring")
        nose.tools.assert_true(state.inspect.exit_guard.is_true())

    def handle_exit_after(state): #pylint:disable=unused-argument
        counts.exit_after += 1

    s = simuvex.SimState(arch="AMD64", mode="symbolic")
    irsb = pyvex.IRSB("\x90\x90\x90\x90\xeb\x0a", mem_addr=1000, arch=archinfo.ArchAMD64())

    # break on exit
    s.inspect.b('exit', simuvex.BP_BEFORE, action=handle_exit_before)
    s.inspect.b('exit', simuvex.BP_AFTER, action=handle_exit_after)

    # step it
    succ = simuvex.SimIRSB(s, irsb).successors

    # check
    nose.tools.assert_equal( succ[0].se.any_int(succ[0].ip), 0x41414141)
    nose.tools.assert_equal(counts.exit_before, 1)
    nose.tools.assert_equal(counts.exit_after, 1)
예제 #6
0
def test_symbolic_write():
    s = simuvex.SimState(
        arch='AMD64', add_options={simuvex.options.SYMBOLIC_WRITE_ADDRESSES})
    x = s.se.BVS('x', 64)
    y = s.se.BVS('y', 64)
    a = s.se.BVV('A' * 0x10)
    b = s.se.BVV('B')
    c = s.se.BVV('C')
    d = s.se.BVV('D')

    s.memory.store(0x10, a)
    s.add_constraints(x >= 0x10, x < 0x20)
    s.memory.store(x, b)

    for i in range(0x10, 0x20):
        assert len(s.se.any_n_int(s.memory.load(i, 1), 10)) == 2

    s.memory.store(x, c)
    for i in range(0x10, 0x20):
        assert len(s.se.any_n_int(s.memory.load(i, 1), 10)) == 2

    s2 = s.copy()
    s2.add_constraints(y >= 0x10, y < 0x20)
    s2.memory.store(y, d)
    for i in range(0x10, 0x20):
        assert len(s2.se.any_n_int(s2.memory.load(i, 1), 10)) == 3
예제 #7
0
    def static_exits(cls, arch, blocks):
        # Execute those blocks with a blank state, and then dump the arguments
        blank_state = simuvex.SimState(arch=arch, mode="fastpath")

        # Execute each block
        state = blank_state
        for b in blocks:
            # state.regs.ip = next(iter(stmt for stmt in b.statements if isinstance(stmt, pyvex.IRStmt.IMark))).addr
            irsb = simuvex.SimIRSB(
                state,
                b,
                addr=next(
                    iter(stmt for stmt in b.statements
                         if isinstance(stmt, pyvex.IRStmt.IMark))).addr)
            if irsb.successors:
                state = irsb.successors[0]
            else:
                break

        cc = simuvex.DefaultCC[arch.name](arch)
        args = [cc.arg(state, _) for _ in xrange(5)]
        main, _, _, init, fini = cls._extract_args(blank_state, *args)

        all_exits = [
            (init, 'Ijk_Call'),
            (main, 'Ijk_Call'),
            (fini, 'Ijk_Call'),
        ]

        return all_exits
예제 #8
0
def test_lseek_end():
    state = simuvex.SimState(arch="AMD64", mode="symbolic")

    # This could be any number above 2 really
    fd = 3

    # Create a file
    f = state.posix.get_file(fd)

    # Give this a fake size
    f.size = 16

    # Part 1

    # Add 5
    current_pos = lseek(state,[fd,5,SEEK_END]).ret_expr
    current_pos = state.se.any_int(current_pos)

    # We should be at the end + offset
    nose.tools.assert_equal(current_pos,21)

    # Part 2

    # Minus 6. End of file never actually changed
    current_pos = lseek(state,[fd,-6,SEEK_END]).ret_expr
    current_pos = state.se.any_int(current_pos)

    # We should be at the end + offset
    nose.tools.assert_equal(current_pos,10)
예제 #9
0
def test_global_condition():
    s = simuvex.SimState()

    s.regs.rax = 10
    old_rax = s.regs.rax
    with s.with_condition(False):
        nose.tools.assert_false(s.se.satisfiable())
        s.regs.rax = 20
    nose.tools.assert_is(s._global_condition, None)
    nose.tools.assert_is(old_rax, s.regs.rax)

    with s.with_condition(True):
        s.regs.rax = 20
    nose.tools.assert_is(s._global_condition, None)
    nose.tools.assert_is_not(old_rax, s.regs.rax)
    nose.tools.assert_is(s.se.BVV(20, s.arch.bits), s.regs.rax)

    with s.with_condition(s.regs.rbx != 0):
        s.regs.rax = 25
    nose.tools.assert_is(s._global_condition, None)
    nose.tools.assert_is_not(s.se.BVV(25, s.arch.bits), s.regs.rax)

    with s.with_condition(s.regs.rbx != 1):
        s.regs.rax = 30
    nose.tools.assert_is(s._global_condition, None)
    nose.tools.assert_is_not(s.se.BVV(30, s.arch.bits), s.regs.rax)

    with s.with_condition(s.regs.rbx == 0):
        nose.tools.assert_equals(s.se.any_n_int(s.regs.rbx, 10), [0])
        nose.tools.assert_items_equal(s.se.any_n_int(s.regs.rax, 10), [30])
    with s.with_condition(s.regs.rbx == 1):
        nose.tools.assert_equals(s.se.any_n_int(s.regs.rbx, 10), [1])
        nose.tools.assert_items_equal(s.se.any_n_int(s.regs.rax, 10), [25])
예제 #10
0
def test_lseek_cur():
    state = simuvex.SimState(arch="AMD64", mode="symbolic")

    # This could be any number above 2 really
    fd = 3

    # Create a file
    state.posix.get_file(fd)

    # Part 1

    # Add 12
    current_pos = lseek(state,[fd,12,SEEK_CUR]).ret_expr
    current_pos = state.se.any_int(current_pos)

    # We should be at the start
    nose.tools.assert_equal(current_pos,12)

    # Part 2

    # Remove 3
    current_pos = lseek(state,[fd,-3,SEEK_CUR]).ret_expr
    current_pos = state.se.any_int(current_pos)

    # We should be at the start
    nose.tools.assert_equal(current_pos,9)
예제 #11
0
def test_lseek_set():
    state = simuvex.SimState(arch="AMD64", mode="symbolic")

    # This could be any number above 2 really
    fd = 3

    # Create a file
    state.posix.get_file(fd)

    # Part 1

    # Seek to the top of the file
    current_pos = lseek(state,[fd,0,SEEK_SET]).ret_expr
    current_pos = state.se.any_int(current_pos)

    # We should be at the start
    nose.tools.assert_equal(current_pos,0)

    # Part 2

    # Seek to the top of the file
    current_pos = lseek(state,[fd,8,SEEK_SET]).ret_expr
    current_pos = state.se.any_int(current_pos)

    # We should be at the start
    nose.tools.assert_equal(current_pos,8)

    # Part 3

    # Seek to the top of the file
    current_pos = lseek(state,[fd,3,SEEK_SET]).ret_expr
    current_pos = state.se.any_int(current_pos)

    # We should be at the start
    nose.tools.assert_equal(current_pos,3)
예제 #12
0
def test_inspect_syscall():
    class counts: #pylint:disable=no-init
        exit_before = 0
        exit_after = 0

    def handle_syscall_before(state):
        counts.exit_before += 1
        syscall_name = state.inspect.syscall_name
        nose.tools.assert_equal(syscall_name, "close")

    def handle_syscall_after(state):
        counts.exit_after += 1
        syscall_name = state.inspect.syscall_name
        nose.tools.assert_equal(syscall_name, "close")

    s = simuvex.SimState(arch="AMD64", mode="symbolic")
    # set up to call so syscall close
    s.regs.rax = 3
    s.regs.rdi = 2

    # break on syscall
    s.inspect.b('syscall', simuvex.BP_BEFORE, action=handle_syscall_before)
    s.inspect.b('syscall', simuvex.BP_AFTER, action=handle_syscall_after)

    # step it
    simuvex.SimProcedures['syscalls']['close'](s, addr=s.se.any_int(s.ip), ret_to=s.ip, syscall_name='close')

    # check counts
    nose.tools.assert_equal(counts.exit_before, 1)
    nose.tools.assert_equal(counts.exit_after, 1)
예제 #13
0
def test_fast_memory():
    s = simuvex.SimState(add_options={simuvex.o.FAST_REGISTERS, simuvex.o.FAST_MEMORY})

    s.regs.rax = 0x4142434445464748
    s.regs.rbx = 0x5555555544444444
    assert (s.regs.rax == 0x4142434445464748).is_true()
    assert (s.regs.rbx == 0x5555555544444444).is_true()

    _concrete_memory_tests(s)
예제 #14
0
def test_registers():
    s = simuvex.SimState(arch='AMD64')
    expr = s.registers.load('rax')
    nose.tools.assert_true(s.se.symbolic(expr))

    s.registers.store('rax', 0x31)
    expr = s.registers.load('rax')
    nose.tools.assert_false(s.se.symbolic(expr))
    nose.tools.assert_equals(s.se.any_int(expr), 0x00000031)
예제 #15
0
def test_false_condition():
    s = simuvex.SimState(arch='AMD64')

    asdf = s.se.BVV('asdf')
    fdsa = s.se.BVV('fdsa')
    s.memory.store(0x1000, asdf)
    s.memory.store(0x1000, fdsa, condition=s.se.false)
    s.memory.store(0, fdsa, condition=s.se.false)

    assert s.memory.load(0x1000, 4) is asdf
    assert 0 not in s.memory.mem._pages
예제 #16
0
def test_mmap_base_copy():
    state = simuvex.SimState(arch="AMD64", mode="symbolic")

    mmap_base = 0x12345678

    state.libc.mmap_base = mmap_base

    # Sanity check
    nose.tools.assert_equal(state.libc.mmap_base, mmap_base)

    state_copy = state.copy()

    nose.tools.assert_equal(state_copy.libc.mmap_base, mmap_base)
예제 #17
0
def test_lseek_symbolic_whence():
    # symbolic whence is currently not possible
    state = simuvex.SimState(arch="AMD64", mode="symbolic")

    # This could be any number above 2 really
    fd = 3

    # Create a file
    state.posix.get_file(fd)

    whence = state.se.BVS('whence',64)

    # This should cause the exception
    lseek(state,[fd,0,whence])
예제 #18
0
def test_lseek_symbolic_seek():
    # symbolic seek is currently not possible
    state = simuvex.SimState(arch="AMD64", mode="symbolic")

    # This could be any number above 2 really
    fd = 3

    # Create a file
    state.posix.get_file(fd)

    seek = state.se.BVS('seek',64)

    # This should cause the exception
    lseek(state,[fd,seek,SEEK_SET])
예제 #19
0
def test_load_bytes():
    s = simuvex.SimState(arch='AMD64')
    asdf = s.se.BVS('asdf', 0x1000*8)
    s.memory.store(0x4000, asdf)
    items = s.memory.mem.load_objects(0x4000, 0x1000)
    assert len(items) == 1

    fdsa = s.se.BVV('fdsa')
    s.memory.store(0x4004, fdsa)
    items = s.memory.mem.load_objects(0x4000, 0x1000)
    assert len(items) == 3

    items = s.memory.mem.load_objects(0x8000, 0x2000)
    assert len(items) == 0
예제 #20
0
def test_state():
    s = simuvex.SimState(arch='AMD64')
    s.registers.store('sp', 0x7ffffffffff0000)
    nose.tools.assert_equals(s.se.any_int(s.registers.load('sp')), 0x7ffffffffff0000)

    s.stack_push(s.se.BVV("ABCDEFGH"))
    nose.tools.assert_equals(s.se.any_int(s.registers.load('sp')), 0x7fffffffffefff8)
    s.stack_push(s.se.BVV("IJKLMNOP"))
    nose.tools.assert_equals(s.se.any_int(s.registers.load('sp')), 0x7fffffffffefff0)

    a = s.stack_pop()
    nose.tools.assert_equals(s.se.any_int(s.registers.load('sp')), 0x7fffffffffefff8)
    nose.tools.assert_equals(s.se.any_str(a), "IJKLMNOP")

    b = s.stack_pop()
    nose.tools.assert_equals(s.se.any_int(s.registers.load('sp')), 0x7ffffffffff0000)
    nose.tools.assert_equals(s.se.any_str(b), "ABCDEFGH")
예제 #21
0
def test_load_bytes():
    s = simuvex.SimState(arch='AMD64')
    asdf = s.se.BVS('asdf', 0x1000 * 8)
    s.memory.store(0x4000, asdf)
    the_bytes, missing, bytes_read = s.memory.mem.load_bytes(0x4000, 0x1000)
    assert len(missing) == 0
    assert len(the_bytes) == 1
    assert bytes_read == 0x1000

    fdsa = s.se.BVV('fdsa')
    s.memory.store(0x4004, fdsa)
    the_bytes, missing, bytes_read = s.memory.mem.load_bytes(0x4000, 0x1000)
    assert len(missing) == 0
    assert len(the_bytes) == 3
    assert bytes_read == 0x1000

    the_bytes, missing, bytes_read = s.memory.mem.load_bytes(0x8000, 0x2000)
    assert len(the_bytes) == 0
    assert len(missing) == 2
    assert bytes_read == 0x2000
예제 #22
0
def test_lseek_unseekable():
    state = simuvex.SimState(arch="AMD64", mode="symbolic")

    # Illegal seek
    current_pos = lseek(state,[0,0,SEEK_SET]).ret_expr
    current_pos = state.se.any_int(current_pos)

    # Assert we have a negative return value
    nose.tools.assert_true(current_pos & (1 << 63) != 0)

    # Illegal seek
    current_pos = lseek(state,[1,0,SEEK_SET]).ret_expr
    current_pos = state.se.any_int(current_pos)

    # Assert we have a negative return value
    nose.tools.assert_true(current_pos & (1 << 63) != 0)

    # Illegal seek
    current_pos = lseek(state,[2,0,SEEK_SET]).ret_expr
    current_pos = state.se.any_int(current_pos)

    # Assert we have a negative return value
    nose.tools.assert_true(current_pos & (1 << 63) != 0)
예제 #23
0
def test_inspect():
    class counts: #pylint:disable=no-init
        mem_read = 0
        mem_write = 0
        reg_read = 0
        reg_write = 0
        tmp_read = 0
        tmp_write = 0
        expr = 0
        statement = 0
        instruction = 0
        constraints = 0
        variables = 0

    def act_mem_read(state): #pylint:disable=unused-argument
        counts.mem_read += 1
    def act_mem_write(state): #pylint:disable=unused-argument
        counts.mem_write += 1
    def act_reg_read(state): #pylint:disable=unused-argument
        counts.reg_read += 1
    def act_reg_write(state): #pylint:disable=unused-argument
        counts.reg_write += 1
    def act_tmp_read(state): #pylint:disable=unused-argument
        counts.tmp_read += 1
    def act_tmp_write(state): #pylint:disable=unused-argument
        counts.tmp_write += 1
    def act_expr(state): #pylint:disable=unused-argument
        counts.expr += 1
    def act_statement(state): #pylint:disable=unused-argument
        counts.statement += 1
    def act_instruction(state): #pylint:disable=unused-argument
        counts.instruction += 1
    def act_variables(state): #pylint:disable=unused-argument
        #print "CREATING:", state.inspect.symbolic_name
        counts.variables += 1
#   def act_constraints(state): #pylint:disable=unused-argument
#       counts.constraints += 1


    s = simuvex.SimState(arch="AMD64", mode="symbolic")

    s.inspect.b('mem_write', when=simuvex.BP_AFTER, action=act_mem_write)
    nose.tools.assert_equals(counts.mem_write, 0)
    s.memory.store(100, s.se.BVV(10, 32))
    nose.tools.assert_equals(counts.mem_write, 1)

    s.inspect.b('mem_read', when=simuvex.BP_AFTER, action=act_mem_read)
    s.inspect.b('mem_read', when=simuvex.BP_AFTER, action=act_mem_read, mem_read_address=100)
    s.inspect.b('mem_read', when=simuvex.BP_AFTER, action=act_mem_read, mem_read_address=123)
    s.inspect.b('mem_read', when=simuvex.BP_BEFORE, action=act_mem_read, mem_read_length=3)
    nose.tools.assert_equals(counts.mem_read, 0)
    s.memory.load(123, 4)
    s.memory.load(223, 3)
    nose.tools.assert_equals(counts.mem_read, 4)

    s.inspect.b('reg_read', when=simuvex.BP_AFTER, action=act_reg_read)
    nose.tools.assert_equals(counts.reg_read, 0)
    s.registers.load(16)
    nose.tools.assert_equals(counts.reg_read, 1)

    s.inspect.b('reg_write', when=simuvex.BP_AFTER, action=act_reg_write)
    nose.tools.assert_equals(counts.reg_write, 0)
    s.registers.store(16, s.se.BVV(10, 32))
    nose.tools.assert_equals(counts.reg_write, 1)
    nose.tools.assert_equals(counts.mem_write, 1)
    nose.tools.assert_equals(counts.mem_read, 4)
    nose.tools.assert_equals(counts.reg_read, 1)

    s.inspect.b('tmp_read', when=simuvex.BP_AFTER, action=act_tmp_read, tmp_read_num=0)
    s.inspect.b('tmp_write', when=simuvex.BP_AFTER, action=act_tmp_write, tmp_write_num=0)
    s.inspect.b('expr', when=simuvex.BP_AFTER, action=act_expr, expr=1016, expr_unique=False)
    s.inspect.b('statement', when=simuvex.BP_AFTER, action=act_statement)
    s.inspect.b('instruction', when=simuvex.BP_AFTER, action=act_instruction, instruction=1001)
    s.inspect.b('instruction', when=simuvex.BP_AFTER, action=act_instruction, instruction=1000)
    irsb = pyvex.IRSB("\x90\x90\x90\x90\xeb\x0a", mem_addr=1000, arch=archinfo.ArchAMD64())
    irsb.pp()
    simuvex.SimIRSB(s, irsb)
    nose.tools.assert_equals(counts.reg_write, 7)
    nose.tools.assert_equals(counts.reg_read, 2)
    nose.tools.assert_equals(counts.tmp_write, 1)
    nose.tools.assert_equals(counts.tmp_read, 1)
    nose.tools.assert_equals(counts.expr, 3) # one for the Put, one for the WrTmp, and one to get the next address to jump to
    nose.tools.assert_equals(counts.statement, 26)
    nose.tools.assert_equals(counts.instruction, 2)
    nose.tools.assert_equals(counts.constraints, 0)
    nose.tools.assert_equals(counts.mem_write, 1)
    nose.tools.assert_equals(counts.mem_read, 4)

    s = simuvex.SimState(arch="AMD64", mode="symbolic")
    s.inspect.b('symbolic_variable', when=simuvex.BP_AFTER, action=act_variables)
    s.memory.load(0, 10)
    nose.tools.assert_equals(counts.variables, 1)
예제 #24
0
def test_inspect_concretization():
    # some values for the test
    x = claripy.BVS('x', 64)
    y = claripy.BVS('y', 64)

    #
    # This tests concretization-time address redirection.
    #

    def change_symbolic_target(state):
        if state.inspect.address_concretization_action == 'store':
            state.inspect.address_concretization_expr = claripy.BVV(0x1000, state.arch.bits)

    s = simuvex.SimState()
    s.inspect.b('address_concretization', simuvex.BP_BEFORE, action=change_symbolic_target)
    s.memory.store(x, 'A')
    assert list(s.se.eval(x, 10)) == [ 0x1000 ]
    assert list(s.se.eval(s.memory.load(0x1000, 1), 10)) == [ 0x41 ]

    #
    # This tests disabling constraint adding through siminspect -- the write still happens
    #

    def dont_add_constraints(state):
        state.inspect.address_concretization_add_constraints = False

    s = simuvex.SimState()
    s.inspect.b('address_concretization', simuvex.BP_BEFORE, action=dont_add_constraints)
    s.memory.store(x, 'A')
    assert len(s.se.eval(x, 10)) == 10

    #
    # This tests raising an exception if symbolic concretization fails (i.e., if the address
    # is too unconstrained). The write aborts.
    #

    class UnconstrainedAbort(Exception):
        def __init__(self, message, state):
            Exception.__init__(self, message)
            self.state = state

    def abort_unconstrained(state):
        print state.inspect.address_concretization_strategy, state.inspect.address_concretization_result
        if (
            isinstance(
                state.inspect.address_concretization_strategy,
                simuvex.concretization_strategies.SimConcretizationStrategyRange
            ) and state.inspect.address_concretization_result is None
        ):
            raise UnconstrainedAbort("uh oh", state)

    s = simuvex.SimState()
    s.memory.write_strategies.insert(
        0, simuvex.concretization_strategies.SimConcretizationStrategyRange(128)
    )
    s.memory._write_address_range = 1
    s.memory._write_address_range_approx = 1
    s.add_constraints(y == 10)
    s.inspect.b('address_concretization', simuvex.BP_AFTER, action=abort_unconstrained)
    s.memory.store(y, 'A')
    assert list(s.se.eval(s.memory.load(y, 1), 10)) == [ 0x41 ]

    try:
        s.memory.store(x, 'A')
        print "THIS SHOULD NOT BE REACHED"
        assert False
    except UnconstrainedAbort as e:
        assert e.state.memory is s.memory