示例#1
0
def Functions(start=None, end=None):
    """
    Get a list of functions

    @param start: start address (default: inf.min_ea)
    @param end:   end address (default: inf.max_ea)

    @return: list of heads between start and end

    @note: The last function that starts before 'end' is included even
    if it extends beyond 'end'. Any function that has its chunks scattered
    in multiple segments will be reported multiple times, once in each segment
    as they are listed.
    """
    if not start: start = ida_ida.cvar.inf.min_ea
    if not end:   end = ida_ida.cvar.inf.max_ea

    # find first function head chunk in the range
    chunk = ida_funcs.get_fchunk(start)
    if not chunk:
        chunk = ida_funcs.get_next_fchunk(start)
    while chunk and chunk.start_ea < end and (chunk.flags & ida_funcs.FUNC_TAIL) != 0:
        chunk = ida_funcs.get_next_fchunk(chunk.start_ea)
    func = chunk

    while func and func.start_ea < end:
        startea = func.start_ea
        yield startea
        func = ida_funcs.get_next_func(startea)
示例#2
0
    def __process_functions(self):
        functions = list()

        start = ida_ida.cvar.inf.min_ea
        end = ida_ida.cvar.inf.max_ea

        # find first function head chunk in the range
        chunk = ida_funcs.get_fchunk(start)

        if not chunk:
            chunk = ida_funcs.get_next_fchunk(start)
        while chunk and chunk.start_ea < end and (chunk.flags
                                                  & ida_funcs.FUNC_TAIL) != 0:
            chunk = ida_funcs.get_next_fchunk(chunk.start_ea)

        func = chunk

        while func and func.start_ea < end:
            start_ea = func.start_ea

            func_flags = ida_bytes.get_full_flags(start_ea)
            func_name = ida_funcs.get_func_name(start_ea)
            func_name_demangled = ida_name.get_demangled_name(
                start_ea, 0xFFFF, 0, 0)
            func_autonamed = func_flags & ida_bytes.FF_LABL != 0
            func_public = ida_name.is_public_name(start_ea)

            function = {
                'start_rva': start_ea - self._base,
                'name': func_name,
                'name_demangled': func_name_demangled,
                'is_public': func_public,
                'is_autonamed': func_autonamed
            }

            # PE32/PE32+ only support binaries up to 2GB
            if function['start_rva'] >= 2**32:
                print('RVA out of range for function: ' + function['name'],
                      file=sys.stderr)

            self.__process_function_typeinfo(function, func)

            function['labels'] = self.__process_function_labels(func)

            functions.append(function)

            func = ida_funcs.get_next_func(start_ea)

        return functions
示例#3
0
def dump_func_info(ea):
    "dump info about function chunk at address 'ea'"
    pfn = ida_funcs.get_fchunk(ea)
    if pfn is None:
        print("No function at %08X!" % ea)
        return
    print("current chunk boundaries: %08X..%08X" % (pfn.start_ea, pfn.end_ea))
    dump_flags(pfn)
    if (ida_funcs.is_func_entry(pfn)):
        print("This is an entry chunk")
        dump_tails(pfn)
        dump_frame(pfn)
        dump_regvars(pfn)
        dump_regargs(pfn)
        dump_stkpnts(pfn)
    elif (ida_funcs.is_func_tail(pfn)):
        print("This is a tail chunk")
        dump_parents(pfn)
示例#4
0
    def StartPtAnalysis(self, startEa):
        curEa = startEa
        nextEa = 0  # Next IDA Address

        while True:
            #Read next packet
            line = self.hTraceFile.readline()
            if (line == '' or line.strip() == 'END'): break
            line = line.strip()
            if (line == ''): continue
            nextPck = self.GetPacket(line)
            self.lineNumber += 1

            nextEa = self.AnalyseNextChunk(curEa, nextPck)
            if (nextEa == 0):
                # Here it means that we are in 2 totally different points in the code (kernel drivers are a good example)
                if (nextPck[1][:3] != "fup" and nextPck[1][:3] != "tip"):
                    print(
                        "I found an internal error. Packet ID: %s, type: %s, current IP: %s"
                        % (hex(nextPck[0]), nextPck[1], hex(curEa)[:-1]))
                    break
                completePtAddr = self.GetPtPckFullIP(nextPck)
                nextEa = self.GetIdaAddress(completePtAddr)
                print(
                    "Found another unrelated block of code in the DUMP. Start at %s. Line #%d in the dump file."
                    % (hex(nextEa)[:-1], self.lineNumber))
            elif (nextEa == -1):
                # Some errors or we are done
                break

            self.lastPtPck = nextPck
            curEa = nextEa

        # Complete this dump if the last packet is a pgd
        lastEa = ida_funcs.get_fchunk(curEa).endEA
        if (nextPck[1][-3:] == "pgd" and curEa != lastEa):
            while (curEa < lastEa):
                mnem = idc.GetMnem(curEa)
                self.ColorInstruction(curEa)
                if (mnem[0] == "j" or mnem[:4] == "loop" or mnem == "call"
                        or mnem == "ret" or mnem == "retn"):
                    break
                curEa = idc.NextHead(curEa)
        return True
