Exemple #1
0
 def _op_float_op_just_low(self, args):
     chopped = [arg[(self._vector_size - 1):0].raw_to_fp() for arg in args]
     result = getattr(claripy, 'fp' + self._generic_name)(claripy.fp.RM.default(), *chopped).to_bv()
     return claripy.Concat(args[0][(args[0].length - 1):self._vector_size], result)
Exemple #2
0
def raw_simple_merging(solver_type):
    s1 = solver_type()
    s2 = solver_type()
    w = claripy.BVS("w", 8)
    x = claripy.BVS("x", 8)
    y = claripy.BVS("y", 8)
    z = claripy.BVS("z", 8)
    m = claripy.BVS("m", 8)

    s1.add([x == 1, y == 10])
    s2.add([x == 2, z == 20, w == 5])
    _, sm = s1.merge([s2], m, [ 0, 1 ])

    nose.tools.assert_equal(s1.eval(x, 1), (1,))
    nose.tools.assert_equal(s2.eval(x, 1), (2,))

    sm1 = sm.branch()
    sm1.add(x == 1)
    nose.tools.assert_equal(sm1.eval(x, 1), (1,))
    nose.tools.assert_equal(sm1.eval(y, 1), (10,))
    nose.tools.assert_equal(sm1.eval(z, 1), (0,))
    nose.tools.assert_equal(sm1.eval(w, 1), (0,))

    sm2 = sm.branch()
    sm2.add(x == 2)
    nose.tools.assert_equal(sm2.eval(x, 1), (2,))
    nose.tools.assert_equal(sm2.eval(y, 1), (0,))
    nose.tools.assert_equal(sm2.eval(z, 1), (20,))
    nose.tools.assert_equal(sm2.eval(w, 1), (5,))

    sm1 = sm.branch()
    sm1.add(m == 0)
    nose.tools.assert_equal(sm1.eval(x, 1), (1,))
    nose.tools.assert_equal(sm1.eval(y, 1), (10,))
    nose.tools.assert_equal(sm1.eval(z, 1), (0,))
    nose.tools.assert_equal(sm1.eval(w, 1), (0,))

    sm2 = sm.branch()
    sm2.add(m == 1)
    nose.tools.assert_equal(sm2.eval(x, 1), (2,))
    nose.tools.assert_equal(sm2.eval(y, 1), (0,))
    nose.tools.assert_equal(sm2.eval(z, 1), (20,))
    nose.tools.assert_equal(sm2.eval(w, 1), (5,))

    m2 = claripy.BVS("m2", 32)
    _, smm = sm1.merge([sm2], m2, [0, 1])

    smm_1 = smm.branch()
    smm_1.add(x == 1)
    nose.tools.assert_equal(smm_1.eval(x, 1), (1,))
    nose.tools.assert_equal(smm_1.eval(y, 1), (10,))
    nose.tools.assert_equal(smm_1.eval(z, 1), (0,))
    nose.tools.assert_equal(smm_1.eval(w, 1), (0,))

    smm_2 = smm.branch()
    smm_2.add(m == 1)
    nose.tools.assert_equal(smm_2.eval(x, 1), (2,))
    nose.tools.assert_equal(smm_2.eval(y, 1), (0,))
    nose.tools.assert_equal(smm_2.eval(z, 1), (20,))
    nose.tools.assert_equal(smm_2.eval(w, 1), (5,))

    so = solver_type()
    so.add(w == 0)

    sa = so.branch()
    sb = so.branch()
    sa.add(x == 1)
    sb.add(x == 2)
    _, sm = sa.merge([sb], m, [0, 1])

    smc = sm.branch()
    smd = sm.branch()
    smc.add(y == 3)
    smd.add(y == 4)

    _, smm = smc.merge([smd], m2, [0, 1])
    wxy = claripy.Concat(w, x, y)

    smm_1 = smm.branch()
    smm_1.add(wxy == 0x000103)
    nose.tools.assert_true(smm_1.satisfiable())

    smm_1 = smm.branch()
    smm_1.add(wxy == 0x000104)
    nose.tools.assert_true(smm_1.satisfiable())

    smm_1 = smm.branch()
    smm_1.add(wxy == 0x000203)
    nose.tools.assert_true(smm_1.satisfiable())

    smm_1 = smm.branch()
    smm_1.add(wxy == 0x000204)
    nose.tools.assert_true(smm_1.satisfiable())

    smm_1 = smm.branch()
    smm_1.add(wxy != 0x000103)
    smm_1.add(wxy != 0x000104)
    smm_1.add(wxy != 0x000203)
    smm_1.add(wxy != 0x000204)
    nose.tools.assert_false(smm_1.satisfiable())
Exemple #3
0
 def get_value(self, state, endness=None, **kwargs):
     if endness is None: endness = state.arch.memory_endness
     vals = []
     for loc in self.locations:
         vals.append(loc.get_value(state, endness, **kwargs))
     return claripy.Concat(*vals)
Exemple #4
0
import angr
import claripy

#Solve just like the example given in class
proj = angr.Project("./cracksymb")

chars = [claripy.BVS(f'c%d' % i, 8) for i in range(0x17)]
input_str = claripy.Concat(*chars + [claripy.BVV(b'\n')]) # + \n
initial_state = proj.factory.entry_state(stdin=input_str, add_options={angr.options.LAZY_SOLVES} ) # use as stdin

for c in chars: # make sure all chars are printable
    initial_state.solver.add(c >= 0x20, c <= 0x7e)

simgr = proj.factory.simulation_manager(initial_state)
simgr.explore(find=0x4033c2) # flag correct

if simgr.found:
    print(simgr.found[0].posix.dumps(0))

#flag{l1n34r_syst3ms_<3}
Exemple #5
0
    def state_entry(self, args=None, env=None, argc=None, **kwargs):
        state = super(SimWindows, self).state_entry(**kwargs)

        if args is None: args = []
        if env is None: env = {}

        # Prepare argc
        if argc is None:
            argc = claripy.BVV(len(args), state.arch.bits)
        elif type(argc) in (int, long):  # pylint: disable=unidiomatic-typecheck
            argc = claripy.BVV(argc, state.arch.bits)

        # Make string table for args and env
        table = StringTableSpec()
        table.append_args(args)
        table.append_env(env)

        # calculate full command line, since this is windows and that's how everything works
        cmdline = claripy.BVV(0, 0)
        for arg in args:
            if cmdline.length != 0:
                cmdline = cmdline.concat(claripy.BVV(' '))

            if type(arg) is str:
                if '"' in arg or '\0' in arg:
                    raise AngrSimOSError("Can't handle windows args with quotes or nulls in them")
                arg = claripy.BVV(arg)
            elif isinstance(arg, claripy.ast.BV):
                for byte in arg.chop(8):
                    state.solver.add(byte != claripy.BVV('"'))
                    state.solver.add(byte != claripy.BVV(0, 8))
            else:
                raise TypeError("Argument must be str or bitvector")

            cmdline = cmdline.concat(claripy.BVV('"'), arg, claripy.BVV('"'))
        cmdline = cmdline.concat(claripy.BVV(0, 8))
        wcmdline = claripy.Concat(*(x.concat(0, 8) for x in cmdline.chop(8)))

        if not state.satisfiable():
            raise AngrSimOSError("Can't handle windows args with quotes or nulls in them")

        # Dump the table onto the stack, calculate pointers to args, env
        stack_ptr = state.regs.sp
        stack_ptr -= 16
        state.memory.store(stack_ptr, claripy.BVV(0, 8*16))

        stack_ptr -= cmdline.length / 8
        state.memory.store(stack_ptr, cmdline)
        state.mem[self.acmdln_ptr].long = stack_ptr

        stack_ptr -= wcmdline.length / 8
        state.memory.store(stack_ptr, wcmdline)
        state.mem[self.wcmdln_ptr].long = stack_ptr

        argv = table.dump(state, stack_ptr)
        envp = argv + ((len(args) + 1) * state.arch.bytes)

        # Put argc on stack and fix the stack pointer
        newsp = argv - state.arch.bytes
        state.memory.store(newsp, argc, endness=state.arch.memory_endness)
        state.regs.sp = newsp

        # store argc argv envp in the posix plugin
        state.posix.argv = argv
        state.posix.argc = argc
        state.posix.environ = envp

        state.regs.sp = state.regs.sp - 0x80    # give us some stack space to work with

        # fake return address from entry point
        return_addr = self.return_deadend
        kernel32 = self.project.loader.shared_objects.get('kernel32.dll', None)
        if kernel32:
            # some programs will use the return address from start to find the kernel32 base
            return_addr = kernel32.get_symbol('ExitProcess').rebased_addr

        if state.arch.name == 'X86':
            state.mem[state.regs.sp].dword = return_addr

            # first argument appears to be PEB
            tib_addr = state.regs.fs.concat(state.solver.BVV(0, 16))
            peb_addr = state.mem[tib_addr + 0x30].dword.resolved
            state.mem[state.regs.sp + 4].dword = peb_addr

        return state
Exemple #6
0
 def _op_generic_GetMSBs(self, args):
     size = self._vector_count * self._vector_size
     bits = [claripy.Extract(i, i, args[0]) for i in range(size - 1, 6, -8)]
     return claripy.Concat(*bits)
Exemple #7
0
 def _op_generic_CatOddLanes(self, args):
     vec_0 = args[0].chop(self._vector_size)
     vec_1 = args[1].chop(self._vector_size)
     return claripy.Concat(*(vec_0[::2] + vec_1[::2]))
Exemple #8
0
flag_addr = p.loader.find_symbol("flag").rebased_addr
print("Flag @", hex(flag_addr))

