def process_func(i): """Convert function i into a mega file line.""" func = idaapi.getn_func(i) if not func: return if idaapi.has_name(idaapi.getFlags(func.startEA)) and \ not (func.flags & idaapi.FUNC_LIB): return create_func_signature(func.startEA, func.endEA - func.startEA)
def has_name(self): """Does the current line have a non-trivial (non-dummy) name?""" return idaapi.has_name(self.flags)
def has_name(self): """Does the current line have a non-trivial (non-dummy) name?""" return idaapi.has_name(self.flags)
def create_func_signature(start, length): """Return function signature in mega format.""" if length < MIN_SIG_LENGTH: return ea = start end = start + length sig = "" publics = [] refs = {} v = [False for _ in range(length)] while (ea - start < length): flags = idaapi.getFlags(ea) if idaapi.has_name(flags): publics.append(ea) ref = idaapi.get_first_dref_from(ea) if ref != idaapi.BADADDR: ref_loc = ea set_v_bytes(v, ref_loc - start) refs[ref_loc] = ref # Check if there is a second data location ref'd ref = idaapi.get_next_dref_from(ea, ref) if ref != idaapi.BADADDR: ref_loc = ea set_v_bytes(v, ref_loc - start) refs[ref_loc] = ref else: # Code ref? ref = idaapi.get_first_fcref_from(ea) if ref != idaapi.BADADDR: if not start <= ref < end: ref_loc = ea set_v_bytes(v, ref_loc - start) refs[ref_loc] = ref # Check for r13 and rtoc disasm = idaapi.generate_disasm_line(ea) if "%r13" in disasm or "%rtoc" in disasm: ref_loc = ea set_v_bytes(v, ref_loc - start) ea = idaapi.next_not_tail(ea) line = "" for i in range(length): if v[i]: line += ".." else: line += "{:02X}".format(idaapi.get_byte(start + i)) # Write publics found = False for public in sorted(publics): name = idaapi.get_true_name(idaapi.BADADDR, public) if name: found = True if is_skipped(name): idaapi.warning("Rename the function {} ({})!".format( name, "it is on the skip list")) return else: line += " :{:04X} {}".format(public - start, name) if not found: idaapi.warning("The function has autogenerated name, rename it first!") # Write refs for ref_loc, ref in sorted(refs.items()): name = idaapi.get_true_name(idaapi.BADADDR, ref) if name: if not is_skipped(name) and ref_loc != idaapi.BADADDR: line += " ^{:04X} {}".format(ref_loc - start, name) return line
def make_func_sigs(config): logger = logging.getLogger("idb2pat:make_func_sigs") sigs = [] if config.mode == USER_SELECT_FUNCTION: f = idaapi.choose_func("Choose Function:", idc.BADADDR) if f is None: logger.error("No function selected") return [] idc.jumpto(f.start_ea) if not idaapi.has_any_name(idc.get_full_flags(f.start_ea)): logger.error("Function doesn't have a name") return [] try: sigs.append(make_func_sig(config, f)) except Exception as e: logger.exception(e) logger.error("Failed to create signature for function at %s (%s)", hex(f.start_ea), idc.get_func_name(f.start_ea) or "") elif config.mode == NON_AUTO_FUNCTIONS: for f in get_functions(): # HTC - remove check FUNC_LIB flag to include library functions if idaapi.has_name(idc.get_full_flags(f.start_ea)): # and f.flags & idc.FUNC_LIB == 0: try: sigs.append(make_func_sig(config, f)) except FuncTooShortException: pass except Exception as e: logger.exception(e) logger.error( "Failed to create signature for function at %s (%s)", hex(f.start_ea), idc.get_name(f.start_ea) or "") elif config.mode == LIBRARY_FUNCTIONS: for f in get_functions(): if idaapi.has_name(idc.get_full_flags( f.start_ea)) and f.flags & idc.FUNC_LIB != 0: try: sigs.append(make_func_sig(config, f)) except FuncTooShortException: pass except Exception as e: logger.exception(e) logger.error( "Failed to create signature for function at %s (%s)", hex(f.start_ea), idc.get_name(f.start_ea) or "") elif config.mode == PUBLIC_FUNCTIONS: for f in get_functions(): if idaapi.is_public_name(f.start_ea): try: sigs.append(make_func_sig(config, f)) except FuncTooShortException: pass except Exception as e: logger.exception(e) logger.error( "Failed to create signature for function at %s (%s)", hex(f.start_ea), idc.get_name(f.start_ea) or "") elif config.mode == ENTRY_POINT_FUNCTIONS: for i in zrange(idaapi.get_func_qty()): f = idaapi.get_func(idaapi.get_entry(idaapi.get_entry_ordinal(i))) if f is not None: try: sigs.append(make_func_sig(config, f)) except FuncTooShortException: pass except Exception as e: logger.exception(e) logger.error( "Failed to create signature for function at %s (%s)", hex(f.start_ea), idc.get_name(f.start_ea) or "") elif config.mode == ALL_FUNCTIONS: n = idaapi.get_func_qty() for i, f in enumerate(get_functions()): try: logger.info("[ %d / %d ] %s %s", i + 1, n, idc.get_name(f.start_ea), hex(f.start_ea)) sigs.append(make_func_sig(config, f)) except FuncTooShortException: pass except Exception as e: logger.exception(e) logger.error( "Failed to create signature for function at %s (%s)", hex(f.start_ea), idc.get_name(f.start_ea) or "") return sigs