def run(self, dst_addr, src_addr, limit): #additional code trace_data = ("memmove", { "dst_addr": (dst_addr, dst_addr.symbolic), "src_addr": (src_addr, src_addr.symbolic), "limit": (limit, limit.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 # 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()) memcpy = simuvex.SimProcedures['libc.so.6']['memcpy'] self.inline_call(memcpy, dst_addr, src_addr, limit) 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 # 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, ptr, size): #additional code trace_data = ("realloc", { "ptr": (ptr, ptr.symbolic), "size": (size, size.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.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, 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, dst_addr, src_addr, limit): #additional code trace_data = ("self", { "dst_addr": (dst_addr, dst_addr.symbolic), "src_addr": (src_addr, src_addr.symbolic), "limit": (limit, limit.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 # 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.se.symbolic(limit): # not symbolic so we just take the value conditional_size = self.state.se.any_int(limit) else: # constraints on the limit are added during the store max_memcpy_size = self.state.libc.max_memcpy_size max_limit = self.state.se.max_int(limit) conditional_size = max(self.state.se.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, src_addr, limit): # TODO: some way to say that type(0) == type(1) ? self.argument_types = { 0: self.ty_ptr(SimTypeTop()), 1: self.ty_ptr(SimTypeTop()), 2: SimTypeLength(self.state.arch) } return self.inline_call(simuvex.SimProcedures['libc.so.6']['memcpy'], dst_addr, src_addr, limit).ret_expr
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()) memcpy = simuvex.SimProcedures['libc.so.6']['memcpy'] self.inline_call(memcpy, dst_addr, src_addr, limit) return dst_addr
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.se.symbolic(sim_nmemb): # TODO: find a better way nmemb = self.state.se.max_int(sim_nmemb) else: nmemb = self.state.se.any_int(sim_nmemb) if self.state.se.symbolic(sim_size): # TODO: find a better way size = self.state.se.max_int(sim_size) else: size = self.state.se.any_int(sim_size) final_size = size * nmemb * 8 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.se.BVV(0, final_size) self.state.memory.store(addr, v) return addr
def run(self, f): #additional code trace_data = ("fileno", {"f": (f, f.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 = 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, 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, src_addr, limit): # TODO: some way to say that type(0) == type(1) ? self.argument_types = {0: self.ty_ptr(SimTypeTop()), 1: self.ty_ptr(SimTypeTop()), 2: SimTypeLength(self.state.arch)} #additional code trace_data = ("bcopy", {"dst_addr": (dst_addr, dst_addr.symbolic), "src_addr": (src_addr, src_addr.symbolic), "limit": (limit, limit.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 return self.inline_call(simuvex.SimProcedures['libc.so.6']['memcpy'], dst_addr, src_addr, limit).ret_expr
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, 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, 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.se.symbolic(limit): # not symbolic so we just take the value conditional_size = self.state.se.any_int(limit) else: # constraints on the limit are added during the store max_memcpy_size = self.state.libc.max_memcpy_size max_limit = self.state.se.max_int(limit) conditional_size = max(self.state.se.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, 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, 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.se.symbolic(limit): if BEST_EFFORT_MEMORY_STORING in self.state.options: conditional_size = self.state.se.max_int(limit) else: conditional_size = self.state.se.any_int(limit) else: max_memcpy_size = self.state.libc.max_buffer_size conditional_size = max( self.state.se.min_int(limit), min(self.state.se.max_int(limit), max_memcpy_size)) l.debug("Memcpy running with conditional_size %d", 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, proj=None, funcaddr=None, gotaddr=None, funcname=None): resolve = Callable( proj, funcaddr, SimTypeFunction((), SimTypePointer(self.state.arch, SimTypeTop()))) try: value = resolve() except AngrCallableError: l.critical("Ifunc \"%s\" failed to resolve!", funcname) #import IPython; IPython.embed() raise self.state.memory.store(gotaddr, value, endness=self.state.arch.memory_endness) self.add_successor(self.state, value, self.state.se.true, 'Ijk_Boring')
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) * 8 addr = self.state.libc.heap_location self.state.libc.heap_location += size return addr
def run(self, ptr): #pylint:disable=unused-argument #additional code trace_data = ("free", {"ptr": (ptr, ptr.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())} return self.state.se.Unconstrained('free', self.state.arch.bits)
def run(self, sim_nmemb, sim_size): #additional code trace_data = ("calloc", { "sim_nmemb": (sim_nmemb, sim_nmemb.symbolic), "sim_size": (sim_size, sim_size.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: 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.se.symbolic(sim_nmemb): # TODO: find a better way nmemb = self.state.se.max_int(sim_nmemb) else: nmemb = self.state.se.any_int(sim_nmemb) if self.state.se.symbolic(sim_size): # TODO: find a better way size = self.state.se.max_int(sim_size) else: size = self.state.se.any_int(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.se.BVV(0, final_size * 8) self.state.memory.store(addr, v) return 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, 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) 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.any_int( 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.se.ite_dict(n - definite_size, conditional_rets, 2) 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
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)