Exemple #1
0
    def run(self, dst, size, file_ptr):
        self.argument_types = {
            2: SimTypeFd(),
            0: self.ty_ptr(SimTypeArray(SimTypeChar(), size)),
            1: SimTypeLength(self.state.arch)
        }
        self.return_type = self.argument_types[0]

        # let's get the memory back for the file we're interested in and find the newline
        fd_offset = io_file_data_for_arch(self.state.arch)['fd']
        fd = self.state.mem[file_ptr + fd_offset:].int.resolved
        simfd = self.state.posix.get_fd(fd)
        if simfd is None:
            return -1

        data, real_size = simfd.read_data(size - 1)

        for i, byte in enumerate(data.chop(8)):
            self.state.solver.add(
                self.state.solver.If(
                    i + 1 != real_size,
                    byte != '\n',  # if not last byte returned, not newline
                    self.state.solver.
                    Or(  # otherwise one of the following must be true
                        i + 2 == size,  # we ran out of space, or
                        byte == '\n'  # it is a newline
                    )))

        self.state.memory.store(dst, data, size=real_size)
        self.state.memory.store(dst + real_size, '\0')

        return real_size
Exemple #2
0
def test_call_function_brancher():
    class NonLocal(object):
        the_state = None
        the_goal = None

    def goal_reached_callback(goal, p, pg):  # pylint:disable=unused-argument
        NonLocal.the_state = p
        NonLocal.the_goal = goal

    p = angr.Project(os.path.join(test_location, 'x86_64', 'brancher'),
                     load_options={'auto_load_libs': False})

    pg = p.factory.simulation_manager()

    # initialize the exploration technique
    dm = angr.exploration_techniques.Director(
        cfg_keep_states=True,
        goal_satisfied_callback=goal_reached_callback,
        num_fallback_states=1)
    _ = p.analyses.CFG()
    puts_func = p.kb.functions.function(name='puts')
    goal = angr.exploration_techniques.CallFunctionGoal(
        puts_func, [(SimTypePointer(SimTypeChar()), ">=20")])
    dm.add_goal(goal)
    pg.use_technique(dm)

    pg.explore(find=(0x40059e, ))

    assert len(pg.deprioritized) > 0
    assert len(pg.found) > 0
    assert NonLocal.the_state is not None
    assert NonLocal.the_goal is goal
Exemple #3
0
def test_stub_procedure_args():
    # stub procedures should have the right number of arguments

    lib.set_prototype(
        "____a_random_stdcall_function__",
        SimTypeFunction(
            [
                SimTypeInt(signed=True),
                SimTypeInt(signed=True),
                SimTypeInt(signed=False)
            ],
            SimTypePointer(SimTypeChar(), offset=0),
            arg_names=["_random_arg_0", "_random_arg_1", "_random_arg_2"]))
    stub = lib.get_stub('____a_random_stdcall_function__', archinfo.ArchX86())
    stub.cc = SimCCStdcall(archinfo.ArchX86())
    lib._apply_metadata(stub, archinfo.ArchX86())
    assert len(stub.cc.args) == 3
    assert all(isinstance(arg, SimStackArg) for arg in stub.cc.args)

    proj = angr.Project(os.path.join(binaries_base, "i386", "all"),
                        auto_load_libs=False)
    state = proj.factory.blank_state()

    initial_sp = state.regs.sp
    stub.state = state
    stub.successors = SimSuccessors(0, state)
    stub.ret(0)

    succ = stub.successors.all_successors[0]
    assert state.solver.eval_one(succ.regs.sp - initial_sp) == 0x10
Exemple #4
0
    def run(self, s_addr, c_int, s_strlen=None):
        c = c_int[7:0]

        self.argument_types = {0: self.ty_ptr(SimTypeString()),
                       1: SimTypeInt(32, True)} # ?
        self.return_type = self.ty_ptr(SimTypeChar()) # ?

        s_strlen = self.inline_call(angr.SIM_PROCEDURES['libc']['strlen'], s_addr)

        chunk_size = None
        if MEMORY_CHUNK_INDIVIDUAL_READS in self.state.options:
            chunk_size = 1

        if self.state.solver.symbolic(s_strlen.ret_expr):
            l.debug("symbolic strlen")
            # TODO: more constraints here to make sure we don't search too little
            max_sym = min(self.state.solver.max_int(s_strlen.ret_expr)+1, self.state.libc.max_symbolic_strchr)
            a, c, i = self.state.memory.find(s_addr, c, s_strlen.max_null_index, max_symbolic_bytes=max_sym, default=0)
        else:
            l.debug("concrete strlen")
            max_search = self.state.solver.eval(s_strlen.ret_expr)+1
            a, c, i = self.state.memory.find(s_addr, c, max_search, default=0, chunk_size=chunk_size)

        if len(i) > 1:
            a = a.annotate(MultiwriteAnnotation())
            self.state.add_constraints(*c)

        return a