flag_size = 0xd

# use unicorn for faster simulation
init_state = p.factory.entry_state(add_options=angr.options.unicorn)

# setup symbolic memory for our flag ..
flag = [claripy.BVS("flag_%d" % i, 8) for i in range(flag_size)]
# .. add some constraints to enforce ASCII characters ..
for c in flag:
    init_state.solver.add(c < 0x7f)
    init_state.solver.add(c > 0x20)
flag = claripy.Concat(*flag)

# .. and store it into the state
init_state.memory.store(flag_addr, flag)

# run the simulation until completion
sm = p.factory.simulation_manager(init_state)
sm.run()

final_state = sm.deadended[0]

# enforce exit code
final_state.solver.add(final_state.regs.dil == 0)

result = final_state.solver.eval(flag, cast_to=bytes)
print("The flag is", result)
Exemple #9
0
def test_expression():
    bc = claripy.backends.concrete

    e = claripy.BVV(0x01020304, 32)
    nose.tools.assert_equal(len(e), 32)
    r = e.reversed
    nose.tools.assert_equal(bc.convert(r), 0x04030201)
    nose.tools.assert_equal(len(r), 32)

    nose.tools.assert_equal([ bc.convert(i) for i in r.chop(8) ], [ 4, 3, 2, 1 ] )

    e1 = r[31:24]
    nose.tools.assert_equal(bc.convert(e1), 0x04)
    nose.tools.assert_equal(len(e1), 8)
    nose.tools.assert_equal(bc.convert(e1[2]), 1)
    nose.tools.assert_equal(bc.convert(e1[1]), 0)

    ee1 = e1.zero_extend(8)
    nose.tools.assert_equal(bc.convert(ee1), 0x0004)
    nose.tools.assert_equal(len(ee1), 16)

    ee1 = claripy.BVV(0xfe, 8).sign_extend(8)
    nose.tools.assert_equal(bc.convert(ee1), 0xfffe)
    nose.tools.assert_equal(len(ee1), 16)

    xe1 = [ bc.convert(i) for i in e1.chop(1) ]
    nose.tools.assert_equal(xe1, [ 0, 0, 0, 0, 0, 1, 0, 0 ])

    a = claripy.BVV(1, 1)
    nose.tools.assert_equal(bc.convert(a+a), 2)

    x = claripy.BVV(1, 32)
    nose.tools.assert_equal(x.length, 32)
    y = claripy.LShR(x, 10)
    nose.tools.assert_equal(y.length, 32)

    r = claripy.BVV(0x01020304, 32)
    rr = r.reversed
    rrr = rr.reversed
    #nose.tools.assert_is(bc.convert(r), bc.convert(rrr))
    #nose.tools.assert_is(type(bc.convert(rr)), claripy.A)
    nose.tools.assert_equal(bc.convert(rr), 0x04030201)
    nose.tools.assert_is(r.concat(rr), claripy.Concat(r, rr))

    rsum = r+rr
    nose.tools.assert_equal(bc.convert(rsum), 0x05050505)

    r = claripy.BVS('x', 32)
    rr = r.reversed
    rrr = rr.reversed
    nose.tools.assert_is(r, rrr)

    # test identity
    nose.tools.assert_is(r, rrr)
    nose.tools.assert_is_not(r, rr)
    ii = claripy.BVS('ii', 32)
    ij = claripy.BVS('ij', 32)
    nose.tools.assert_is(ii, ii)
    nose.tools.assert_is_not(ii, ij)

    si = claripy.SI(bits=32, stride=2, lower_bound=20, upper_bound=100)
    sj = claripy.SI(bits=32, stride=2, lower_bound=10, upper_bound=10)
    sk = claripy.SI(bits=32, stride=2, lower_bound=20, upper_bound=100)
    nose.tools.assert_true(claripy.backends.vsa.identical(si, si))
    nose.tools.assert_false(claripy.backends.vsa.identical(si, sj))
    nose.tools.assert_true(claripy.backends.vsa.identical(si, sk))
    nose.tools.assert_is_not(si, sj)
    nose.tools.assert_is_not(sj, sk)
    nose.tools.assert_is_not(sk, si)

    # test hash cache
    nose.tools.assert_is(a+a, a+a)

    # test replacement
    old = claripy.BVS('old', 32, explicit_name=True)
    new = claripy.BVS('new', 32, explicit_name=True)
    ooo = claripy.BVV(0, 32)

    old_formula = claripy.If((old + 1)%256 == 0, old+10, old+20)
    print old_formula.dbg_repr()
    new_formula = old_formula.replace(old, new)
    print new_formula.dbg_repr()
    ooo_formula = new_formula.replace(new, ooo)

    print ooo_formula.dbg_repr()

    nose.tools.assert_not_equal(hash(old_formula), hash(new_formula))
    nose.tools.assert_not_equal(hash(old_formula), hash(ooo_formula))
    nose.tools.assert_not_equal(hash(new_formula), hash(ooo_formula))

    nose.tools.assert_equal(old_formula.variables, { 'old' })
    nose.tools.assert_equal(new_formula.variables, { 'new' })
    nose.tools.assert_equal(ooo_formula.variables, ooo.variables)

    nose.tools.assert_true(old_formula.symbolic)
    nose.tools.assert_true(new_formula.symbolic)
    nose.tools.assert_true(new_formula.symbolic)

    nose.tools.assert_equal(str(old_formula).replace('old', 'new'), str(new_formula))
    nose.tools.assert_equal(bc.convert(ooo_formula), 20)

    # test dict replacement
    old = claripy.BVS('old', 32, explicit_name=True)
    new = claripy.BVS('new', 32, explicit_name=True)
    c = (old + 10) - (old + 20)
    d = (old + 1) - (old + 2)
    cr = c.replace_dict({(old+10).cache_key: (old+1), (old+20).cache_key: (old+2)})
    nose.tools.assert_is(cr, d)

    # test AST collapse
    s = claripy.SI(bits=32, stride=0, lower_bound=10, upper_bound=10)
    b = claripy.BVV(20, 32)

    sb = s+b
    nose.tools.assert_is_instance(sb.args[0], claripy.ast.Base)

    bb = b+b
    # this was broken previously -- it was checking if type(bb.args[0]) == A,
    # and it wasn't, but was instead a subclass. leaving this out for now
    # nose.tools.assert_not_is_instance(bb.args[0], claripy.ast.Base)

    # ss = s+s
    # (see above)
    # nose.tools.assert_not_is_instance(ss.args[0], claripy.ast.Base)

    sob = s|b
    # for now, this is collapsed. Presumably, Fish will make it not collapse at some point
    nose.tools.assert_is_instance(sob.args[0], claripy.ast.Base)

    # make sure the AST collapses for delayed ops like reversing
    rb = b.reversed
    #nose.tools.assert_is_instance(rb.args[0], claripy.ast.Base)
    # TODO: Properly delay reversing: should not be eager

    nose.tools.assert_is_not(rb, bb)
    nose.tools.assert_is(rb, rb)

    # test some alternate bvv creation methods
    nose.tools.assert_is(claripy.BVV('AAAA'), claripy.BVV(0x41414141, 32))
    nose.tools.assert_is(claripy.BVV('AAAA', 32), claripy.BVV(0x41414141, 32))
    nose.tools.assert_is(claripy.BVV('AB'), claripy.BVV(0x4142, 16))
    nose.tools.assert_is(claripy.BVV('AB', 16), claripy.BVV(0x4142, 16))
    nose.tools.assert_raises(claripy.errors.ClaripyValueError, claripy.BVV, 'AB', 8)
Exemple #10
0
 def string_to_ast(string):
         return claripy.Concat(*(claripy.BVV(ord(c), 8) for c in string))
    if found:
        return found[0]
    raise Exception("No address found for function : " + function_name)


binary = str(
    os.path.join(os.path.dirname(os.path.abspath(__file__)), "sub1or2"))
project = angr.Project(binary, auto_load_libs=False)
cfg = project.analyses.CFGFast(normalize=True)
function_name = "sub1or2"
start_address = get_function_address(cfg, function_name)
entry_state = project.factory.entry_state()

symbolic_integer = claripy.BVS("y_intle:32", 32)
symbolic_integer_le = claripy.Concat(claripy.Extract(7, 0, symbolic_integer),
                                     claripy.Extract(15, 8, symbolic_integer),
                                     claripy.Extract(23, 16, symbolic_integer),
                                     claripy.Extract(31, 24, symbolic_integer))
print("vex for 0x40053b: ")
project.factory.block(0x40053b).vex.pp()
call_state = project.factory.call_state(start_address,
                                        symbolic_integer_le,
                                        ret_addr=0x0)
simulation_manager = project.factory.simulation_manager(call_state)
while simulation_manager.active:
    for i in range(0, len(simulation_manager.active)):
        state = simulation_manager.active[i]
        memaddr4 = state.solver.eval(state.regs.rbp) - 4
        memval4 = state.memory.load(memaddr4, 4, endness=archinfo.Endness.LE)

        if state.addr == 0x400537:
            print("after the first decrement of x we have y:")
Exemple #12
0
logging.getLogger('angr').setLevel(logging.INFO)

# num_keys = get_arg()

proj = angr.Project(
    program_name,
    main_opts={"base_addr": 0},  # PIE binary
)

# create an array of bitvectors so that the value of each can easily be
# constrained to the range of printable ASCII characters
key_bytes = [
    claripy.BVS("byte_%d" % i, 8) for i in range(num_bytes_of_flag * 8)
]
key_bytes_AST = claripy.Concat(*key_bytes)

