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, 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.solver.BVV(0, self.state.arch.bits)
def run(self, c): self.argument_types = {0: SimTypeInt(self.state.arch, True)} self.return_type = SimTypeInt(self.state.arch, True) return self.state.solver.If( self.state.solver.And(c >= 97, c <= 122), # a - z c - 32, c)
def run(self, argc_p, argv_ppp, env_ppp, dowildcard, startupinfo_p): self.argument_types = { 0: self.ty_ptr(SimTypeInt()), 1: self.ty_ptr(SimTypeTop()), 2: self.ty_ptr(SimTypeTop()), 3: SimTypeInt(), 4: self.ty_ptr(SimTypeTop()) } self.return_type = SimTypeInt() if any(map(self.state.se.symbolic, [argc_p, argv_ppp, env_ppp])): l.warn("got a symbolic argument... aborting") return -1 self.state.memory.store(argc_p, self.state.posix.argc, self.state.arch.bits, endness=self.state.arch.memory_endness) self.state.memory.store(argv_ppp, self.state.posix.argv, self.state.arch.bits, endness=self.state.arch.memory_endness) self.state.memory.store(env_ppp, self.state.posix.environ, self.state.arch.bits, endness=self.state.arch.memory_endness) return 0
def run(self, c): self.argument_types = {0: SimTypeInt(self.state.arch, True)} self.return_type = SimTypeInt(self.state.arch, True) return self.state.solver.If( self.state.solver.And(c >= 65, c <= 90), # A - Z c + 32, c)
def run(self, fp_a, fp_z): self.argument_types = {0: self.ty_ptr(SimTypeInt()), 1: self.ty_ptr(SimTypeInt()) } self.return_type = SimTypeInt() if self.state.solver.symbolic(fp_a) or self.state.solver.symbolic(fp_z): l.warn("Symbolic argument to _initterm{_e} is not supported... returning") return 0 # might as well try to keep going self.callbacks = self.get_callbacks(fp_a, fp_z) self.do_callbacks(fp_a, fp_z)
def run(self, target, value): #pylint:disable=arguments-differ self.argument_types = {0: self.ty_ptr(SimTypeInt()), 1: SimTypeInt()} self.return_type = SimTypeInt() if not self.state.se.symbolic(target): old_value = self.state.memory.load( target, 4, endness=self.state.arch.memory_endness) self.state.memory.store(target, value) else: old_value = self.state.se.Unconstrained( "unconstrained_ret_%s" % self.display_name, self.state.arch.bits) return old_value
def run(self, f_p): self.argument_types = {0: SimTypeFd()} self.return_type = SimTypeInt(32, True) fileno = angr.SIM_PROCEDURES['posix']['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, 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(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: 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): self.return_type = SimTypeInt(32, True) data = self.inline_call( # TODO: use a less private getc angr.SIM_PROCEDURES['glibc']['_IO_getc'], 0).ret_expr # stdin return data
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, 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 state.solver.eval(state.memory.load(ARRAY_ADDRESS, 40), cast_to=bytes).strip(b'\0')
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 = angr.SIM_PROCEDURES['libc']['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_manysum(arch): addr = addresses_manysum[arch] p = angr.Project(os.path.join(location, 'tests', arch, 'manysum')) inttype = SimTypeInt() prototype = SimTypeFunction([inttype] * 11, inttype) sumlots = p.factory.callable(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(range(12)))
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, s1_addr, s2_addr, n): # TODO: look into smarter types here self.argument_types = {0: self.ty_ptr(SimTypeTop()), 1: self.ty_ptr(SimTypeTop()), 2: SimTypeLength(self.state.arch)} self.return_type = SimTypeInt(32, True) try: max_memcmp_size = self.state.libc.max_buffer_size definite_size = self.state.se.min_int(n) conditional_s1_start = s1_addr + definite_size conditional_s2_start = s2_addr + definite_size if self.state.se.symbolic(n): conditional_size = int(max(max_memcmp_size - definite_size, 0)) else: conditional_size = 0 l.debug("Definite size %s and conditional size: %s", definite_size, conditional_size) if definite_size > 0: s1_part = self.state.memory.load(s1_addr, definite_size, endness='Iend_BE') s2_part = self.state.memory.load(s2_addr, definite_size, endness='Iend_BE') cases = [ [s1_part == s2_part, self.state.se.BVV(0, self.state.arch.bits)], [self.state.se.ULT(s1_part, s2_part), self.state.se.BVV(-1, self.state.arch.bits)], [self.state.se.UGT(s1_part, s2_part), self.state.se.BVV(1, self.state.arch.bits) ] ] definite_answer = self.state.se.ite_cases(cases, 2) constraint = self.state.se.Or(*[c for c,_ in cases]) self.state.add_constraints(constraint) l.debug("Created definite answer: %s", definite_answer) l.debug("Created constraint: %s", constraint) l.debug("... crom cases: %s", cases) else: definite_answer = self.state.se.BVV(0, self.state.arch.bits) if not self.state.se.symbolic(definite_answer) and self.state.se.eval(definite_answer) != 0: return definite_answer if conditional_size > 0: s1_all = self.state.memory.load(conditional_s1_start, conditional_size, endness='Iend_BE') s2_all = self.state.memory.load(conditional_s2_start, conditional_size, endness='Iend_BE') conditional_rets = { 0: definite_answer } for byte, bit in zip(range(conditional_size), range(conditional_size*8, 0, -8)): s1_part = s1_all[conditional_size*8-1 : bit-8] s2_part = s2_all[conditional_size*8-1 : bit-8] cases = [ [s1_part == s2_part, self.state.se.BVV(0, self.state.arch.bits)], [self.state.se.ULT(s1_part, s2_part), self.state.se.BVV(-1, self.state.arch.bits)], [self.state.se.UGT(s1_part, s2_part), self.state.se.BVV(1, self.state.arch.bits) ] ] conditional_rets[byte+1] = self.state.se.ite_cases(cases, 0) self.state.add_constraints(self.state.se.Or(*[c for c,_ in cases])) ret_expr = self.state.solver.If(definite_answer == 0, self.state.se.ite_dict(n - definite_size, conditional_rets, 2), definite_answer) self.state.add_constraints(self.state.se.Or(*[n-definite_size == c for c in conditional_rets.keys()])) return ret_expr else: return definite_answer except angr.SimUnsatError: return self.state.se.Unconstrained('memcmp', 32, uninitialized=False)
def run_manysum(arch): addr = addresses_manysum[arch] p = angr.Project(location + '/' + arch + '/manysum') inttype = SimTypeInt() prototype = SimTypeFunction([inttype]*11, inttype) cc = p.factory.cc(func_ty=prototype) sumlots = p.factory.callable(addr, cc=cc) 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 run(self, lpString1, lpString2): self.argument_types = { 0: self.ty_ptr(SimTypeString()), 1: self.ty_ptr(SimTypeString()) } self.return_type = SimTypeInt(signed=True) strcmp = angr.SIM_PROCEDURES['libc']['strcmp'] return self.inline_call(strcmp, lpString1, lpString2, wchar=True).ret_expr
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( # TODO: use a less private implementation? angr.SIM_PROCEDURES['glibc']['_IO_getc'], fd).ret_expr return data
def run(self, data, 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(2, self.arg, addr=data) return items
def run(self, data, 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) try: fmt_str = self._parse(1) items = fmt_str.interpret(2, self.arg, addr=data) return items except angr.SimUnsatError: return self.state.se.Unconstrained('sscanf', 32, uninitialized=False)
def run(self, string): self.argument_types = {0: self.ty_ptr(SimTypeString())} self.return_type = SimTypeInt(32, True) stdout = self.state.posix.get_fd(1) if stdout is None: return -1 strlen = angr.SIM_PROCEDURES['libc']['strlen'] length = self.inline_call(strlen, string).ret_expr out = stdout.write(string, length) stdout.write_data(self.state.solver.BVV(b'\n')) return out + 1
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 = angr.SIM_PROCEDURES['libc']['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(angr.SIM_PROCEDURES['libc']['strncmp'], a_addr, b_addr, maxlen, a_len=a_strlen, b_len=b_strlen) return strncmp.ret_expr
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, category, locale): self.argument_types = { 0: SimTypeInt(32, True), 1: self.ty_ptr(SimTypeString()) } self.return_type = self.ty_ptr(SimTypeString()) # FIXME: just symbolic maxlen string max_str_len = self.state.libc.max_str_len malloc = SIM_PROCEDURES['libc']['malloc'] str_addr = self.inline_call(malloc, max_str_len).ret_expr return self.state.se.If(self.state.se.BoolS("setlocale_flag"), str_addr, self.state.se.BVV(0, self.state.arch.bits))
def run(self, string): self.argument_types = {0: self.ty_ptr(SimTypeString())} self.return_type = SimTypeInt(32, True) # TODO: use a write that's not a linux syscall write = angr.SIM_PROCEDURES['linux_kernel']['write'] strlen = angr.SIM_PROCEDURES['libc']['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, stream, simfd=None): self.argument_types = {0: SimTypeFd()} self.return_type = SimTypeInt(32, True) if simfd is None: fileno = angr.SIM_PROCEDURES['posix']['fileno'] fd = self.inline_call(fileno, stream).ret_expr simfd = self.state.posix.get_fd(fd) if simfd is None: return -1 data, real_length, = simfd.read_data(1) return self.state.solver.If(real_length == 0, -1, data.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 simfd = self.state.posix.get_fd(0) if simfd is None: return -1 items = fmt_str.interpret(1, self.arg, simfd=simfd) return items
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.solver.symbolic(num): l.debug("symbolic length") try: max_size = self.state.solver.min_int( num) + self.state.libc.max_buffer_size except angr.SimUnsatError: max_size = self.state.libc.max_buffer_size write_bytes = self.state.solver.Concat(*([char] * max_size)) self.state.memory.store(dst_addr, write_bytes, size=num) else: max_size = self.state.solver.eval(num) # angr doesn't check max length here. max_size = min(max_size, self.state.libc.max_buffer_size) l.warning("memset writing %d bytes", max_size) offset = 0 while offset < max_size: chunksize = min(max_size - offset, 0x1000) if self.state.solver.symbolic(char): l.debug("symbolic char") write_bytes = self.state.solver.Concat(*([char] * chunksize)) else: # Concatenating many bytes is slow, so some sort of optimization is required if char._model_concrete.value == 0: write_bytes = self.state.solver.BVV(0, chunksize * 8) else: rb = memset._repeat_bytes(char._model_concrete.value, chunksize) write_bytes = self.state.solver.BVV(rb, chunksize * 8) self.state.memory.store(dst_addr + offset, write_bytes) offset += chunksize return dst_addr