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, ptr, size): if not self.state.se.symbolic(ptr) and \ self.state.se.eval(ptr) == 0: return self.inline_call(malloc, size).ret_expr try: self.state.add_constraints( size <= self.state.libc.max_variable_size) size_int = self.state.se.max_int(size) l.debug("Size: %d", size_int) self.state.add_constraints(size_int == size) except angr.SimUnsatError: size_int = self.state.libc.max_variable_size self.argument_types = { 0: self.ty_ptr(SimTypeTop()), 1: SimTypeLength(self.state.arch) } self.return_type = self.ty_ptr(SimTypeTop(size)) addr = self.state.libc.heap_location v = self.state.memory.load(ptr, size_int) self.state.memory.store(addr, v) self.state.libc.heap_location += size_int return addr
def run(self, dst_addr, src_addr, limit): # 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 = self.ty_ptr(SimTypeTop()) if not self.state.solver.symbolic(limit): # not symbolic so we just take the value conditional_size = self.state.solver.eval(limit) else: # constraints on the limit are added during the store max_memcpy_size = self.state.libc.max_memcpy_size max_limit = self.state.solver.max_int(limit) conditional_size = max(self.state.solver.min_int(limit), min(max_limit, max_memcpy_size)) if max_limit > max_memcpy_size and conditional_size < max_limit: l.warning("memcpy upper bound of %#x outside limit, limiting to %#x instead", max_limit, conditional_size) l.debug("Memcpy running with conditional_size %#x", conditional_size) if conditional_size > 0: src_mem = self.state.memory.load(src_addr, conditional_size, endness='Iend_BE') if ABSTRACT_MEMORY in self.state.options: self.state.memory.store(dst_addr, src_mem, size=conditional_size, endness='Iend_BE') else: self.state.memory.store(dst_addr, src_mem, size=limit, endness='Iend_BE') 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: 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, ptr, size): self.argument_types = { 0: self.ty_ptr(SimTypeTop()), 1: SimTypeLength(self.state.arch) } self.return_type = self.ty_ptr(SimTypeTop(size)) return self.state.heap._realloc(ptr, size)
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(self, ptr, size): self.argument_types = { 0: self.ty_ptr(SimTypeTop()), 1: SimTypeLength(self.state.arch) } self.return_type = self.ty_ptr(SimTypeTop(size)) minus = 0 chunk = self.state.heap.chunk_from_mem(ptr) if chunk is not None: minus = chunk.get_size() actual_val = self.state.heap._conc_alloc_size(size) if (actual_val - minus) > self.state.globals[NO_OOM_MEMSIZE]: return 0 self.state.globals[NO_OOM_MEMSIZE] -= (actual_val - minus) return self.state.heap._realloc(ptr, size)
def run(self, sim_nmemb, sim_size): self.argument_types = { 0: SimTypeLength(self.state.arch), 1: SimTypeLength(self.state.arch) } plugin = self.state.get_plugin('libc') self.return_type = self.ty_ptr( SimTypeArray(SimTypeTop(sim_size), sim_nmemb)) if self.state.solver.symbolic(sim_nmemb): # TODO: find a better way nmemb = self.state.solver.max_int(sim_nmemb) else: nmemb = self.state.solver.eval(sim_nmemb) if self.state.solver.symbolic(sim_size): # TODO: find a better way size = self.state.solver.max_int(sim_size) else: size = self.state.solver.eval(sim_size) final_size = size * nmemb if final_size > plugin.max_variable_size: final_size = plugin.max_variable_size addr = plugin.heap_location plugin.heap_location += final_size v = self.state.solver.BVV(0, final_size * 8) self.state.memory.store(addr, v) return addr
def run(self, ptr): self.argument_types = {0: self.ty_ptr(SimTypeTop())} f_ptr = self.state.solver.eval(ptr) if "has_free" in self.state.globals: has_free = self.state.globals["has_free"] if f_ptr in has_free: hists = self.state.history.bbl_addrs.hardcopy paths, print_paths = self.deal_history(self.state, hists) double_free_paths = self.state.globals['double_free_paths'] limit = self.state.globals['limit'] if self.cmp_path(paths, double_free_paths, limit): self.save_msg(self.state, "double_free_result", print_paths) self.state.globals['double_free'] = True else: self.state.globals["has_free"] = {} has_free = self.state.globals["has_free"] if "has_malloc" in self.state.globals: has_malloc = self.state.globals["has_malloc"] if f_ptr in has_malloc: has_free[f_ptr] = has_malloc[f_ptr] return self.state.heap._free(ptr)
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, 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
def run(self, sim_nmemb, sim_size): self.argument_types = { 0: SimTypeLength(self.state.arch), 1: SimTypeLength(self.state.arch) } self.return_type = self.ty_ptr( SimTypeArray(SimTypeTop(sim_size), sim_nmemb)) return self.state.heap._calloc(sim_nmemb, sim_size)
def run(self, sim_nmemb, sim_size): self.argument_types = { 0: SimTypeLength(self.state.arch), 1: SimTypeLength(self.state.arch)} self.return_type = self.ty_ptr(SimTypeArray(SimTypeTop(sim_size), sim_nmemb)) actual_val = self.state.heap._conc_alloc_size(sim_nmemb * sim_size) if actual_val > self.state.globals[NO_OOM_MEMSIZE]: return 0 self.state.globals[NO_OOM_MEMSIZE] -= actual_val return self.state.heap._calloc(sim_nmemb, sim_size)
def run(self, ptr): self.argument_types = {0: self.ty_ptr(SimTypeTop())} chunk = self.state.heap.chunk_from_mem(ptr) if chunk is None: l.warn('Unknown (double?) free') return size = chunk.get_size() self.state.globals[NO_OOM_MEMSIZE] += size return self.state.heap._free(ptr)
def run(self, f): self.argument_types = {0: self.ty_ptr(SimTypeTop())} self.return_type = SimTypeFd() # Get FILE struct io_file_data = io_file_data_for_arch(self.state.arch) # Get the file descriptor from FILE struct result = self.state.mem[f + io_file_data['fd']].int.resolved return result.sign_extend(self.arch.bits - len(result))
def run(self, ptr, size): self.state.add_constraints(size <= self.state.libc.max_variable_size) size_int = self.state.se.max_int(size) l.debug("Size: %d", size_int) self.state.add_constraints(size_int == size) self.argument_types = { 0: self.ty_ptr(SimTypeTop()), 1: SimTypeLength(self.state.arch) } self.return_type = self.ty_ptr(SimTypeTop(size)) addr = self.state.libc.heap_location v = self.state.memory.load(ptr, size_int) self.state.memory.store(addr, v) self.state.libc.heap_location += size_int return addr
def run(self, sim_size): self.argument_types = {0: SimTypeLength(self.state.arch)} self.return_type = self.ty_ptr(SimTypeTop(sim_size)) # this function contains logic errors, including not confirming the resulting # size is a valid one, but it's not likely to fail either # misbehave in the general sense actual_val = self.state.heap._conc_alloc_size(sim_size) if actual_val > self.state.globals[NO_OOM_MEMSIZE]: return 0 self.state.globals[NO_OOM_MEMSIZE] -= actual_val return self.state.heap._malloc(actual_val)
def run(self, sim_size): self.argument_types = {0: SimTypeLength(self.state.arch)} self.return_type = self.ty_ptr(SimTypeTop(sim_size)) if self.state.se.symbolic(sim_size): size = self.state.se.max_int(sim_size) if size > self.state.libc.max_variable_size: size = self.state.libc.max_variable_size else: size = self.state.se.any_int(sim_size) addr = self.state.libc.heap_location self.state.libc.heap_location += size return addr
def run(self, f): self.argument_types = {0: self.ty_ptr(SimTypeTop())} self.return_type = SimTypeFd() # Get FILE struct io_file_data = io_file_data_for_arch(self.state.arch) # Get the file descriptor from FILE struct fd = self.state.se.any_int( self.state.memory.load( f + io_file_data['fd'], 4 * 8, # int endness=self.state.arch.memory_endness)) return fd
def run(self, sim_size): self.argument_types = {0: SimTypeLength(self.state.arch)} self.return_type = self.ty_ptr(SimTypeTop(sim_size)) addr = self.state.heap._malloc(sim_size) size = self.state.solver.eval(sim_size) # print("size:",size,"addr:",addr) if "has_malloc" in self.state.globals: malloc_dir = self.state.globals["has_malloc"] else: self.state.globals["has_malloc"] = {} malloc_dir = self.state.globals["has_malloc"] malloc_dir[addr] = size # print(self.state.globals["has_malloc"]) return addr
def run(self, f): self.argument_types = {0: self.ty_ptr(SimTypeTop())} self.return_type = SimTypeFd() # Get FILE struct io_file_data = io_file_data_for_arch(self.state.arch) try: # Get the file descriptor from FILE struct fd = self.state.se.eval( self.state.memory.load( f + io_file_data['fd'], 4 * 8, # int endness=self.state.arch.memory_endness)) return fd except angr.SimUnsatError: # XXX: hase -> resymbolic return self.state.se.Unconstrained("fileno_fd", 32, uninitialized=False)
def run(self, ptr): self.argument_types = {0: self.ty_ptr(SimTypeTop())} return self.state.heap._free(ptr)
def run(self, sim_size): self.argument_types = {0: SimTypeLength(self.state.arch)} self.return_type = self.ty_ptr(SimTypeTop(sim_size)) return self.state.heap._malloc(sim_size)
def run(self, ptr): self.argument_types = {0: self.ty_ptr(SimTypeTop())} f_ptr = self.state.solver.eval(ptr) if "has_free" in self.state.globals: has_free = self.state.globals["has_free"] if f_ptr in has_free: hists = self.state.history.bbl_addrs.hardcopy paths, print_paths = self.deal_history(self.state, hists) double_free_paths = self.state.globals['double_free_paths'] limit = self.state.globals['limit'] if self.cmp_path(paths, double_free_paths, limit): self.save_msg(self.state, "double_free_result", print_paths) self.state.globals['double_free'] = True else: self.state.globals["has_free"] = {} has_free = self.state.globals["has_free"] if "has_malloc" in self.state.globals: has_malloc = self.state.globals["has_malloc"] if f_ptr in has_malloc: has_free[f_ptr] = has_malloc[f_ptr] #----------------------------------------------------------------- # if "has_malloc" in self.state.globals: # malloc_dir=self.state.globals["has_malloc"] # if f_ptr not in malloc_dir: # if "has_free" in self.state.globals: # free_dir=self.state.globals["has_free"] # if f_ptr in free_dir: # hists=self.state.history.bbl_addrs.hardcopy # paths,print_paths=self.deal_history(self.state,hists) # double_free_paths=self.state.globals['double_free_paths'] # limit=self.state.globals['limit'] # if self.cmp_path(paths,double_free_paths,limit): # self.save_msg(self.state,"double_free_result",print_paths) # self.state.globals['double_free']=True # else: # hists=self.state.history.bbl_addrs.hardcopy # paths,print_paths=self.deal_history(self.state,hists) # error_free_paths=self.state.globals['error_free_paths'] # limit=self.state.globals['limit'] # self.state.globals['error_free_ptr']=True # else: # self.state.globals["has_free"]={} # # free_dir=self.state.globals["has_free"] # hists=self.state.history.bbl_addrs.hardcopy # paths,print_paths=self.deal_history(self.state,hists) # error_free_paths=self.state.globals['error_free_paths'] # limit=self.state.globals['limit'] # self.state.globals['error_free_ptr']=True # else: # size=malloc_dir[f_ptr] # malloc_dir.pop(f_ptr) # if "has_free" in self.state.globals: # free_dir=self.state.globals["has_free"] # free_dir[f_ptr]=size # else: # self.state.globals["has_free"]={} # free_dir=self.state.globals["has_free"] # free_dir[f_ptr]=size # else: # hists=self.state.history.bbl_addrs.hardcopy # paths,print_paths=self.deal_history(self.state,hists) # error_free_paths=self.state.globals['error_free_paths'] # limit=self.state.globals['limit'] # self.state.globals['error_free_ptr']=True #----------------------------------------------------------------- return self.state.heap._free(ptr)
def run(self, ptr): #pylint:disable=unused-argument self.argument_types = {0: self.ty_ptr(SimTypeTop())} return self.state.se.Unconstrained('free', self.state.arch.bits)