Exemple #5
0
def run_fauxware(arch):
    addr = addresses_fauxware[arch]
    p = angr.Project(location + '/' + arch + '/fauxware')
    charstar = SimTypePointer(SimTypeChar())
    prototype = SimTypeFunction((charstar, charstar), SimTypeInt(False))
    cc = p.factory.cc(func_ty=prototype)
    authenticate = p.factory.callable(addr, toc=0x10018E80 if arch == 'ppc64' else None, concrete_only=True, cc=cc)
    nose.tools.assert_equal(authenticate("asdf", "SOSNEAKY")._model_concrete.value, 1)
    nose.tools.assert_raises(AngrCallableMultistateError, authenticate, "asdf", "NOSNEAKY")
Exemple #6
0
    def run(self, fd, dst, length):
        self.argument_types = {0: SimTypeFd(),
                               1: self.ty_ptr(SimTypeArray(SimTypeChar(), length)),
                               2: SimTypeLength(self.state.arch)}
        self.return_type = SimTypeLength(self.state.arch)

        simfd = self.state.posix.get_fd(fd)
        if simfd is None:
            return -1

        return simfd.read(dst, length)
Exemple #7
0
    def run(self, fd, dst, length):
        self.argument_types = {
            0: SimTypeFd(),
            1: self.ty_ptr(SimTypeArray(SimTypeChar(), length)),
            2: SimTypeLength(self.state.arch)
        }
        self.return_type = SimTypeLength(self.state.arch)

        # TODO handle errors
        length = self.state.posix.read(fd, dst, length)

        return length
Exemple #8
0
 def run_fauxware(self, arch):
     addr = addresses_fauxware[arch]
     p = angr.Project(os.path.join(location, 'tests', arch, 'fauxware'))
     charstar = SimTypePointer(SimTypeChar())
     prototype = SimTypeFunction((charstar, charstar), SimTypeInt(False))
     authenticate = p.factory.callable(
         addr,
         toc=0x10018E80 if arch == 'ppc64' else None,
         concrete_only=True,
         prototype=prototype)
     assert authenticate("asdf", "SOSNEAKY")._model_concrete.value == 1
     self.assertRaises(AngrCallableMultistateError, authenticate, "asdf",
                       "NOSNEAKY")
Exemple #9
0
    def run(self, fd, dst, length):
        self.argument_types = {
            0: SimTypeFd(),
            1: self.ty_ptr(SimTypeArray(SimTypeChar(), length)),
            2: SimTypeLength(self.state.arch)
        }
        self.return_type = SimTypeLength(self.state.arch)

        try:
            simfd = self.state.posix.get_fd(fd)
            if simfd is None:
                return -1

            return simfd.read(dst, length)
        except angr.SimUnsatError:
            return self.state.se.Unconstrained('read', 32, uninitialized=False)
Exemple #10
0
    def run(self, fd, dst, length):
        self.argument_types = {
            0: SimTypeFd(),
            1: self.ty_ptr(SimTypeArray(SimTypeChar(), length)),
            2: SimTypeLength(self.state.arch)
        }
        self.return_type = SimTypeLength(self.state.arch)

        # TODO handle errors
        length = self.state.posix.read(fd, dst, length)
        filename = self.state.posix.get_file(fd)
        #filter read passwd file
        if (filename.name.find('passwd') != -1 or 1):
            print filename.name + ' !!!'
            #print "test!!!!"
            fff = open('/data/find_read.flag', 'w')
            fff.close()
            write_file('read file name: ' + filename.name + '\n')

        return length
