def write_bp(state): target_addr = state.inspect.mem_write_address # target_size = state.inspect.mem_write_length if type(target_addr) != int: target_addr = target_addr.args[0] # if type(target_size) != int: # target_size = target_size.args[0] target_size = state.inspect.mem_write_expr.size( ) // state.arch.byte_width if (target_addr >= start_addr + size) \ or (start_addr >= target_addr + target_size): return if (target_addr + target_size > start_addr + size): overflow_len = target_addr + target_size - (start_addr + size) # mem_wriet_expr = state.inspect.mem_write_expr mem_wriet_expr = state.memory.load(target_addr, target_size, endness='Iend_BE') overflow_content = mem_wriet_expr[overflow_len * 8 - 1:0] memory = printable_memory(state, min(start_addr, target_addr), max(size,target_size)\ ,warn_pos = start_addr+size, warn_size = overflow_len, info_pos = target_addr\ ,info_size = target_size) message = "Found chunk overflow at %s." % hex(start_addr) report_logger.warn(message, type='heap_overflow', start_addr = start_addr, size = size, target_addr = target_addr, \ target_size = target_size, overflow_len = overflow_len, overflow_content = overflow_content, \ memory = memory, state_timestamp = state_timestamp(state)) return
def write_bp(state): target_addr = state.inspect.mem_write_address # target_size = state.inspect.mem_write_length if type(target_addr) != int: target_addr = target_addr.args[0] # if type(target_size) != int: # target_size = target_size.args[0] target_expr = state.inspect.mem_write_expr target_size = target_expr.size() // state.arch.byte_width end_addr = start_addr + size if target_addr >= end_addr or \ start_addr >= target_addr + target_size: return overlap_start = max(target_addr, start_addr) overlap_end = min(target_addr + target_size, end_addr) # target_expr = state.inspect.mem_write_expr exists some problems, # it is 'Iend_BE' when display read syscall's content target_expr = state.memory.load(target_addr, target_size, endness='Iend_LE') # target_expr_inspect = state.inspect.mem_write_expr # print(target_expr) # print(target_expr_inspect) overlap_expr = target_expr[(overlap_end - target_addr) * 8 - 1:(overlap_start - target_addr) * 8] memory_expr = memory_content[(overlap_end - start_addr) * 8 - 1:(overlap_start - start_addr) * 8] # print(memory_content) # print(target_expr) # print("addr :%s size:%s" % (hex(target_addr), hex(target_size))) # print("start: %s end: %s overlap_expr: %s" % ((overlap_end-target_addr)*8-1,(overlap_start-target_addr)*8,hex(overlap_expr.args[0]))) # print("start: %s end: %s memory_expr: %s" % ((overlap_end-start_addr)*8-1,(overlap_start-start_addr)*8,hex(memory_expr.args[0]))) # print("\n" + memory + "\n") if (overlap_expr == memory_expr).args[0]: print_start = min(start_addr, target_addr) print_start = (print_start >> 4) << 4 memory = printable_memory(state, print_start, \ max(end_addr, target_addr + target_size) - print_start, \ warn_pos=overlap_start, warn_size=overlap_end - overlap_start, \ info_pos=target_addr, info_size=target_size) # warn_pos=target_addr, warn_size=target_size, \ # info_pos=overlap_start, info_size=overlap_end - overlap_start) bt = stack_backtrace(state) # print(memory) message = "Found shellcode written at %s (%s)." % ( hex(target_addr), pos) report_logger.warn(message, type = "shell_write", \ start_addr=start_addr, size = size, \ target_addr = target_addr, target_size = target_size, \ shellcode_write = target_expr, memory = memory, \ backtrace = printable_backtrace(bt), \ exploit_method = state.project.exploited_state_method, \ state_timestamp = state_timestamp(state))
def write_bp(state): target_addr = state.inspect.mem_write_address # target_size = state.inspect.mem_write_length write_expr = state.inspect.mem_write_expr if type(target_addr) != int: target_addr = target_addr.args[0] # if type(target_size) != int: # target_size = target_size.args[0] target_size = write_expr.size() // state.arch.byte_width # make sure the write covers our addr if (target_addr >= addr + size): return if (target_addr + target_size <= addr): return # break on BP_AFTER, so we only need to get the value we care about # origin = state.memory.load(addr, 8, endness = 'Iend_LE').args[0] # #print(write_expr) bt = stack_backtrace(state) # backup = state.memory.load(target_addr, size) # state.memory.store(target_addr, write_expr, disable_actions=True, inspect = False) modified = state.memory.load(addr, 8, endness='Iend_LE').args[0] # ana.overflow_pos.add(addr) # state.memory.store(target_addr, backup, disable_actions=True, inspect = False) # if origin == 0x4005b4: # print("found %s %s" % origin, modified) if origin == modified: return memory = printable_memory(state, addr-0x10, 0x30 \ , warn_pos=addr, warn_size=0x8) message = "Return address at %s overwritten to %s" % (hex(addr), hex(modified)) state.project.report_logger.warn(message, type='ret_addr_overwrite',stack_address = addr, \ origin_return_address = origin, modified_return_address = modified, \ backtrace = printable_backtrace(bt), state_timestamp = state_timestamp(state), \ memory = memory) # def get_state_starts(state): # return state.history.bbl_addrs.hardcopy[-10:] # # def generate_cfg(cfg_sequence): # last_addr = cfg_sequence[0] # cfg_recorded = networkx.DiGraph() # for addr in cfg_sequence[1:]: # cfg_recorded.add_edge(last_addr, addr) # last_addr = addr # networkx.draw(cfg_recorded) # plt.savefig("ret_%s.png" % state_timestamp(state)) # # generate_cfg(get_state_starts(state)) #print(state.callstack) return
def write_bp(state): nonlocal start_addr, size target_addr = state.inspect.mem_write_address target_size = state.inspect.mem_write_length if type(target_addr) != int: target_addr = target_addr.args[0] if type(target_size) != int: target_size = target_size.args[0] if (target_addr >= start_addr + size) \ or (start_addr >= target_addr + target_size): return info_pos = target_addr info_size = target_size # true analysis starts from here # XXX: at present we extract the write content within the redzone, should we display whole # write content? if target_addr < start_addr: offset = start_addr - target_addr write_size = min(target_size - offset, size) target_addr = start_addr else: offset = 0 write_size = min(target_size, size) assert (write_size) # figure out if this write comes from heap operations if write_size < allow_heap_ops_size: bt = printable_callstack(state) if 'alloc' in bt or 'free' in bt: #print(frame) return write_expr = state.inspect.mem_write_expr write_expr = write_expr[(target_size - offset) * 8 - 1:(target_size - offset - write_size) * 8] if size > 0x40: start_addr = ((target_addr >> 4) << 4) - 0x10 size = ((write_size >> 4) << 4) + 0x10 memory = printable_memory(state, min(start_addr, info_pos)\ , max(size, info_size), warn_pos = target_addr,\ warn_size = write_size, info_pos = info_pos, info_size = info_size) backtrace = printable_callstack(state) message = "Redzone(%s) at %s overwritten." % (mtype, hex(start_addr)) report_logger.warn(message, type="redzone_write",mtype = mtype, start_addr = start_addr, target_addr = target_addr, \ write_size = write_size, write_expr = write_expr, backtrace = backtrace, memory = memory, state_timestamp = state_timestamp(state)) return
def write_bp(state): nonlocal bp_start_addr, bp_size start_addr = bp_start_addr size = bp_size target_addr = state.inspect.mem_write_address # target_size = state.inspect.mem_write_length if type(target_addr) != int: target_addr = target_addr.args[0] # if type(target_size) != int: # target_size = target_size.args[0] target_size = state.inspect.mem_write_expr.size( ) // state.arch.byte_width # it does not overlap if (target_addr >= start_addr + size) \ or (start_addr >= target_addr + target_size): return info_pos = target_addr info_size = target_size # info_pos 是内存写操作的地址 # info_size 是内存写入操作的大小 # true analysis starts from here # XXX: at present we extract the write content within the redzone, should we display whole # write content? if target_addr < start_addr: offset = start_addr - target_addr # target_size : mem_write's size # size : bp's size write_size = min(target_size - offset, size) target_addr = start_addr else: offset = target_addr - start_addr write_size = min(target_size, size - offset) offset = 0 # target_addr 是重叠部分的最低地址 # write_size 是 assert (write_size) # figure out if this write comes from heap operations if write_size < allow_heap_ops_size: bt = printable_callstack(state) if 'alloc' in bt or 'free' in bt: #print(frame) return # write_expr = state.inspect.mem_write_expr write_expr = state.memory.load(info_pos, info_size, endness='Iend_BE') write_expr_inspect = state.inspect.mem_write_expr # print(write_expr) # print(write_expr_inspect) write_expr = write_expr[(target_size - offset) * 8 - 1:(target_size - offset - write_size) * 8] # print("%s %s" % ((target_size-offset)*8 - 1, (target_size-offset-write_size)*8)) # if size > 0x40: start_addr = ((target_addr >> 4) << 4) - 0x10 size = ((size >> 4) << 4) + 0x10 # size = ((write_size>>4)<<4) + 0x10 memory = printable_memory(state, start_addr \ , size, warn_pos = target_addr,\ warn_size = write_size, info_pos = info_pos, info_size = info_size) backtrace = printable_callstack(state) arena = Arena(state) # if arena.arena is not None: # print("=========after red:\n"+arena.output_all_bins()) # arena.do_check() # pass tcache = Tcache(state, state.project.heap_analysis.heapbase) # if tcache.tcache is not None: # print(tcache.output_tcache_bins()) # tcache.do_check() # pass message = "Redzone(%s) at %s overwritten." % (mtype, hex(bp_start_addr)) report_logger.warn(message, type="redzone_write",mtype = mtype, \ write_addr = info_pos, write_size = info_size, start_addr = bp_start_addr, \ covered_addr = target_addr, covered_size = write_size, covered_expr = write_expr.args[0], \ backtrace = backtrace, memory = memory, \ state_timestamp = state_timestamp(state), \ malloc_state = "None" if arena.arena is None else arena.output_all_bins(), \ tcache = "None" if tcache.tcache is None else tcache.output_tcache_bins()) return