# we want to generate valid keys, so a symbolic variable is passed to
# the state rather than a concrete value
state = proj.factory.full_init_state(args=["./" + program_name],
                                     add_options=angr.options.unicorn)

# impose constraints on bitvectors the symbolic key is composed of
for byte in key_bytes:
    state.solver.add(byte >= 0x21, byte <= 0x7e)

sm = proj.factory.simulation_manager(state)

# find path to message indicating key was correct
sm.explore(find=find_address)
Exemple #13
0
    buf[0x6060] = 21

    start = 0
    while True:
        start = buf.find(b'\xBF\x94\x50\x40\x00', start)
        if start == -1:
            break
        AVOID.append(start + 0x400000)
        start += len(b'\xBF\x94\x50\x40\x00')

    with open('./angrybird_patch', 'wb') as f:
        f.write(buf)


if __name__ == "__main__":
    patch_and_anaylze()

    proj = angr.Project('./angrybird_patch',
                        load_options={'auto_load_libs': False})
    flag = claripy.Concat(claripy.BVV(0, 8 * (20)), claripy.BVV(b'\n'))
    state = proj.factory.blank_state(addr=0x4007B8)
    simgr = proj.factory.simulation_manager(state)
    print(AVOID)
    print(FIND)
    simgr.explore(find=FIND, avoid=AVOID)

    found = simgr.found[0]
    print(found.posix.dumps(0))
    print(found.state.posix.dumps(1))
Exemple #14
0
 def _op_generic_InterleaveLO(self, args):
     s = self._vector_size
     c = self._vector_count
     dst_vector = [ args[0][(i+1)*s-1:i*s] for i in xrange(c/2) ]
     src_vector = [ args[1][(i+1)*s-1:i*s] for i in xrange(c/2) ]
     return claripy.Concat(*itertools.chain.from_iterable(reversed(zip(dst_vector, src_vector))))
Exemple #15
0
 def _op_vector_mapped(self, args):
     chopped_args = ([claripy.Extract((i + 1) * self._vector_size - 1, i * self._vector_size, a) for a in args]
                     for i in reversed(range(self._vector_count)))
     return claripy.Concat(*(self._op_mapped(ca) for ca in chopped_args))
Exemple #16
0
    def state_blank(self,
                    flag_page=None,
                    allocate_stack_page_count=0x100,
                    **kwargs):
        """
        :param flag_page:                   Flag page content, either a string or a list of BV8s
        :param allocate_stack_page_count:   Number of pages to pre-allocate for stack
        """
        # default stack as specified in the cgc abi
        if kwargs.get('stack_end', None) is None:
            kwargs['stack_end'] = 0xbaaab000
        if kwargs.get('stack_size', None) is None:
            kwargs['stack_size'] = 1024 * 1024 * 8

        s = super(SimCGC, self).state_blank(**kwargs)  # pylint:disable=invalid-name

        # pre-grow the stack. unsure if this is strictly required or just a hack around a compiler bug
        if hasattr(s.memory, 'allocate_stack_pages'):
            s.memory.allocate_stack_pages(kwargs['stack_end'] - 1,
                                          allocate_stack_page_count * 0x1000)

        # Map the flag page
        if o.ABSTRACT_MEMORY not in s.options:
            s.memory.map_region(0x4347c000, 4096, 1)

        # Create the CGC plugin
        s.get_plugin('cgc')

        # Set maximum bytes a single receive syscall should read
        s.cgc.max_receive_size = kwargs.get("cgc_max_recv_size", 0)

        # Set up the flag page
        if flag_page is None:
            flag_page = [
                s.solver.BVS("cgc-flag-byte-%d" % i,
                             8,
                             key=('flag', i),
                             eternal=True) for i in range(0x1000)
            ]
        elif type(flag_page) is bytes:
            flag_page = [s.solver.BVV(c, 8) for c in flag_page]
        elif type(flag_page) is list:
            pass
        else:
            raise ValueError(
                "Bad flag page: expected None, bytestring, or list, but got %s"
                % type(flag_page))

        s.cgc.flag_bytes = flag_page
        if s.mode != 'static':
            s.memory.store(0x4347c000,
                           claripy.Concat(*s.cgc.flag_bytes),
                           priv=True)

        # set up the address for concrete transmits and receive
        s.unicorn.cgc_transmit_addr = self.syscall_from_number(2).addr
        s.unicorn.cgc_receive_addr = self.syscall_from_number(3).addr
        s.unicorn.cgc_random_addr = self.syscall_from_number(7).addr

        s.libc.max_str_len = 1000000
        s.libc.max_strtol_len = 10
        s.libc.max_memcpy_size = 0x100000
        s.libc.max_buffer_size = 0x100000

        return s
Exemple #17
0
 def _op_concat(self, args):
     return claripy.Concat(*args)
Exemple #18
0
    def _prepare_chall_resp(self, state):
        # now we need to find the challenge response stuff
        # first break constraints at And's
        constraints = []
        for c in state.solver.constraints:
            if c.op == "And":
                constraints.extend(c.args)
            else:
                constraints.append(c)

        # filter for possible flag constraints
        filtered_constraints = []
        for c in constraints:
            if any(
                    v.startswith("cgc-flag") or v.startswith("random")
                    for v in c.variables):
                filtered_constraints.append(c)

        self.filter_uncontrolled_constraints(state)
        # now separate into constraints we can probably control, and those we can't

        controllable_constraints = []
        uncontrollable_constraints = []
        if not state.has_plugin("chall_resp_info"):
            # register a blank one
            state.register_plugin("chall_resp_info", ChallRespInfo())

        chall_resp_info = state.get_plugin("chall_resp_info")

        for c in filtered_constraints:
            if any(v.startswith("aeg_stdin") for v in c.variables) or \
                    any(v in chall_resp_info.vars_we_added for v in c.variables):
                controllable_constraints.append(c)
            elif any(v.startswith("output_var") for v in c.variables):
                # an output like a leak
                pass
            else:
                # uncontrollable constraints will show up as zen constraints etc
                uncontrollable_constraints.append(c)

        if len(controllable_constraints) > 0:
            l.debug("Challenge response detected!")
            file_1 = state.posix.stdout
            stdout = file_1.load(0, file_1.size)

            stdout_len = state.solver.eval(file_1.size)
            stdout_bvs = [
                claripy.BVS("file_stdout_%#x" % i, 8, explicit_name=True)
                for i in range(stdout_len)
            ]
            stdout_bv = claripy.Concat(*stdout_bvs)

            state.add_constraints(stdout == stdout_bv)
            # we call simplify to separate the contraints/dependencies
            state.solver.simplify()

            merged_solver = state.solver._solver._merged_solver_for(
                lst=[self._mem] + controllable_constraints)
            # todo here we can verify that there are actually stdout bytes here, otherwise we have little hope

            # add the important stdout vars to mem
            needed_vars = []
            for bv in stdout_bvs:
                if len(bv.variables & merged_solver.variables) != 0:
                    needed_vars.append(bv)

            # add the str_to_int vars and int_to_str vars
            for _, v in chall_resp_info.str_to_int_pairs:
                needed_vars.append(v)
            for v, _ in chall_resp_info.int_to_str_pairs:
                needed_vars.append(v)
            self._mem = claripy.Concat(self._mem, *needed_vars)