Exemple #11
0
    def run(self, s_addr, c_int, s_strlen=None):
        c = c_int[7:0]

        self.argument_types = {
            0: self.ty_ptr(SimTypeString()),
            1: SimTypeInt(32, True)
        }  # ?
        self.return_type = self.ty_ptr(SimTypeChar())  # ?

        s_strlen = self.inline_call(angr.SIM_PROCEDURES['libc']['strlen'],
                                    s_addr)

        if self.state.se.symbolic(s_strlen.ret_expr):
            l.debug("symbolic strlen")
            # TODO: more constraints here to make sure we don't search too little
            try:
                max_sym = min(self.state.se.max_int(s_strlen.ret_expr),
                              self.state.libc.max_symbolic_strchr)
                a, c, i = self.state.memory.find(s_addr,
                                                 c,
                                                 s_strlen.max_null_index,
                                                 max_symbolic_bytes=max_sym,
                                                 default=0)
            except angr.SimUnsatError:
                # XXX: reduce constraint
                max_sym = self.state.libc.max_symbolic_strchr
                a, c, i = self.state.memory.find(s_addr,
                                                 c,
                                                 self.state.libc.max_str_len,
                                                 max_symbolic_bytes=max_sym,
                                                 default=0)
        else:
            l.debug("concrete strlen")
            max_search = self.state.se.eval(s_strlen.ret_expr)
            a, c, i = self.state.memory.find(s_addr, c, max_search, default=0)

        if len(i) > 1:
            a = a.annotate(MultiwriteAnnotation())
            self.state.add_constraints(*c)

        return a
Exemple #12
0
    def run(self, dst, size, file_ptr):
        self.argument_types = {
            2: SimTypeFd(),
            0: self.ty_ptr(SimTypeArray(SimTypeChar(), size)),
            1: SimTypeLength(self.state.arch)
        }
        self.return_type = self.argument_types[0]

        # some sensible limits for the new line search
        max_symbolic_bytes = self.state.libc.buf_symbolic_bytes
        max_str_len = self.state.libc.max_str_len

        # let's get the memory back for the file we're interested in and find the newline
        fd_offset = io_file_data_for_arch(self.state.arch)['fd']
        fd = self.state.mem[file_ptr + fd_offset:].int.resolved
        fp = self.state.posix.get_file(fd)
        pos = fp.pos
        mem = fp.content
        # if there exists a limit on the file size, let's respect that, the limit cannot be symbolic
        limit = max_str_len if fp.size is None else self.state.se.max_int(
            fp.size - pos)

        # limit will always be concrete, if it's zero we EOF'd
        if limit != 0:
            # XXX max_str_len is small, might not be suitable for tracing!
            # measure up to the newline of size - 1
            r, c, i = mem.find(pos,
                               self.state.se.BVV('\n'),
                               limit,
                               max_symbolic_bytes=max_symbolic_bytes)
        else:
            r = 0
            c = []

        # XXX: this is a HACK to determine if r is 0 because there is a newline at the first index or
        # if r is 0 because there cannot be any newline
        errored = False
        if not self.state.se.satisfiable(extra_constraints=(r > 0, )):
            errored = True
            if self.state.se.solution(mem.load(0, 1), self.state.se.BVV('\n')):
                errored = False

        # make sure we only read up to size - 1
        read_size = self.state.se.If(size == 0, 0, size - 1)
        # if file can EOF (ie not completely symbolic)
        if fp.size is not None:
            read_size = self.state.se.If(limit < read_size, limit, read_size)

        # now if find errored then there cannot exist a newline in the file, otherwise this logic checks out
        if not errored:
            newline_d = self.state.se.If(r == 0, r, r - pos + 1)
            distance = self.state.se.If(read_size < newline_d, read_size,
                                        newline_d)
        else:
            distance = read_size

        # read in up to the newline
        ret = self.inline_call(angr.SIM_PROCEDURES['posix']['read'], fd, dst,
                               distance).ret_expr

        # in case there's no newline
        c = self.state.se.Or(ret == read_size, *c)
        self.state.add_constraints(c)

        # otherwise we take care of the newline case
        # now write the terminating null byte, should be placed after the newline which is also stored
        self.state.memory.store(dst + distance, self.state.se.BVV(0, 8))

        inner_case = self.state.se.If(self.state.se.And(fp.pos == 0, ret == 0),
                                      0, dst)
        return self.state.se.If(size == 0, 0, inner_case)