示例#5
0
def fix_func_prolog(ea, end_ea=idc.BADADDR):
    global FUNC_BY_LS

    func_cnt = 0
    func = ida_funcs.get_fchunk(ea)
    if func is None:
        func = ida_funcs.get_next_func(ea)
    ea = func.start_ea

    while func is not None and ea < end_ea:
        # if current function is small enough and there exists a function right
        # next to current function
        if (func.size() <= 8 and idc.get_func_attr(
                func.end_ea, idc.FUNCATTR_START) != idc.BADADDR):
            # If the next function can be connected, there must be a basic block reference.
            # xref.type == 21 means 'fl_F', which is an ordinary flow.
            if all(
                (func.start_ea <= xref.frm < func.end_ea) and xref.type == 21
                    for xref in XrefsTo(func.end_ea)):
                if func_cnt > 0 and func_cnt % 1000 == 0:
                    print("%x <- %x: prolog merging (%d)." %
                          (func.start_ea, func.end_ea, func_cnt))
                ida_bytes.del_items(func.end_ea, ida_bytes.DELIT_EXPAND)
                ida_bytes.del_items(func.start_ea, ida_bytes.DELIT_EXPAND)
                ida_auto.auto_wait()

                status = idc.add_func(func.start_ea)
                if not status:
                    print("Error merging 0x%x <- 0x%x" %
                          (func.start_ea, func.end_ea))
                else:
                    func_cnt += 1
                    FUNC_BY_LS.discard(func.end_ea)
                ida_auto.auto_wait()

        func = ida_funcs.get_next_func(ea)
        if func:
            ea = func.start_ea

    print("Fixed %d functions" % func_cnt)
示例#6
0
def analyze_ida_str():
    global all_str
    if "all_str" not in globals():
        all_str = idautils.Strings()

    str_cnt = 0
    start_time = time.time()

    for s in all_str:
        # check if there exists already assigned function or string
        if any(
                ida_funcs.get_fchunk(ea) or (idc.get_str_type(ea) is not None)
                for ea in (s.ea, s.ea + s.length)):
            continue

        if check_string(30) and create_string(s.ea):
            str_cnt += 1
            if str_cnt % 1000 == 0:
                print("%x: %d strings has been found. (%0.3f secs)" %
                      (s.ea, str_cnt, time.time() - start_time))

    print("Created %d strings. (%0.3f secs)" %
          (str_cnt, time.time() - start_time))
示例#7
0
def processFunctions():
    functions = list()

    start = ida_ida.cvar.inf.min_ea
    end = ida_ida.cvar.inf.max_ea

    # find first function head chunk in the range
    chunk = ida_funcs.get_fchunk(start)

    if not chunk:
        chunk = ida_funcs.get_next_fchunk(start)
    while chunk and chunk.start_ea < end and (chunk.flags
                                              & ida_funcs.FUNC_TAIL) != 0:
        chunk = ida_funcs.get_next_fchunk(chunk.start_ea)

    func = chunk

    while func and func.start_ea < end:
        start_ea = func.start_ea

        flags = ida_bytes.get_full_flags(start_ea)

        function = {
            'start_ea': start_ea,
            'name': ida_funcs.get_func_name(start_ea),
            'is_public': ida_name.is_public_name(start_ea),
            'is_autonamed': flags & ida_bytes.FF_LABL != 0
        }

        processFunctionTypeinfo(function)

        functions.append(function)

        func = ida_funcs.get_next_func(start_ea)

    return functions
 def __call__(self):
     tail = ida_funcs.get_fchunk(self.tail_ea)
     ida_funcs.set_tail_owner(tail, self.owner_func)
示例#9
0
 def _on_tailownerchanged(self, tail_ea, owner_func):
     tail = ida_funcs.get_fchunk(tail_ea)
     ida_funcs.set_tail_owner(tail, owner_func)