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
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
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
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
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")
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)
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
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")
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)
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
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
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)