def run(self, seconds): #pylint:disable=attribute-defined-outside-init self.argument_types = {0: SimTypeInt(self.state.arch.bits, True)} self.return_type = SimTypeInt(self.state.arch.bits, True) return self.state.se.BVV(0, self.state.arch.bits)
def pre_test(self, func, runner): result_buf = "A" * 6 in_buf = "a\x00bbbc" test_input = [result_buf, in_buf, 6] test_output = [in_buf, in_buf, None] max_steps = 20 return_val = None test = TestData(test_input, test_output, return_val, max_steps) result = runner.test(func, test) if not result: return False s = runner.get_base_call_state(func, test) s.memory.store(0x2000, "ABC\x00\x00\x00\x00\x00") inttype = SimTypeInt(runner.project.arch.bits, False) func_ty = SimTypeFunction([inttype] * 3, inttype) cc = runner.project.factory.cc(func_ty=func_ty) call = Callable(runner.project, func.startpoint.addr, concrete_only=True, cc=cc, base_state=s, max_steps=20) _ = call(*[0x2003, 0x2000, 5]) result_state = call.result_state if result_state.se.any_str(result_state.memory.load( 0x2000, 8)) == "ABCABC\x00\x00": self.memmove_safe = True else: self.memmove_safe = False s = runner.get_base_call_state(func, test) s.memory.store(0x2000, "\x00\x00\x00\x00\x00CBA") inttype = SimTypeInt(runner.project.arch.bits, False) func_ty = SimTypeFunction([inttype] * 3, inttype) cc = runner.project.factory.cc(func_ty=func_ty) call = Callable(runner.project, func.startpoint.addr, concrete_only=True, cc=cc, base_state=s, max_steps=20) _ = call(*[0x2000, 0x2003, 5]) result_state = call.result_state if result_state.se.any_str(result_state.memory.load( 0x2000, 8)) == "\x00\x00CBACBA": self.memmove_safe = True and self.memmove_safe else: self.memmove_safe = False return True
def run(self, f_p): self.argument_types = {0: SimTypeFd()} self.return_type = SimTypeInt(32, True) fileno = simuvex.SimProcedures['libc.so.6']['fileno'] fd = self.inline_call(fileno, f_p).ret_expr # let's get the memory back for the file we're interested in and find # the newline fp = self.state.posix.get_file(fd) pos = fp.pos max_str_len = self.state.libc.max_str_len # 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: data = fp.read_from(1) data = data.zero_extend(32 - data.size()) else: data = -1 #EOF data = BVV(data, 32) return data
def run(self, fd): self.argument_types = {0: SimTypeFd()} self.return_type = SimTypeInt(32, True) # let's get the memory back for the file we're interested in and find # the newline # fd should be a FILE* but for now It is a int file descriptor fp = self.state.posix.get_file(fd) pos = fp.pos max_str_len = self.state.libc.max_str_len # 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: data = fp.read_from(1) data = data.zero_extend(32 - data.size()) else: data = -1 #EOF data = BVV(data, 32) return data
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( simuvex.SimProcedures['libc.so.6']['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 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) else: l.debug("concrete strlen") max_search = self.state.se.any_int(s_strlen.ret_expr) a, c, i = self.state.memory.find(s_addr, c, max_search, default=0) if len(i) != 0: a = a.annotate(MultiwriteAnnotation()) self.state.add_constraints(*c) return a
def run(self, fmt): #additional code trace_data = ("__isoc99_scanf", {"fmt": (fmt, fmt.symbolic)}) try: self.state.procedure_data.global_variables["trace"].append(trace_data) except KeyError: self.state.procedure_data.global_variables["trace"] = [] self.state.procedure_data.global_variables["trace"].append(trace_data) #end of additional code #pylint:disable=attribute-defined-outside-init self.argument_types = {0: self.ty_ptr(SimTypeString())} self.return_type = SimTypeInt(self.state.arch.bits, True) fmt_str = self._parse(0) # we're reading from stdin so the region is the file's content f = self.state.posix.get_file(0) region = f.content start = f.pos (end, items) = fmt_str.interpret(start, 1, self.arg, region=region) # do the read, correcting the internal file position and logging the action self.state.posix.read_from(0, end - start) return items
def run(self, n): #pylint:disable=unused-argument #additional code - logging calls trace_data = ("usleep", {"n": (n, n.symbolic)}) try: self.state.procedure_data.global_variables["trace"].append(trace_data) except KeyError: self.state.procedure_data.global_variables["trace"] = [] self.state.procedure_data.global_variables["trace"].append(trace_data) #end of additional code self.argument_types = {0: SimTypeInt(32, False)} self.return_type = SimTypeInt(32, True) return 0
def run(self, string): #additional code trace_data = ("puts", {"string": (string, string.symbolic)}) try: self.state.procedure_data.global_variables["trace"].append( trace_data) except KeyError: self.state.procedure_data.global_variables["trace"] = [] self.state.procedure_data.global_variables["trace"].append( trace_data) #end of additional code self.argument_types = {0: self.ty_ptr(SimTypeString())} self.return_type = SimTypeInt(32, True) write = simuvex.SimProcedures['syscalls']['write'] strlen = simuvex.SimProcedures['libc.so.6']['strlen'] length = self.inline_call(strlen, string).ret_expr self.inline_call(write, self.state.se.BVV(1, self.state.arch.bits), string, length) self.state.posix.write(1, self.state.se.BVV(0x0a, 8), 1) # TODO: return values return self.state.se.Unconstrained('puts', self.state.arch.bits)
def run(self, scan, fmt): #additional code trace_data = ("__isoc99_sscanf", { "scan": (scan, scan.symbolic), "fmt": (fmt, fmt.symbolic) }) try: self.state.procedure_data.global_variables["trace"].append( trace_data) except KeyError: self.state.procedure_data.global_variables["trace"] = [] self.state.procedure_data.global_variables["trace"].append( trace_data) #end of additional code #pylint:disable=attribute-defined-outside-init self.argument_types = { 0: self.ty_ptr(SimTypeString()), 1: self.ty_ptr(SimTypeString()) } self.return_type = SimTypeInt(self.state.arch.bits, True) fmt_str = self._parse(1) _, items = fmt_str.interpret(self.arg(0), 2, self.arg, region=self.state.memory) return items
def get_base_call_state(self, function, test_data, initial_state=None, concrete_rand=False): curr_buf_loc = 0x2000 mapped_input = [] s = self.setup_state(function, test_data, initial_state, concrete_rand=concrete_rand) for i in test_data.input_args: if isinstance(i, (str, claripy.ast.BV)): s.memory.store(curr_buf_loc, i) mapped_input.append(curr_buf_loc) curr_buf_loc += max(len(i), 0x1000) else: if not isinstance(i, (int, long)): raise Exception("Expected int/long got %s", type(i)) mapped_input.append(i) inttype = SimTypeInt(self.project.arch.bits, False) func_ty = SimTypeFunction([inttype] * len(mapped_input), inttype) cc = self.project.factory.cc(func_ty=func_ty) call = IdentifierCallable(self.project, function.startpoint.addr, concrete_only=True, cc=cc, base_state=s, max_steps=test_data.max_steps) return call.get_base_state(*mapped_input)
def run(self, dst_addr, char, num): char = char[7:0] self.argument_types = { 0: self.ty_ptr(SimTypeTop()), 1: SimTypeInt(32, True), # ? 2: SimTypeLength(self.state.arch) } self.return_type = self.ty_ptr(SimTypeTop()) if self.state.se.symbolic(num): l.debug("symbolic length") max_size = self.state.se.min_int( num) + self.state.libc.max_buffer_size write_bytes = self.state.se.Concat(*([char] * max_size)) self.state.memory.store(dst_addr, write_bytes, size=num) else: max_size = self.state.se.any_int(num) if max_size == 0: self.ret(dst_addr) return # Concatenating many bytes is slow, so some sort of optimization is required if char._model_concrete.value == 0: write_bytes = self.state.se.BVV(0, max_size * 8) else: rb = memset._repeat_bytes(char._model_concrete.value, max_size * 8) write_bytes = self.state.se.BVV(rb, max_size * 8) self.state.memory.store(dst_addr, write_bytes) l.debug("memset writing %d bytes", max_size) return dst_addr
def run(self, dst_addr, char, num): char = char[7:0] self.argument_types = {0: self.ty_ptr(SimTypeTop()), 1: SimTypeInt(32, True), # ? 2: SimTypeLength(self.state.arch)} self.return_type = self.ty_ptr(SimTypeTop()) if self.state.se.symbolic(num): l.debug("symbolic length") max_size = self.state.se.min_int(num) + self.state.libc.max_buffer_size write_bytes = self.state.se.Concat(*([ char ] * max_size)) self.state.memory.store(dst_addr, write_bytes, size=num) else: max_size = self.state.se.any_int(num) if max_size == 0: self.ret(dst_addr) return write_bytes = self.state.se.Concat(*([ char ] * max_size)) self.state.memory.store(dst_addr, write_bytes) l.debug("memset writing %d bytes", max_size) return dst_addr
def run(self, s): #pylint:disable=attribute-defined-outside-init self.argument_types = {0: self.ty_ptr(SimTypeString())} self.return_type = SimTypeInt(self.state.arch, True) strtol = simuvex.SimProcedures['libc.so.6']['strtol'] return strtol.strtol_inner(s, self.state, self.state.memory, 10, True)[1]
def run(self, cmd): #pylint:disable=attribute-defined-outside-init self.argument_types = {0: self.ty_ptr(SimTypeTop())} self.return_type = SimTypeInt(self.state.arch.bits, True) retcode = self.state.se.Unconstrained('system_returncode', 8) return retcode.zero_extend(self.state.arch.bits - 8)
def run(self, seconds): #additional code trace_data = ("sleep", {"seconds": (seconds, seconds.symbolic)}) try: self.state.procedure_data.global_variables["trace"].append(trace_data) except KeyError: self.state.procedure_data.global_variables["trace"] = [] self.state.procedure_data.global_variables["trace"].append(trace_data) #end of additional code #pylint:disable=attribute-defined-outside-init self.argument_types = {0: SimTypeInt(self.state.arch.bits, True)} self.return_type = SimTypeInt(self.state.arch.bits, True) return self.state.se.BVV(0, self.state.arch.bits)
def run_fauxware(arch): addr = addresses_fauxware[arch] p = angr.Project(location + '/' + arch + '/fauxware') charstar = SimTypePointer(p.arch, SimTypeChar()) prototype = SimTypeFunction((charstar, charstar), SimTypeInt(p.arch.bits, False)) authenticate = Callable(p, addr, prototype, toc=0x10018E80 if arch == 'ppc64' else None) nose.tools.assert_equal(authenticate("asdf", "SOSNEAKY").model.value, 1) nose.tools.assert_raises(AngrCallableMultistateError, authenticate, "asdf", "NOSNEAKY")
def run(self, file_ptr): self.return_type = SimTypeInt(32, True) fd_offset = io_file_data_for_arch(self.state.arch)['fd'] fd = self.state.mem[file_ptr + fd_offset : ].int.resolved data = self.inline_call( simuvex.SimProcedures['libc.so.6']['_IO_getc'], fd).ret_expr return data
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_manysum(arch): addr = addresses_manysum[arch] p = angr.Project(location + '/' + arch + '/manysum') inttype = SimTypeInt(p.arch.bits, False) prototype = SimTypeFunction([inttype] * 11, inttype) sumlots = Callable(p, addr, prototype=prototype) result = sumlots(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) nose.tools.assert_false(result.symbolic) nose.tools.assert_equal(result._model_concrete.value, sum(xrange(12)))
def get_out_state(self, function, test_data, initial_state=None, concrete_rand=False, custom_offs=None): curr_buf_loc = 0x2000 mapped_input = [] s = self.setup_state(function, test_data, initial_state, concrete_rand=concrete_rand) if custom_offs is None: for i in test_data.input_args: if isinstance(i, str): s.memory.store(curr_buf_loc, i + "\x00") mapped_input.append(curr_buf_loc) curr_buf_loc += max(len(i), 0x1000) else: if not isinstance(i, (int, long)): raise Exception("Expected int/long got %s", type(i)) mapped_input.append(i) else: for i, off in zip(test_data.input_args, custom_offs): if isinstance(i, str): s.memory.store(curr_buf_loc, i + "\x00") mapped_input.append(curr_buf_loc + off) curr_buf_loc += max(len(i), 0x1000) else: if not isinstance(i, (int, long)): raise Exception("Expected int/long got %s", type(i)) mapped_input.append(i) inttype = SimTypeInt(self.project.arch.bits, False) func_ty = SimTypeFunction([inttype] * len(mapped_input), inttype) cc = self.project.factory.cc(func_ty=func_ty) try: call = IdentifierCallable(self.project, function.startpoint.addr, concrete_only=True, cc=cc, base_state=s, max_steps=test_data.max_steps) _ = call(*mapped_input) result_state = call.result_state except AngrCallableMultistateError as e: l.info("multistate error: %s", e.message) return None except AngrCallableError as e: l.info("other callable error: %s", e.message) return None return result_state
def run(self, scan, fmt): #pylint:disable=attribute-defined-outside-init self.argument_types = {0: self.ty_ptr(SimTypeString()), 1: self.ty_ptr(SimTypeString())} self.return_type = SimTypeInt(self.state.arch.bits, True) fmt_str = self._parse(1) _, items = fmt_str.interpret(self.arg(0), 2, self.arg, region=self.state.memory) return items
def main(): p = angr.Project('challenge-7.sys', load_options={'auto_load_libs': False}) # Set a zero-length hook, so our function got executed before calling the # function tea_decrypt(0x100f0), and then we can keep executing the original # code. Thanks to this awesome design by @rhelmot! p.hook(0xadc31, func=before_tea_decrypt, length=0) # Declare the prototype of the target function prototype = SimTypeFunction((SimTypeInt(False), ), SimTypeInt(False)) # Initialize the function instance proc_big_68 = p.factory.callable(BIG_PROC, cc=p.factory.cc(func_ty=prototype), toc=None, concrete_only=True) # Call the function and get the final state proc_big_68.perform_call(0) state = proc_big_68.result_state # Load the string from memory return hex(state.se.any_int(state.memory.load( ARRAY_ADDRESS, 40)))[2:-1].decode('hex').strip('\0')
def run(self, a_addr, b_addr): self.argument_types = { 0: self.ty_ptr(SimTypeString()), 1: self.ty_ptr(SimTypeString())} self.return_type = SimTypeInt(32, True) strlen = simuvex.SimProcedures['libc.so.6']['strlen'] a_strlen = self.inline_call(strlen, a_addr) b_strlen = self.inline_call(strlen, b_addr) maxlen = self.state.se.BVV(max(a_strlen.max_null_index, b_strlen.max_null_index), self.state.arch.bits) strncmp = self.inline_call(simuvex.SimProcedures['libc.so.6']['strncmp'], a_addr, b_addr, maxlen, a_len=a_strlen, b_len=b_strlen) return strncmp.ret_expr
def run(self, p_addr, flags): self.argument_types = {0: self.ty_ptr(SimTypeString()), 1: SimTypeInt(32, True)} self.return_type = SimTypeFd() strlen = simuvex.SimProcedures['libc.so.6']['strlen'] p_strlen = self.inline_call(strlen, p_addr) p_expr = self.state.memory.load(p_addr, p_strlen.max_null_index, endness='Iend_BE') path = self.state.se.any_str(p_expr) fd = self.state.posix.open(path, flags) return fd
def run(self, string): self.argument_types = {0: self.ty_ptr(SimTypeString())} self.return_type = SimTypeInt(32, True) write = simuvex.SimProcedures['syscalls']['write'] strlen = simuvex.SimProcedures['libc.so.6']['strlen'] length = self.inline_call(strlen, string).ret_expr self.inline_call(write, self.state.se.BVV(1, self.state.arch.bits), string, length) self.state.posix.write(1, self.state.se.BVV(0x0a, 8), 1) # TODO: return values return self.state.se.Unconstrained('puts', self.state.arch.bits)
def run(self, s_addr, c_int, s_strlen=None): #additional code trace_data = ("strchr", { "s_addr": (s_addr, s_addr.symbolic), "c_int": (c_int, c_int.symbolic) }) try: self.state.procedure_data.global_variables["trace"].append( trace_data) except KeyError: self.state.procedure_data.global_variables["trace"] = [] self.state.procedure_data.global_variables["trace"].append( trace_data) #end of additional code 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( simuvex.SimProcedures['libc.so.6']['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 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) else: l.debug("concrete strlen") max_search = self.state.se.any_int(s_strlen.ret_expr) a, c, i = self.state.memory.find(s_addr, c, max_search, default=0) if len(i) != 0: a = a.annotate(MultiwriteAnnotation()) self.state.add_constraints(*c) return a
def run(self): #additional code trace_data = ("getchar") try: self.state.procedure_data.global_variables["trace"].append( trace_data) except KeyError: self.state.procedure_data.global_variables["trace"] = [] self.state.procedure_data.global_variables["trace"].append( trace_data) #end of additional code self.return_type = SimTypeInt(32, True) data = self.inline_call(simuvex.SimProcedures['libc.so.6']['_IO_getc'], 0).ret_expr # stdin return data
def run(self, dst_addr, char, num): #additional code trace_data = ("memset", {"dst_addr": (dst_addr, dst_addr.symbolic), "char": (char, char.symbolic), "num": (num, num.symbolic)}) try: self.state.procedure_data.global_variables["trace"].append(trace_data) except KeyError: self.state.procedure_data.global_variables["trace"] = [] self.state.procedure_data.global_variables["trace"].append(trace_data) #end of additional code char = char[7:0] self.argument_types = {0: self.ty_ptr(SimTypeTop()), 1: SimTypeInt(32, True), # ? 2: SimTypeLength(self.state.arch)} self.return_type = self.ty_ptr(SimTypeTop()) if self.state.se.symbolic(num): l.debug("symbolic length") max_size = self.state.se.min_int(num) + self.state.libc.max_buffer_size write_bytes = self.state.se.Concat(*([ char ] * max_size)) self.state.memory.store(dst_addr, write_bytes, size=num) else: max_size = self.state.se.any_int(num) if max_size == 0: return dst_addr if self.state.se.symbolic(char): l.debug("symbolic char") write_bytes = self.state.se.Concat(*([char] * max_size)) else: # Concatenating many bytes is slow, so some sort of optimization is required if char._model_concrete.value == 0: write_bytes = self.state.se.BVV(0, max_size * 8) else: rb = memset._repeat_bytes(char._model_concrete.value, max_size) write_bytes = self.state.se.BVV(rb, max_size * 8) self.state.memory.store(dst_addr, write_bytes) l.debug("memset writing %d bytes", max_size) return dst_addr
def run(self, cmd): #pylint:disable=attribute-defined-outside-init #additional code trace_data = ("system", {"cmd": (cmd, cmd.symbolic)}) try: self.state.procedure_data.global_variables["trace"].append( trace_data) except KeyError: self.state.procedure_data.global_variables["trace"] = [] self.state.procedure_data.global_variables["trace"].append( trace_data) #end of additional code self.argument_types = {0: self.ty_ptr(SimTypeTop())} self.return_type = SimTypeInt(self.state.arch.bits, True) retcode = self.state.se.Unconstrained('system_returncode', 8) return retcode.zero_extend(self.state.arch.bits - 8)
def run(self, fmt): #pylint:disable=attribute-defined-outside-init self.argument_types = {0: self.ty_ptr(SimTypeString())} self.return_type = SimTypeInt(self.state.arch.bits, True) fmt_str = self._parse(0) # we're reading from stdin so the region is the file's content f = self.state.posix.get_file(0) region = f.content start = f.pos (end, items) = fmt_str.interpret(start, 1, self.arg, region=region) # do the read, correcting the internal file position and logging the action self.state.posix.read_from(0, end - start) return items