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
Exemple #2
0
    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