Exemple #19
0
 def _op_generic_InterleaveHI(self, args):
     s = self._vector_size
     c = self._vector_count
     left_vector = [ args[0][(i+1)*s-1:i*s] for i in range(c//2, c) ]
     right_vector = [ args[1][(i+1)*s-1:i*s] for i in range(c//2, c) ]
     return claripy.Concat(*itertools.chain.from_iterable(zip(reversed(left_vector), reversed(right_vector))))
Exemple #20
0
import claripy

import pdb

arch = archinfo.ArchPPC32(archinfo.Endness.BE)
s = angr.SimState(arch=arch, mode="symbolic")

x = s.solver.BVS('x', 32, explicit_name=True)

#code = bytes(bytearray.fromhex("3c601234")) # lis

tyenv = pyvex.block.IRTypeEnv(arch, [ 'Ity_I32','Ity_I32','Ity_I32' ])

imark = pyvex.stmt.IMark(0x100, 4, 0)

a = claripy.Concat( x[31:16],  s.solver.BVV(0, 16))
c = pyvex.const.UN(a)
constExpr = pyvex.expr.Const(c)
wr = pyvex.stmt.WrTmp(1, constExpr)

rd = pyvex.expr.RdTmp(1)
put = pyvex.stmt.Put(rd, 28)

advance = pyvex.stmt.Put(pyvex.expr.Const(pyvex.const.U32(0x104)), 1168)

statements = [imark, wr, put, advance]

nxt = pyvex.expr.Const(pyvex.const.U32(0x104))


irsb1 = pyvex.IRSB.from_py(tyenv, statements, nxt, 'Ijk_Boring', 0x100, arch)
Exemple #21
0
    def _compose_objects(cls, objects, size, endness, **kwargs):
        if endness == 'Iend_LE':
            objects = reversed(objects)

        return claripy.Concat(*objects)
Exemple #22
0
p = angr.Project("i_can_count_8484ceff57cb99e3bdb3017f8c8a2467",
                 auto_load_libs=False)

# calculate all the addresses as they depend on the loading address
CHECK_FLAG_ADDR = p.loader.find_symbol('check_flag').rebased_addr
FLAG_BUF_ADDR = p.loader.find_symbol('flag_buf').rebased_addr

PRINT_FLAG_ADDR = p.loader.main_object.mapped_base + 0x0000f87
WRONG_FLAG_ADDR = p.loader.main_object.mapped_base + 0x0000fae

# create a state at the beginning of the check_flag function
st = p.factory.blank_state(addr=CHECK_FLAG_ADDR)

# create solvable variables for the flag characters
flag_chars = [claripy.BVS('flag_%d' % i, 8) for i in range(0x13)]
flag = claripy.Concat(*flag_chars)

# flag characters can only be digits
for k in flag_chars:
    st.solver.add(k >= ord('0'))
    st.solver.add(k <= ord('9'))

# make the flag_buf memory depending on user input and solvable
for i in range(len(flag_chars)):
    st.mem[FLAG_BUF_ADDR + i:].byte = flag_chars[i]

sm = p.factory.simulation_manager(st)

print("Calculating Flag")

# try to find a solution that prints out the flag and does not return before
Exemple #23
0
def test_some_vector_ops():
    engine = HeavyVEXMixin(None)
    s = SimState(arch="AMD64")

    def translate(state, op, args):
        return engine._perform_vex_expr_Op(op, args)

    a = s.solver.BVV(0xFFFF0000000100020003000400050006, 128)
    b = s.solver.BVV(0x00020002000200020002000200020002, 128)

    calc_result = translate(s, "Iop_Sub16x8", (a, b))
    correct_result = s.solver.BVV(0xFFFDFFFEFFFF00000001000200030004, 128)
    assert s.solver.is_true(calc_result == correct_result)

    calc_result = translate(s, "Iop_CmpEQ16x8", (a, b))
    correct_result = s.solver.BVV(0x000000000000FFFF0000000000000000, 128)
    assert s.solver.is_true(calc_result == correct_result)

    calc_result = translate(s, "Iop_CmpEQ8x16", (a, b))
    correct_result = s.solver.BVV(0x0000FF00FF00FFFFFF00FF00FF00FF00, 128)
    assert s.solver.is_true(calc_result == correct_result)

    calc_result = translate(s, "Iop_CmpGT16Sx8", (a, b))
    correct_result = s.solver.BVV(0x0000000000000000FFFFFFFFFFFFFFFF, 128)
    assert s.solver.is_true(calc_result == correct_result)

    calc_result = translate(s, "Iop_CmpGT16Ux8", (a, b))
    correct_result = s.solver.BVV(0xFFFF000000000000FFFFFFFFFFFFFFFF, 128)
    assert s.solver.is_true(calc_result == correct_result)

    calc_result = translate(s, "Iop_InterleaveLO16x8", (a, b))
    correct_result = s.solver.BVV(0x00030002000400020005000200060002, 128)
    assert s.solver.is_true(calc_result == correct_result)

    calc_result = translate(s, "Iop_InterleaveLO8x16", (a, b))
    correct_result = s.solver.BVV(0x00000302000004020000050200000602, 128)
    assert s.solver.is_true(calc_result == correct_result)

    calc_result = translate(s, "Iop_Min8Ux16", (a, b))
    correct_result = s.solver.BVV(0x00020000000100020002000200020002, 128)
    assert s.solver.is_true(calc_result == correct_result)

    calc_result = translate(s, "Iop_Min8Sx16", (a, b))
    correct_result = s.solver.BVV(0xFFFF0000000100020002000200020002, 128)
    assert s.solver.is_true(calc_result == correct_result)

    calc_result = translate(s, "Iop_QNarrowBin16Sto8Ux16", (a, b))
    correct_result = s.solver.BVV(0x00000102030405060202020202020202, 128)
    assert s.solver.is_true(calc_result == correct_result)

    c = s.solver.BVV(0xFF008877, 32)
    d = s.solver.BVV(0x11111111, 32)

    calc_result = translate(s, "Iop_HAdd8Sx4", (c, d))
    correct_result = s.solver.BVV(0x0808CC44, 32)
    assert s.solver.is_true(calc_result == correct_result)

    calc_result = translate(s, "Iop_QAdd8Sx4", (c, d))
    correct_result = s.solver.BVV(0x1011997F, 32)
    assert s.solver.is_true(calc_result == correct_result)

    calc_result = translate(s, "Iop_QAdd8Ux4", (c, d))
    correct_result = s.solver.BVV(0xFF119988, 32)
    assert s.solver.is_true(calc_result == correct_result)

    calc_result = translate(s, "Iop_QSub8Sx4", (c, d))
    correct_result = s.solver.BVV(0xEEEF8066, 32)
    assert s.solver.is_true(calc_result == correct_result)

    calc_result = translate(s, "Iop_QSub8Ux4", (c, d))
    correct_result = s.solver.BVV(0xEE007766, 32)
    assert s.solver.is_true(calc_result == correct_result)

    e = s.solver.BVV(0xFF00887766554433, 64)
    f = s.solver.BVV(0x0202000200020002, 64)

    calc_result = translate(s, "Iop_QNarrowBin16Sto8Ux8", (e, f))
    correct_result = s.solver.BVV(0x0000FFFFFF020202, 64)
    assert s.solver.is_true(calc_result == correct_result)

    gg = claripy.BVV(0x111111112222222233333333FFFFFFFF, 128)
    h = claripy.BVV(0x1111111100000000FFFFFFFFFFFFFFFF, 128)

    calc_result = translate(s, "Iop_CmpEQ32Fx4", (gg, h))
    correct_result = claripy.BVV(0xFFFFFFFF000000000000000000000000, 128)
    assert s.solver.is_true(calc_result == correct_result)

    calc_result = translate(s, "Iop_Clz32x4", (gg, ))
    correct_result = claripy.BVV(0x00000003000000020000000200000000, 128)
    assert s.solver.is_true(calc_result == correct_result)

    i = claripy.BVV(0x1001000000001000, 64)
    j = claripy.BVV(0x100000000000F000, 64)

    calc_result = translate(s, "Iop_Mull16Sx4", (i, j))
    correct_result = claripy.BVV(0x10010000000000000000000FF000000, 128)
    assert s.solver.is_true(calc_result == correct_result)

    calc_result = translate(s, "Iop_Mull16Ux4", (i, j))
    correct_result = claripy.BVV(0x100100000000000000000000F000000, 128)
    assert s.solver.is_true(calc_result == correct_result)

    k = claripy.BVV(0xE7, 8)
    ll = claripy.BVV(0x1234, 16)
    m = claripy.BVV(0x12345678, 32)

    calc_result = translate(s, "Iop_Dup8x8", (k, ))
    correct_result = claripy.BVV(0xE7E7E7E7E7E7E7E7, 64)
    assert s.solver.is_true(calc_result == correct_result)

    calc_result = translate(s, "Iop_Dup8x16", (k, ))
    correct_result = claripy.BVV(0xE7E7E7E7E7E7E7E7E7E7E7E7E7E7E7E7, 128)
    assert s.solver.is_true(calc_result == correct_result)

    calc_result = translate(s, "Iop_Dup16x4", (ll, ))
    correct_result = claripy.BVV(0x1234123412341234, 64)
    assert s.solver.is_true(calc_result == correct_result)

    calc_result = translate(s, "Iop_Dup16x8", (ll, ))
    correct_result = claripy.BVV(0x12341234123412341234123412341234, 128)
    assert s.solver.is_true(calc_result == correct_result)

    calc_result = translate(s, "Iop_Dup32x2", (m, ))
    correct_result = claripy.BVV(0x1234567812345678, 64)
    assert s.solver.is_true(calc_result == correct_result)

    calc_result = translate(s, "Iop_Dup32x4", (m, ))
    correct_result = claripy.BVV(0x12345678123456781234567812345678, 128)
    assert s.solver.is_true(calc_result == correct_result)

    n = claripy.BVV(0x0123456789ABCDEF, 64)
    o = claripy.BVV(0xAF, 8)
    p = claripy.BVV(0xDFEC, 16)
    q = claripy.BVV(0xBFCFDFEF, 32)
    r = claripy.BVV(0x0102030405060708, 64)
    ss = claripy.BVS("index", 8)

    # According to the source code of LibVex, the index is a U8 constant
    calc_result = translate(s, "Iop_GetElem8x8", (n, claripy.BVV(0, 8)))
    correct_result = claripy.BVV(0xEF, 8)
    assert s.solver.is_true(calc_result == correct_result)

    calc_result = translate(s, "Iop_GetElem8x8", (n, claripy.BVV(1, 8)))
    correct_result = claripy.BVV(0xCD, 8)
    assert s.solver.is_true(calc_result == correct_result)

    calc_result = translate(s, "Iop_GetElem8x8", (n, claripy.BVV(6, 8)))
    correct_result = claripy.BVV(0x23, 8)
    assert s.solver.is_true(calc_result == correct_result)

    calc_result = translate(s, "Iop_GetElem8x8", (n, claripy.BVV(7, 8)))
    correct_result = claripy.BVV(0x01, 8)
    assert s.solver.is_true(calc_result == correct_result)

    calc_result = translate(s, "Iop_GetElem16x4", (n, claripy.BVV(0, 8)))
    correct_result = claripy.BVV(0xCDEF, 16)
    assert s.solver.is_true(calc_result == correct_result)

    calc_result = translate(s, "Iop_GetElem16x4", (n, claripy.BVV(3, 8)))
    correct_result = claripy.BVV(0x0123, 16)
    assert s.solver.is_true(calc_result == correct_result)

    calc_result = translate(s, "Iop_GetElem32x2", (n, claripy.BVV(0, 8)))
    correct_result = claripy.BVV(0x89ABCDEF, 32)
    assert s.solver.is_true(calc_result == correct_result)

    calc_result = translate(s, "Iop_GetElem32x2", (n, claripy.BVV(1, 8)))
    correct_result = claripy.BVV(0x01234567, 32)
    assert s.solver.is_true(calc_result == correct_result)

    calc_result = translate(s, "Iop_SetElem8x8", (n, claripy.BVV(0, 8), o))
    correct_result = claripy.BVV(0x0123456789ABCDAF, 64)
    assert s.solver.is_true(calc_result == correct_result)

    calc_result = translate(s, "Iop_SetElem8x8", (n, claripy.BVV(1, 8), o))
    correct_result = claripy.BVV(0x0123456789ABAFEF, 64)
    assert s.solver.is_true(calc_result == correct_result)

    calc_result = translate(s, "Iop_SetElem8x8", (n, claripy.BVV(6, 8), o))
    correct_result = claripy.BVV(0x01AF456789ABCDEF, 64)
    assert s.solver.is_true(calc_result == correct_result)

    calc_result = translate(s, "Iop_SetElem8x8", (n, claripy.BVV(7, 8), o))
    correct_result = claripy.BVV(0xAF23456789ABCDEF, 64)
    assert s.solver.is_true(calc_result == correct_result)

    calc_result = translate(s, "Iop_SetElem16x4", (n, claripy.BVV(0, 8), p))
    correct_result = claripy.BVV(0x0123456789ABDFEC, 64)
    assert s.solver.is_true(calc_result == correct_result)

    calc_result = translate(s, "Iop_SetElem16x4", (n, claripy.BVV(3, 8), p))
    correct_result = claripy.BVV(0xDFEC456789ABCDEF, 64)
    assert s.solver.is_true(calc_result == correct_result)

    calc_result = translate(s, "Iop_SetElem32x2", (n, claripy.BVV(0, 8), q))
    correct_result = claripy.BVV(0x01234567BFCFDFEF, 64)
    assert s.solver.is_true(calc_result == correct_result)

    calc_result = translate(s, "Iop_SetElem32x2", (n, claripy.BVV(1, 8), q))
    correct_result = claripy.BVV(0xBFCFDFEF89ABCDEF, 64)
    assert s.solver.is_true(calc_result == correct_result)

    # Symbolic indexes
    calc_result = translate(ss, "Iop_GetElem8x8", (r, ss))
    correct_result = claripy.If(
        ss == 7,
        claripy.BVV(0x01, 8),
        claripy.If(
            ss == 6,
            claripy.BVV(0x02, 8),
            claripy.If(
                ss == 5,
                claripy.BVV(0x03, 8),
                claripy.If(
                    ss == 4,
                    claripy.BVV(0x04, 8),
                    claripy.If(
                        ss == 3,
                        claripy.BVV(0x05, 8),
                        claripy.If(
                            ss == 2,
                            claripy.BVV(0x06, 8),
                            claripy.If(ss == 1, claripy.BVV(0x07, 8),
                                       claripy.BVV(0x08, 8)),
                        ),
                    ),
                ),
            ),
        ),
    )
    assert s.solver.is_true(calc_result == correct_result)

    calc_result = translate(s, "Iop_GetElem16x4", (r, ss))
    correct_result = claripy.If(
        ss == 3,
        claripy.BVV(0x0102, 16),
        claripy.If(
            ss == 2,
            claripy.BVV(0x0304, 16),
            claripy.If(ss == 1, claripy.BVV(0x0506, 16),
                       claripy.BVV(0x0708, 16)),
        ),
    )
    assert s.solver.is_true(calc_result == correct_result)

    calc_result = translate(s, "Iop_GetElem32x2", (r, ss))
    correct_result = claripy.If(ss == 1, claripy.BVV(0x01020304, 32),
                                claripy.BVV(0x05060708, 32))
    assert s.solver.is_true(calc_result == correct_result)

    r_slices = r.chop(8)
    calc_result = translate(s, "Iop_SetElem8x8", (r, ss, o))
    correct_result = claripy.Concat(
        claripy.If(ss == 7, o, r_slices[0]),
        claripy.If(ss == 6, o, r_slices[1]),
        claripy.If(ss == 5, o, r_slices[2]),
        claripy.If(ss == 4, o, r_slices[3]),
        claripy.If(ss == 3, o, r_slices[4]),
        claripy.If(ss == 2, o, r_slices[5]),
        claripy.If(ss == 1, o, r_slices[6]),
        claripy.If(ss == 0, o, r_slices[7]),
    )
    assert s.solver.is_true(calc_result == correct_result)

    r_slices = r.chop(16)
    calc_result = translate(s, "Iop_SetElem16x4", (r, ss, p))
    correct_result = claripy.Concat(
        claripy.If(ss == 3, p, r_slices[0]),
        claripy.If(ss == 2, p, r_slices[1]),
        claripy.If(ss == 1, p, r_slices[2]),
        claripy.If(ss == 0, p, r_slices[3]),
    )
    assert s.solver.is_true(calc_result == correct_result)

    r_slices = r.chop(32)
    calc_result = translate(s, "Iop_SetElem32x2", (r, ss, q))
    correct_result = claripy.Concat(
        claripy.If(ss == 1, q, r_slices[0]),
        claripy.If(ss == 0, q, r_slices[1]),
    )
    assert s.solver.is_true(calc_result == correct_result)
Exemple #24
0
#!/usr/bin/env python3
import angr
import claripy

p = angr.Project('./angrme')

base = 0x400000

flag_chars = [claripy.BVS('flag_%d' % i, 8) for i in range(0x24)]
flag = claripy.Concat(*flag_chars + [claripy.BVV(b'\n')])

state = p.factory.entry_state(stdin=flag)
sm = p.factory.simulation_manager(state)

good = base + 0x2370
bad = base + 0x2390
sm.explore(find=good, avoid=bad)

print(sm.found[0].posix.dumps(0))
Exemple #25
0
#!/usr/bin/env python3
import time
import angr
import claripy

before = time.time()

binary = "./dist/tellme"
proj = angr.Project(binary)

start = claripy.BVV(b"flag{")
flag = claripy.BVS("flag", 16 * 8)
end = claripy.BVV(b"}\n")
flagsym = claripy.Concat(start, flag, end)

opts = angr.options.unicorn.union({"ZERO_FILL_UNCONSTRAINED_REGISTERS"})
state = proj.factory.full_init_state(args=[binary],
                                     add_options=opts,
                                     stdin=flagsym)

for c in flag.chop(8):
    state.solver.add(c != 0)
    state.solver.add(c != ord("\n"))
    state.solver.add(c >= ord(" "))
    state.solver.add(c <= ord("~"))

simman = proj.factory.simulation_manager(state)
#simman.explore(find=lambda s: b"You got it!" in s.posix.dumps(1))
simman.explore(find=0x004014aa, avoid=[0x004014b8])
for s in simman.found:
    print(s.solver.eval(flagsym, cast_to=bytes))
Exemple #26
0
    def _cgc_prepare_paths(self, state=None):
        '''
        prepare the initial paths for CGC binaries
        :param state: optional state to use instead of preparing a fresh one
        '''

        # FixedRandom, FixedInReceive, and FixedOutTransmit always are applied as defaults
        simuvex.SimProcedures['cgc']['random'] = FixedRandom
        simuvex.SimProcedures['cgc']['receive'] = FixedInReceive
        simuvex.SimProcedures['cgc']['transmit'] = FixedOutTransmit

        # if we're in crash mode we want the authentic system calls
        if not self.crash_mode:
            self._set_cgc_simprocedures()

        project = angr.Project(self.binary)

        self._set_hooks(project)

        if not self.pov:
            fs = {'/dev/stdin': simuvex.storage.file.SimFile(
                "/dev/stdin", "r",
                size=len(self.input))}

        else:
            fs = self._prepare_dialogue()

        entry_state = None
        if state is None:
            options = set()
            options.add(so.CGC_ZERO_FILL_UNCONSTRAINED_MEMORY)
            options.add(so.CGC_NO_SYMBOLIC_RECEIVE_LENGTH)
            options.add(so.REPLACEMENT_SOLVER)
            options.add(so.UNICORN_THRESHOLD_CONCRETIZATION)

            # try to enable unicorn, continue if it doesn't exist
            try:
                options.add(so.UNICORN)
                options.add(so.UNICORN_SYM_REGS_SUPPORT)
                self.unicorn_enabled = True
                l.debug("unicorn tracing enabled")
            except AttributeError:
                pass

            self.remove_options |= so.simplification | set(so.LAZY_SOLVES) | set(so.SUPPORT_FLOATING_POINT)
            self.add_options |= options
            entry_state = project.factory.entry_state(
                fs=fs,
                add_options=self.add_options,
                remove_options=self.remove_options)

            csr = entry_state.unicorn.cooldown_symbolic_registers
            entry_state.unicorn.concretization_threshold_registers = 25000 / csr
            entry_state.unicorn.concretization_threshold_memory = 25000 / csr
        else:
            # hookup the new files
            for name in fs:
                fs[name].set_state(state)
                for fd in state.posix.files:
                    if state.posix.files[fd].name == name:
                        state.posix.files[fd] = fs[name]
                        break

            state.scratch.executed_block_count = 0

            for option in self.add_options:
                state.options.add(option)

            for option in self.remove_options:
                state.options.discard(option)

            entry_state = state

        if not self.pov:
            entry_state.cgc.input_size = len(self.input)

        if len(self._hooks):
            self._set_simproc_limits(entry_state)

        # preconstrain flag page
        self._preconstrain_flag_page(entry_state, self.cgc_flag_bytes)
        entry_state.memory.store(0x4347c000, claripy.Concat(*self.cgc_flag_bytes))

        pg = project.factory.path_group(
            entry_state,
            immutable=True,
            save_unsat=True,
            hierarchy=False,
            save_unconstrained=self.crash_mode)

        pg.use_technique(angr.exploration_techniques.Oppologist())
        l.info("oppologist enabled")

        return pg
# cek = [0x5B,0x43,0x6D,0x67,0x1C,0x38,0x10,0x33,0x14,0x52,0x33,0x7A,0x27,0x1B,0x3D,0x3D,0x40,0x6A,0x0F,0x68,0x60,0x0C,0x6E,0x5C,0x19,0x58,0x3D,0x46,0x5C,0x79,0x67,0x6F,0x5E,0x51,0x49,0x65,0x6B,0x7D,0x18,0x6B,0x7C,0x78,0x58,0x74,0x4B,0x27,0x27,0x50,0x1D,0x58,0x2E,0x6F,0x45,0x10,0x3A,0x5A,0x1C,0x7D,0x20,0x53,0x64,0x4B,0x31,0x20,0x46,0x74,0x38,0x5A,0x9,0x0D,0x59,0x38,0x11,0x24,0x18,0x46,0x15,0x1B,0x44,0x66,0x5A,0x15,0x1E,0x66,0x39,0x5C,0x6D,0x1A,0x0C,0x29,0x5C,0x4B,0x31,0x71,0x10,0x5B,0x1,0x7B,0x16,0x61,0x6,0x9,0x0B,0x1B,0x7E,0x42,0x2B,0x10,0x1E,0x55,0x5E,0x62,0x2,0x74,0x2A,0x0B,0x15,0x75,0x79,0x1C,0x59,0x5D,0x18,0x79,0x40,0x5,0x2E,0x29,0x1B,0x3,0x3C,0x2,0x23,0x41,0x2F,0x2E,0x6,0x9,0x77,0x65,0x3E,0x2C,0x6E,0x6D,0x43,0x7,0x9,0x76,0x4,0x2D,0x53,0x43,0x35,0x6F,0x54,0x10,0x1C,0x62,0x0,0x3E,0x12,0x2D,0x68,0x5E,0x5,0x57,0x49,0x59,0x57,0x40,0x62,0x10,0x62,0x14,0x78,0x59,0x61,0x62,0x6E,0x2,0x7C,0x30,0x4C,0x4C,0x49,0x18,0x4,0x1B,0x51,0x4B,0x1C,0x4E,0x19,0x4E,0x2E,0x2D,0x42,0x3,0x10,0x46,0x33,0x46,0x4C,0x7,0x41,0x6,0x38,0x6A,0x13,0x46,0x71,0x12,0x18,0x26,0x3F,0x42,0x5D,0x47,0x39,0x11,0x11,0x58,0x3A,0x7D,0x22,0x35,0x5E,0x45,0x34,0x48,0x59,0x37,0x68,0x7A,0x49,0x78,0x28,0x39,0x52,0x48,0x56,0x0B,0x1C,0x4C,0x75,0x7A,0x17,0x17,0x0B,0x47,0x3D,0x6F,0x3C,0x3A,0x20,0x31,0x51,0x43,0x18,0x64,0x20,0x27,0x6E,0x7A,0x11,0x4C,0x18,0x69,0x67,0x4F,0x6C,0x31,0x2B,0x23,0x39,0x71,0x49,0x75,0x66,0x6C,0x51,0x3A,0x62,0x3C,0x5A,0x68,0x14,0x42,0x72,0x27,0x0E,0x24,0x71,0x4B,0x72,0x25,0x20,0x0A,0x5A,0x34,0x37,0x70,0x48,0x2B,0x30,0x8,0x74,0x60,0x65,0x47,0x65,0x5,0x51,0x74,0x65,0x2F,0x43,0x6E,0x4,0x76,0x1F,0x5C,0x26,0x43,0x0F,0x6E,0x53,0x29,0x40,0x66,0x35,0x23,0x4,0x42,0x5,0x1B,0x23,0x65,0x55,0x9,0x1A,0x0,0x31,0x6A,0x15,0x22,0x18,0x78,0x65,0x64,0x49,0x3E,0x53,0x4F,0x47,0x49,0x0F,0x18,0x55,0x2C,0x21,0x49,0x1,0x17,0x2F,0x6E,0x63,0x7B,0x5B,0x3B,0x32,0x2,0x6A,0x13,0x66,0x26,0x3B,0x18,0x24,0x39,0x2C,0x3F,0x66,0x74,0x63,0x26,0x1A,0x10,0x8,0x43,0x71,0x38,0x6D,0x29,0x1E,0x2D,0x41,0x56,0x38,0x40,0x4A,0x37,0x5F,0x57,0x29,0x49,0x41,0x74,0x4A,0x1B,0x9,0x69,0x59,0x3A,0x2,0x1B,0x9,0x6B,0x71,0x4C,0x55,0x3C,0x5B,0x6A,0x7B,0x32,0x74,0x52,0x0E,0x33,0x0F,0x18,0x7E,0x5A,0x4D,0x20,0x55,0x4A,0x34,0x0E,0x7A,0x66,0x42,0x3B,0x5E,0x68,0x5F,0x4A,0x28,0x16,0x38,0x4,0x55,0x54,0x1A,0x5,0x1B,0x52,0x2,0x40,0x79,0x56,0x6D,0x23,0x7,0x73,0x1,0x67,0x58,0x51,0x0F,0x54,0x23,0x2D,0x11,0x48,0x15,0x4E,0x55,0x3F,0x3C,0x24,0x28,0x10,0x2A,0x4E,0x26,0x38,0x2F,0x0C,0x4E,0x74,0x5B,0x6C,0x2A,0x61,0x6,0x0C,0x12,0x42,0x23,0x4,0x63,0x38,0x3B,0x55,0x1F,0x67,0x26,0x38,0x4F,0x1,0x26,0x29,0x2B,0x4A,0x1C,0x0E,0x2F,0x7B,0x30,0x26,0x3D,0x6B,0x3,0x3F,0x6C,0x28,0x7C,0x62,0x6C,0x44,0x66,0x2B,0x54,0x50,0x0F,0x6C,0x38,0x45,0x6A,0x41,0x41,0x0B,0x73,0x78,0x60,0x2F,0x12,0x40,0x53,0x15,0x8,0x1C,0x1D,0x2B,0x0,0x5E,0x30,0x49,0x3E,0x64,0x0B,0x19,0x72,0x1,0x11,0x79,0x29,0x0A,0x17,0x2,0x6,0x4C,0x29,0x58,0x23,0x55,0x32,0x38,0x7E,0x65,0x5,0x26,0x37,0x5B,0x13,0x7,0x16,0x5,0x0D,0x0A,0x6D,0x59,0x73,0x71,0x64,0x74,0x48,0x42,0x57,0x48,0x20,0x25,0x73,0x30,0x1B,0x22,0x23,0x0B,0x70,0x3E,0x4C,0x31,0x7D,0x41,0x36,0x46,0x58,0x7C,0x2C,0x4,0x0A,0x71,0x3,0x34,0x3B,0x4A,0x1A,0x47,0x10,0x3A,0x67,0x1F,0x51,0x6F,0x44,0x70,0x73,0x32,0x6B,0x22,0x13,0x64,0x77,0x72,0x6,0x17,0x66,0x31,0x38,0x2F,0x0E,0x54,0x50,0x61,0x7E,0x74,0x74,0x25,0x0B,0x48,0x7C,0x5F,0x0C,0x25,0x3F,0x75,0x51,0x11,0x19,0x3F,0x44,0x27,0x25,0x79,0x64,0x6E,0x68,0x41,0x37,0x50,0x9,0x1A,0x4F,0x5D,0x72,0x71,0x52,0x6E,0x17,0x0C,0x25,0x5D,0x26,0x21,0x0F,0x6A,0x3E,0x2E,0x3B,0x4B,0x1A,0x0B,0x54,0x6,0x38,0x60,0x25,0x55,0x3C,0x3,0x2C,0x6D,0x77,0x5A,0x3A,0x73,0x17,0x79,0x2B,0x4A,0x54,0x33,0x69,0x46,0x62,0x77,0x0D,0x50,0x73,0x2C,0x12,0x5E,0x3A,0x5D,0x3F,0x64,0x0F,0x40,0x2E,0x64,0x59,0x6E,0x1D,0x67,0x1A,0x16,0x1C,0x0B,0x14,0x10,0x5F,0x17,0x3,0x28,0x45,0x54,0x23,0x5,0x5D,0x69,0x79,0x0C,0x72,0x5,0x1E,0x19,0x51,0x4E,0x5,0x23,0x6A,0x0F,0x35,0x5B,0x7B,0x23,0x5C,0x19,0x2F,0x51,0x53,0x7A,0x75,0x58,0x18,0x5B,0x3A,0x2,0x42,0x53,0x15,0x42,0x1B,0x0,0x1F,0x21,0x61,0x66,0x25,0x1,0x39,0x63,0x4D,0x1,0x75,0x51,0x4A,0x5F,0x8,0x4B,0x12,0x56,0x8,0x0F,0x3E,0x11,0x40,0x68,0x8,0x7C,0x19,0x0E,0x4F,0x21,0x1E,0x7D,0x12,0x3A,0x4B,0x5A,0x51,0x65,0x18,0x7E,0x1B,0x7B,0x66]
# cek2 = [0x53,0x62,0x2,0x59,0x51,0x73,0x30,0x40,0x6,0x15,0x6A,0x55,0x29,0x9,0x4E,0x6A,0x76,0x2C,0x61,0x5B,0x12,0x79,0x6D,0x72,0x1E,0x2F,0x3F,0x34,0x6E]

import angr
import claripy

FLAG_LEN = 28
STDIN_FD = 0

base_addr = 0x8049000

proj = angr.Project("./soal",main_opts={'base_addr':base_addr})
flag_chars = [claripy.BVS('flag_%d' % i, 8) for i in range(FLAG_LEN)]
flag = claripy.Concat( *flag_chars + [claripy.BVV(b'\n')]) # Add \n for scanf() to accept the input

state = proj.factory.full_init_state(
        args=['./soal'],
        add_options=angr.options.unicorn,
        stdin=flag,
)

# Add constraints that all characters are printable
for k in flag_chars:
    state.solver.add(k >= ord('!'))
    state.solver.add(k <= ord('~'))

simgr = proj.factory.simulation_manager(state)
find_addr  = 0x080490C5 # SUCCESS
avoid_addr = 0x080490DD # FAILURE
simgr.explore(find=find_addr, avoid=avoid_addr)
Exemple #28
0
def test_vsa_constraint_to_si():
    # Set backend
    b = claripy.backends.vsa
    s = claripy.SolverVSA() #pylint:disable=unused-variable

    SI = claripy.SI
    BVV = claripy.BVV

    claripy.vsa.strided_interval.allow_dsis = False

    #
    # If(SI == 0, 1, 0) == 1
    #

    s1 = claripy.SI(bits=32, stride=1, lower_bound=0, upper_bound=2)
    ast_true = (claripy.If(s1 == BVV(0, 32), BVV(1, 1), BVV(0, 1)) == BVV(1, 1))
    ast_false = (claripy.If(s1 == BVV(0, 32), BVV(1, 1), BVV(0, 1)) != BVV(1, 1))

    trueside_sat, trueside_replacement = b.constraint_to_si(ast_true)
    nose.tools.assert_equal(trueside_sat, True)
    nose.tools.assert_equal(len(trueside_replacement), 1)
    nose.tools.assert_true(trueside_replacement[0][0] is s1)
    # True side: claripy.SI<32>0[0, 0]
    nose.tools.assert_true(
        claripy.backends.vsa.is_true(trueside_replacement[0][1] == claripy.SI(bits=32, stride=0, lower_bound=0, upper_bound=0)))

    falseside_sat, falseside_replacement = b.constraint_to_si(ast_false)
    nose.tools.assert_equal(falseside_sat, True)
    nose.tools.assert_equal(len(falseside_replacement), 1)
    nose.tools.assert_true(falseside_replacement[0][0] is s1)
    # False side; claripy.SI<32>1[1, 2]

    nose.tools.assert_true(
        claripy.backends.vsa.identical(falseside_replacement[0][1], SI(bits=32, stride=1, lower_bound=1, upper_bound=2))
    )

    #
    # If(SI == 0, 1, 0) <= 1
    #

    s1 = SI(bits=32, stride=1, lower_bound=0, upper_bound=2)
    ast_true = (claripy.If(s1 == BVV(0, 32), BVV(1, 1), BVV(0, 1)) <= BVV(1, 1))
    ast_false = (claripy.If(s1 == BVV(0, 32), BVV(1, 1), BVV(0, 1)) > BVV(1, 1))

    trueside_sat, trueside_replacement = b.constraint_to_si(ast_true)
    nose.tools.assert_equal(trueside_sat, True) # Always satisfiable

    falseside_sat, falseside_replacement = b.constraint_to_si(ast_false)
    nose.tools.assert_equal(falseside_sat, False) # Not sat

    #
    # If(SI == 0, 20, 10) > 15
    #

    s1 = SI(bits=32, stride=1, lower_bound=0, upper_bound=2)
    ast_true = (claripy.If(s1 == BVV(0, 32), BVV(20, 32), BVV(10, 32)) > BVV(15, 32))
    ast_false = (claripy.If(s1 == BVV(0, 32), BVV(20, 32), BVV(10, 32)) <= BVV(15, 32))

    trueside_sat, trueside_replacement = b.constraint_to_si(ast_true)
    nose.tools.assert_equal(trueside_sat, True)
    nose.tools.assert_equal(len(trueside_replacement), 1)
    nose.tools.assert_true(trueside_replacement[0][0] is s1)
    # True side: SI<32>0[0, 0]
    nose.tools.assert_true(
        claripy.backends.vsa.identical(trueside_replacement[0][1], SI(bits=32, stride=0, lower_bound=0, upper_bound=0))
    )

    falseside_sat, falseside_replacement = b.constraint_to_si(ast_false)
    nose.tools.assert_equal(falseside_sat, True)
    nose.tools.assert_equal(len(falseside_replacement), 1)
    nose.tools.assert_true(falseside_replacement[0][0] is s1)
    # False side; SI<32>1[1, 2]
    nose.tools.assert_true(
        claripy.backends.vsa.identical(falseside_replacement[0][1], SI(bits=32, stride=1, lower_bound=1, upper_bound=2))
    )

    #
    # If(SI == 0, 20, 10) >= 15
    #

    s1 = SI(bits=32, stride=1, lower_bound=0, upper_bound=2)
    ast_true = (claripy.If(s1 == BVV(0, 32), BVV(15, 32), BVV(10, 32)) >= BVV(15, 32))
    ast_false = (claripy.If(s1 == BVV(0, 32), BVV(15, 32), BVV(10, 32)) < BVV(15, 32))

    trueside_sat, trueside_replacement = b.constraint_to_si(ast_true)
    nose.tools.assert_equal(trueside_sat, True)
    nose.tools.assert_equal(len(trueside_replacement), 1)
    nose.tools.assert_true(trueside_replacement[0][0] is s1)
    # True side: SI<32>0[0, 0]
    nose.tools.assert_true(
        claripy.backends.vsa.identical(trueside_replacement[0][1], SI(bits=32, stride=0, lower_bound=0, upper_bound=0))
    )

    falseside_sat, falseside_replacement = b.constraint_to_si(ast_false)
    nose.tools.assert_equal(falseside_sat, True)
    nose.tools.assert_equal(len(falseside_replacement), 1)
    nose.tools.assert_true(falseside_replacement[0][0] is s1)
    # False side; SI<32>0[0,0]
    nose.tools.assert_true(
        claripy.backends.vsa.identical(falseside_replacement[0][1], SI(bits=32, stride=1, lower_bound=1, upper_bound=2))
    )

    #
    # Extract(0, 0, Concat(BVV(0, 63), If(SI == 0, 1, 0))) == 1
    #

    s2 = claripy.SI(bits=32, stride=1, lower_bound=0, upper_bound=2)
    ast_true = (claripy.Extract(0, 0, claripy.Concat(BVV(0, 63), claripy.If(s2 == 0, BVV(1, 1), BVV(0, 1)))) == 1)
    ast_false = (claripy.Extract(0, 0, claripy.Concat(BVV(0, 63), claripy.If(s2 == 0, BVV(1, 1), BVV(0, 1)))) != 1)

    trueside_sat, trueside_replacement = b.constraint_to_si(ast_true)
    nose.tools.assert_equal(trueside_sat, True)
    nose.tools.assert_equal(len(trueside_replacement), 1)
    nose.tools.assert_true(trueside_replacement[0][0] is s2)
    # True side: claripy.SI<32>0[0, 0]
    nose.tools.assert_true(
        claripy.backends.vsa.identical(trueside_replacement[0][1], SI(bits=32, stride=0, lower_bound=0, upper_bound=0))
    )

    falseside_sat, falseside_replacement = b.constraint_to_si(ast_false)
    nose.tools.assert_equal(falseside_sat, True)
    nose.tools.assert_equal(len(falseside_replacement), 1)
    nose.tools.assert_true(falseside_replacement[0][0] is s2)
    # False side; claripy.SI<32>1[1, 2]
    nose.tools.assert_true(
        claripy.backends.vsa.identical(falseside_replacement[0][1], SI(bits=32, stride=1, lower_bound=1, upper_bound=2))
    )

    #
    # Extract(0, 0, ZeroExt(32, If(SI == 0, BVV(1, 32), BVV(0, 32)))) == 1
    #

    s3 = claripy.SI(bits=32, stride=1, lower_bound=0, upper_bound=2)
    ast_true = (claripy.Extract(0, 0, claripy.ZeroExt(32, claripy.If(s3 == 0, BVV(1, 32), BVV(0, 32)))) == 1)
    ast_false = (claripy.Extract(0, 0, claripy.ZeroExt(32, claripy.If(s3 == 0, BVV(1, 32), BVV(0, 32)))) != 1)

    trueside_sat, trueside_replacement = b.constraint_to_si(ast_true)
    nose.tools.assert_equal(trueside_sat, True)
    nose.tools.assert_equal(len(trueside_replacement), 1)
    nose.tools.assert_true(trueside_replacement[0][0] is s3)
    # True side: claripy.SI<32>0[0, 0]
    nose.tools.assert_true(
        claripy.backends.vsa.identical(trueside_replacement[0][1], SI(bits=32, stride=0, lower_bound=0, upper_bound=0))
    )

    falseside_sat, falseside_replacement = b.constraint_to_si(ast_false)
    nose.tools.assert_equal(falseside_sat, True)
    nose.tools.assert_equal(len(falseside_replacement), 1)
    nose.tools.assert_true(falseside_replacement[0][0] is s3)
    # False side; claripy.SI<32>1[1, 2]
    nose.tools.assert_true(
        claripy.backends.vsa.identical(falseside_replacement[0][1], SI(bits=32, stride=1, lower_bound=1, upper_bound=2))
    )

    #
    # Extract(0, 0, ZeroExt(32, If(Extract(32, 0, (SI & claripy.SI)) < 0, BVV(1, 1), BVV(0, 1))))
    #

    s4 = claripy.SI(bits=64, stride=1, lower_bound=0, upper_bound=0xffffffffffffffff)
    ast_true = (
        claripy.Extract(0, 0, claripy.ZeroExt(32, claripy.If(claripy.Extract(31, 0, (s4 & s4)).SLT(0), BVV(1, 32), BVV(0, 32)))) == 1)
    ast_false = (
        claripy.Extract(0, 0, claripy.ZeroExt(32, claripy.If(claripy.Extract(31, 0, (s4 & s4)).SLT(0), BVV(1, 32), BVV(0, 32)))) != 1)

    trueside_sat, trueside_replacement = b.constraint_to_si(ast_true)
    nose.tools.assert_equal(trueside_sat, True)
    nose.tools.assert_equal(len(trueside_replacement), 1)
    nose.tools.assert_true(trueside_replacement[0][0] is s4[31:0])
    # True side: claripy.SI<32>0[0, 0]
    nose.tools.assert_true(
        claripy.backends.vsa.identical(trueside_replacement[0][1], SI(bits=32, stride=1, lower_bound=-0x80000000, upper_bound=-1))
    )

    falseside_sat, falseside_replacement = b.constraint_to_si(ast_false)
    nose.tools.assert_equal(falseside_sat, True)
    nose.tools.assert_equal(len(falseside_replacement), 1)
    nose.tools.assert_true(falseside_replacement[0][0] is s4[31:0])
    # False side; claripy.SI<32>1[1, 2]
    nose.tools.assert_true(
        claripy.backends.vsa.identical(falseside_replacement[0][1], SI(bits=32, stride=1, lower_bound=0, upper_bound=0x7fffffff))
    )

    #
    # TOP_SI != -1
    #

    s5 = claripy.SI(bits=32, stride=1, lower_bound=0, upper_bound=0xffffffff)
    ast_true = (s5 == claripy.SI(bits=32, stride=1, lower_bound=0xffffffff, upper_bound=0xffffffff))
    ast_false = (s5 != claripy.SI(bits=32, stride=1, lower_bound=0xffffffff, upper_bound=0xffffffff))

    trueside_sat, trueside_replacement = b.constraint_to_si(ast_true)
    nose.tools.assert_true(trueside_sat)
    nose.tools.assert_equal(len(trueside_replacement), 1)
    nose.tools.assert_true(trueside_replacement[0][0] is s5)
    nose.tools.assert_true(claripy.backends.vsa.identical(trueside_replacement[0][1],
                                                          SI(bits=32, stride=1, lower_bound=0xffffffff,
                                                             upper_bound=0xffffffff)
                                                          )
                           )

    falseside_sat, falseside_replacement = b.constraint_to_si(ast_false)
    nose.tools.assert_true(falseside_sat)
    nose.tools.assert_equal(len(falseside_replacement), 1)
    nose.tools.assert_true(falseside_replacement[0][0] is s5)
    nose.tools.assert_true(claripy.backends.vsa.identical(falseside_replacement[0][1],
                                                          SI(bits=32, stride=1, lower_bound=0,
                                                             upper_bound=0xfffffffe)
                                                          )
                           )
Exemple #29
0
    def _standardize_value(arg, ty, state, alloc):
        check = ty is not None
        if isinstance(arg, SimActionObject):
            return SimCC._standardize_value(arg.ast, ty, state, alloc)
        elif isinstance(arg, PointerWrapper):
            if check and not isinstance(ty, SimTypePointer):
                raise TypeError("Type mismatch: expected %s, got pointer-wrapper" % ty.name)

            real_value = SimCC._standardize_value(arg.value, ty.pts_to if check else None, state, alloc)
            return alloc(real_value, state)

        elif isinstance(arg, str):
            # TODO: when we switch to py3, distinguish between str and bytes
            # by null-terminating str but not bytes :/
            arg += '\0'
            ref = False
            if check:
                if isinstance(ty, SimTypePointer) and \
                        isinstance(ty.pts_to, SimTypeChar):
                    ref = True
                elif isinstance(ty, SimTypeFixedSizeArray) and \
                        isinstance(ty.elem_type, SimTypeChar):
                    ref = False
                    if len(arg) > ty.length:
                        raise TypeError("String %s is too long for %s" % (repr(arg), ty.name))
                    arg = arg.ljust(ty.length, '\0')
                elif isinstance(ty, SimTypeArray) and \
                        isinstance(ty.elem_type, SimTypeChar):
                    ref = True
                    if ty.length is not None:
                        if len(arg) > ty.length:
                            raise TypeError("String %s is too long for %s" % (repr(arg), ty.name))
                        arg = arg.ljust(ty.length, '\0')
                elif isinstance(ty, SimTypeString):
                    ref = False
                    if len(arg) > ty.length + 1:
                        raise TypeError("String %s is too long for %s" % (repr(arg), ty.name))
                    arg = arg.ljust(ty.length + 1, '\0')
                else:
                    raise TypeError("Type mismatch: Expected %s, got char*" % ty.name)
            val = SimCC._standardize_value(map(ord, arg), SimTypeFixedSizeArray(SimTypeChar(), len(arg)), state, alloc)
            if ref:
                val = alloc(val, state)
            return val

        elif isinstance(arg, list):
            ref = False
            subty = None
            if check:
                if isinstance(ty, SimTypePointer):
                    ref = True
                    subty = ty.pts_to
                elif isinstance(ty, SimTypeFixedSizeArray):
                    ref = False
                    subty = ty.elem_type
                    if len(arg) != ty.length:
                        raise TypeError("Array %s is the wrong length for %s" % (repr(arg), ty.name))
                elif isinstance(ty, SimTypeArray):
                    ref = True
                    subty = ty.elem_type
                    if ty.length is not None:
                        if len(arg) != ty.length:
                            raise TypeError("Array %s is the wrong length for %s" % (repr(arg), ty.name))
                else:
                    raise TypeError("Type mismatch: Expected %s, got char*" % ty.name)
            else:
                types = map(type, arg)
                if types[1:] != types[:-1]:
                    raise TypeError("All elements of list must be of same type")

            val = claripy.Concat(*[SimCC._standardize_value(sarg, subty, state, alloc) for sarg in arg])
            if ref:
                val = alloc(val, state)
            return val

        elif isinstance(arg, tuple):
            if check:
                if not isinstance(ty, SimStruct):
                    raise TypeError("Type mismatch: Expected %s, got tuple (i.e. struct)" % ty.name)
                if len(arg) != len(ty.fields):
                    raise TypeError("Wrong number of fields in struct, expected %d got %d" % (len(ty.fields), len(arg)))
                return claripy.Concat(*[SimCC._standardize_value(sarg, sty, state, alloc)
                                        for sarg, sty
                                        in zip(arg, ty.fields.values())])
            else:
                return claripy.Concat(*[SimCC._standardize_value(sarg, None, state, alloc) for sarg in arg])

        elif isinstance(arg, (int, long)):
            if check and isinstance(ty, SimTypeFloat):
                return SimCC._standardize_value(float(arg), ty, state, alloc)

            val = state.se.BVV(arg, ty.size if check else state.arch.bits)
            if state.arch.memory_endness == 'Iend_LE':
                val = val.reversed
            return val

        elif isinstance(arg, float):
            sort = claripy.FSORT_FLOAT
            if check:
                if isinstance(ty, SimTypeDouble):
                    sort = claripy.FSORT_DOUBLE
                elif isinstance(ty, SimTypeFloat):
                    pass
                else:
                    raise TypeError("Type mismatch: expectd %s, got float" % ty.name)
            else:
                sort = claripy.FSORT_DOUBLE if state.arch.bits == 64 else claripy.FSORT_FLOAT

            val = claripy.fpToIEEEBV(claripy.FPV(arg, sort))
            if state.arch.memory_endness == 'Iend_LE':
                val = val.reversed      # pylint: disable=no-member
            return val

        elif isinstance(arg, claripy.ast.FP):
            val = claripy.fpToIEEEBV(arg)
            if state.arch.memory_endness == 'Iend_LE':
                val = val.reversed      # pylint: disable=no-member
            return val

        elif isinstance(arg, claripy.ast.Base):
            # yikes
            if state.arch.memory_endness == 'Iend_LE' and arg.length == state.arch.bits:
                arg = arg.reversed
            return arg

        else:
            raise TypeError("I don't know how to serialize %s." % repr(arg))
Exemple #30
0
import re
from tqdm import tqdm
import claripy

# Define which rers problem we are solving
problem = "Problem11"
problemset = "TrainingSeqReachRers2019"

proj = angr.Project(f'rers/{problemset}/{problem}/{problem}')

# Restrict input
input_len = 8

# We create a bitvector representing stdin
input_chars = [claripy.BVS('inputbyte_%d' % i, 8) for i in range(input_len)]
sym_input = claripy.Concat(*input_chars)

# Setup the initial state, and point it to the symbolic input
state = proj.factory.entry_state(stdin=sym_input)
simgr = proj.factory.simgr(state)

# Add constraints on input bytes, we know the valid inputs (look at the rers code)
for k in input_chars:
    state.solver.add(k >= 0x01)
    state.solver.add(k <= 0x10)

# Explore for a few iterations
# Explore runs until a new state is found that satisfies the "find" condition,
# e.g. stderr contains the string "error"
n_iterations = 50