def run(self, arg): for function in idautils.Functions(): values = {} #function = ida_kernwin.get_screen_ea() function_start = idc.get_func_attr(function, idc.FUNCATTR_START) function_end = idc.get_func_attr(function, idc.FUNCATTR_END) function_name = idc.get_func_name(function) if "func" in function_name: try: values[function_name] = [] for z in re.findall("= (0[xX][0-9a-fA-F]+)",str(ida_hexrays.decompile(function))): values[function_name].append(binascii.hexlify(struct.pack('<Q', int(int(z.replace("0x", ""), base=16)))).decode("windows-1252").replace("00","")) except idaapi.DecompilationFailure: pass lenght = int(len(values[function_name]) / 2) string = self.to_decimal(values[function_name][0:lenght]) key = self.to_decimal(values[function_name][lenght::]) str_decrypted = "" for i in range(0, len(string)): str_decrypted += chr(string[i] ^ key[i % len(key)]) #idaapi.msg(f"{string[i]} ^ {key[i % len(key)]}\n") if str_decrypted != "": #idaapi.msg(str_decrypted+"\n") idc.set_func_cmt(function_start, str_decrypted, 0) rowPosition = self.plg.table.rowCount() self.plg.table.insertRow(rowPosition) self.plg.table.setItem(rowPosition, 0, QtWidgets.QTableWidgetItem(function_name)) self.plg.table.setItem(rowPosition, 1, QtWidgets.QTableWidgetItem(str_decrypted))
def main(): log("plugin run") if not is_jni_header_loaded(): idaapi.warning('Please load jni.h first') load_jni_header() st = idc.set_ida_state(idc.IDA_STATUS_WORK) infos = load_methods() failed = [] succ = 0 for ea in idautils.Functions(): fname = idc.get_func_name(ea) if fname.startswith('Java_'): info = infos.get(fname) if info is None: failed.append(fname) else: succ += 1 apply_signature(ea, info) if fname == 'JNI_OnLoad': apply_load_unload(ea, True) succ += 1 if fname == 'JNI_OnUnload': apply_load_unload(ea, False) succ += 1 idaapi.info('JNI functions loaded, {} success. {} failed. \n{}'.format( succ, len(failed), '\n'.join(failed))) idc.set_ida_state(st)
def _get_tif_with_guess_type(address: int) -> Optional[ida_typeinf.tinfo_t]: """ Attempt to get the tinfo_t object for the function using the "guess_type" function. :raises: RuntimeError on failure. :returns: tinfo_t object on success. """ guessed_type = idc.guess_type(address) if guessed_type is None: return None func_name = idc.get_func_name(address) if func_name is None: return None # Documentation states the type must be ';' terminated, also the function name must be inserted guessed_type = re.sub(r"\(", f" {func_name}(", f"{guessed_type};") set_type_result = idc.SetType(address, guessed_type) if not set_type_result: logger.warning( f"Failed to SetType for function at 0x{address:X} with guessed type {guessed_type!r}" ) tif = ida_typeinf.tinfo_t() if not ida_nalt.get_tinfo(tif, address): return None return tif
def RenameMod(orig, new): i = idc.get_next_func(0) while (i != BADADDR): n = idc.get_func_name(i) if n.startswith(orig + "_"): RenameFuncWithNewMod(i, new) i = NextFunction(i)
def format_rules(fva, rules): ''' given the address of a function, and the byte signatures for basic blocks in the function, format a complete YARA rule that matches all of the basic block signatures. ''' name = idc.get_func_name(fva) # some characters aren't valid for YARA rule names safe_name = name BAD_CHARS = '@ /\\!@#$%^&*()[]{};:\'",./<>?' for c in BAD_CHARS: safe_name = safe_name.replace(c, '') md5 = idautils.GetInputFileMD5().hex() ret = [] ret.append(f'rule a_{md5}_{safe_name}') ret.append(' meta:') ret.append(f' sample_md5 = "{md5}"') ret.append(f' function_address = "0x{fva}"') ret.append(f' function_name = "{name}"') ret.append(' strings:') for rule in rules: formatted_rule = ' '.join(rule.masked_bytes) ret.append(f' {rule.name} = {{{formatted_rule}}}') ret.append(' condition:') ret.append(' all of them') ret.append('}') return '\n'.join(ret)
def GetCanonicalName(f): n = idc.get_func_name(f) parts = n.split("_") if len(parts) == 3: return parts[1] else: return None
def enum_func(self): ### iterate to all functions of the malware ea = here() func_addr = 0 seg_start = idc.get_segm_start(ea) seg_end = idc.get_segm_end(ea) for func_addr in idautils.Functions(seg_start, seg_end): func_name = idc.get_func_name(func_addr) if self.seh_func_name in func_name: print("[+] STATUS: Found Needed Function -> {} {}".format( hex(func_addr), func_name)) break else: pass #print("[-] STATUS: Skipped this Function -> {} {}".format(hex(func_addr),func_name)) self.find_xref_func(func_addr) ### find the ehFuncInfo Address which is the mov address before the jmp to ___CxxFrameHandler ### .text:00407B60 mov eax, offset stru_408928 ### .text:00407B65 jmp ___CxxFrameHandler self.find_ehfuncinfo_addr() return
def jtool2_information(): print("[-] Other method information construction") fd = open(kernelcache_path) data = fd.readlines() fd.close() for line in data: t = line[:-1].strip() addr = int(t.split("|")[0], 0) sym = t.split("|")[1] segName = idc.get_segm_name(addr) if segName != "__TEXT_EXEC:__text" or "." in sym: if "__DATA" in segName: idaapi.set_name(addr, sym, idaapi.SN_FORCE) continue if not idau.is_function_start(addr): print("[jtool2] Current '{}'' - [{}] is not defined as function". format(sym, hex(addr))) if not idau.force_function(addr): print("[jtool2] Can't convert '{}' - [{}] to function".format( sym, hex(addr))) continue curSym = idc.get_func_name(addr) if "sub_" in curSym: idaapi.set_name(addr, sym, idaapi.SN_FORCE) print("[-] Done")
def iter_functions( func_names: Union[None, str, List[str]] = None) -> Iterable[Tuple[int, str]]: """ Iterate all defined functions and yield their address and name. (This includes imported and dynamically generated functions) :param func_names: Filter based on specific function names. :yield: (ea, name) """ if isinstance(func_names, str): func_names = [func_names] # Yield declared functions. for ea in idautils.Functions(): name = idc.get_func_name(ea) if (not func_names or name in func_names or name.strip("_") in func_names or any( re.match("_*{}_[0-9]?".format(name_), name) for name_ in func_names)): yield ea, name # Also yield from imported. for ea, name, _ in iter_imports(api_names=func_names): yield ea, name # Yield dynamically resolved functions. for ea, name in iter_dynamic_functions(): if (not func_names or name in func_names or name.strip("_") in func_names or any( re.match("_*{}_[0-9]?".format(name_), name) for name_ in func_names)): yield ea, name
def Create(self): ea = idc.get_screen_ea() if not idaapi.simplecustviewer_t.Create( self, '%s - Nao' % (idc.get_func_name(ea))): return False self.instruction_list = idautils.GetInstructionList() self.instruction_list.extend(['ret']) self.register_list = idautils.GetRegisterList() self.register_list.extend([ 'r8l', 'r9l', 'r10l', 'r11l', 'r12l', 'r13l', 'r14l', 'r15l', 'r8w', 'r9w', 'r10w', 'r11w', 'r12w', 'r13w', 'r14w', 'r15w', 'r8d', 'r9d', 'r10d', 'r11d', 'r12d', 'r13d', 'r14d', 'r15d', 'eax', 'ebx', 'ecx', 'edx', 'edi', 'esi', 'ebp', 'esp', 'rax', 'rbx', 'rcx', 'rdx', 'rdi', 'rsi', 'rbp', 'rsp' ]) f = idaapi.get_func(ea) self.fc = idaapi.FlowChart(f) self.block_list = [] for block in self.fc: self.block_list.append(format(block.start_ea, 'x').upper()) self.load(ea) action_desc = idaapi.action_desc_t( 'nao:jump', # The action name. 'Jump', # The action text. JumpHandler(self), # The action handler. '', # Optional: the action shortcut '', # Optional: the action tooltip (available in menus/toolbar) ) # Optional: the action icon (shows when in menus/toolbars) use numbers 1-255 idaapi.register_action(action_desc) idaapi.attach_action_to_popup(self.GetWidget(), None, 'nao:jump', None) return True
def apply_load_unload(ea, load=True): name = idc.get_func_name(ea) log('apply 0x%x %s', ea, name) decl = "{} {}(JavaVM *vm, void *reserved)".format( "jint" if load else "void", "JNI_OnLoad" if load else "JNI_OnUnload") prototype_details = idc.parse_decl(decl, idc.PT_SILENT) idc.apply_type(ea, prototype_details)
def make_new_name(start_addr, end_addr, off_new_name, off_func_addr): # offset1 -> handle string -> get new func name # offset2 -> handle func -> get func addr for addr in range(start_addr, end_addr, off_new_name): # first addr is string using to new func name name_addr = [ref for ref in idautils.DataRefsFrom(addr)] if len(name_addr) < 1: frn_log("can't get name addr") continue new_name = idc.et_strlit_contents(name_addr[0]) frn_log("Get new func name is :{}".format(new_name)) # Get the address of the function to be renamed # name_addr = [ref for ref in DataRefsFrom(0x5B200)][0] func_addr = [ ref for ref in idautils.DataRefsFrom(addr + off_func_addr) ][0] # for xref in idautils.XrefsFrom(addr+off_func_addr, 0): # func_addr = xref.to # --- Check if the function needs to be renamed old_name = idc.get_func_name(func_addr) if 'sub_' not in old_name: frn_log("The function has been renamed") continue name = 'func_' + new_name.decode() frn_log("The new func name is :{}".format(new_name)) frn_log("The func addr is :{:#x}".format(func_addr)) idc.set_name(func_addr, name)
def activate(self, ctx): import json filepath = ida_kernwin.ask_file(False, "*.zmu;*.overlay;*", "Load Zelos Overlay...") if filepath is None: return f = open(filepath, "r") zelos_data = f.read() f.close() zelos_data = zelos_data[len("DISAS\n"):] zelos_dump = json.loads(zelos_data) # Apply the overlay data for comment in zelos_dump["comments"]: ea = comment["address"] try: comment_text = str(comment["text"]) except UnicodeEncodeError: comment_text = "" color = comment.get("color", 0x73F0DF) # Set color of instruction line idaapi.set_item_color(ea, color) idaapi.set_cmt(ea, comment_text, False) # Set function name if not already changed idc.get_func_attr(ea, idc.FUNCATTR_START) name = idc.get_func_name(ea) if len(name) > 0 and name.startswith("zmu_") is False: idc.set_name(ea, "zmu_" + name) return 1
def _get_function_tif_with_guess_type(offset): """ Attempt to get the tinfo_t object of a function using the "guess_type" function. :param offset: Offset of function. :raises: RuntimeError on failure. :returns: tinfo_t object on success. """ tif = ida_typeinf.tinfo_t() guessed_type = idc.guess_type(offset) if guessed_type is None: raise RuntimeError( "Failed to guess function type for offset 0x{:X}".format(offset)) func_name = idc.get_func_name(offset) if func_name is None: raise RuntimeError( "Failed to get function name for offset 0x{:X}".format(offset)) # Documentation states the type must be ';' terminated, also the function name must be inserted guessed_type = re.sub(r"\(", " {}(".format(func_name), "{};".format(guessed_type)) set_type_result = idc.SetType(offset, guessed_type) if not set_type_result: logger.warning( "Failed to SetType for function at 0x{:X} with guessed type {!r}". format(offset, guessed_type)) # Try one more time to get the tinfo_t object if not ida_nalt.get_tinfo(tif, offset): raise RuntimeError( "Failed to obtain tinfo_t object for offset 0x{:X}".format(offset)) return tif
def scanDatabase(self, json_configuration): configuration = "" try: configuration = json.loads(json_configuration) except: print("IDA Function Tagger: Invalid configuration file") return print("IDA Function Tagger: Loading configuration: %s" % configuration["name"]) print("IDA Function Tagger: Configuration comment: %s" % configuration["comment"]) for tag in configuration["tag_list"]: print("IDA Function Tagger: Scanning for tag '%s'..." % tag["name"]) for imported_function in tag["import_list"]: function_address = idc.get_name_ea_simple( str(imported_function)) if function_address == BADADDR: continue cross_reference_list = idautils.CodeRefsTo(function_address, 0) for xref in cross_reference_list: function_name = idc.get_func_name(xref) self._addTagToFunction(function_name, str(tag["name"]))
def update(self): global OPEN_TAG global CLOSE_TAG global TAG_SEPARATOR self.clear() for function_address in idautils.Functions(): function_comment = idc.get_func_cmt(function_address, False) tag_list_start = function_comment.find(OPEN_TAG) if tag_list_start == -1: continue tag_list_end = function_comment.find(CLOSE_TAG, tag_list_start) if tag_list_end == -1: continue tag_list = function_comment[tag_list_start + len(OPEN_TAG): tag_list_end] if len(tag_list) == 0: continue current_function_name = idc.get_func_name(function_address) self._function_list[current_function_name] = tag_list.split( TAG_SEPARATOR) tag_list = tag_list.split(TAG_SEPARATOR) for tag_name in tag_list: if tag_name not in self._tag_list: self._tag_list[tag_name] = [] self._tag_list[tag_name].append(current_function_name)
def find_game_init(): strings = idautils.Strings() taint_ea = None # Find the string which is referenced only in CGameUI::Initialize for i in strings: if taint_ea is None and str(i) == 'Whether taint logging is enabled': taint_ea = i.ea break if taint_ea is None: raise RuntimeError('Unable to find CGGameUI::Initialize (1)') refs = list(idautils.DataRefsTo(taint_ea)) if len(refs) != 1: raise RuntimeError('Unable to find CGGameUI::Initialize (2)') func_start = find_func_containing(refs[0]) func_name = idc.get_func_name(func_start) mangled_name = '__ZN8CGGameUI10InitializeEv' if func_name != mangled_name: idc.set_name(func_start, mangled_name, SN_CHECK) print('CGGameUI::Initialize: 0x%x ' % func_start) return func_start
def apply_signature(ea, sig): name = idc.get_func_name(ea) ret, args = sig log('apply 0x%x %s', ea, name) decl = '{} {}({})'.format(ret, name, args) # log(decl) prototype_details = idc.parse_decl(decl, idc.PT_SILENT) # idc.set_name(ea, name) idc.apply_type(ea, prototype_details)
def PrefixRange(start, end, prefix): x = start while x < end: n = idc.get_func_name(x) if n.startswith("sub_"): nn = prefix + n print "Renaming %s to %s\n" % (n, nn) ida_name.set_name(x, nn) x = NextFunction(x)
def function_xrefs(name): import idc import idautils functions_that_exit = [] wf_addr = idc.get_name_ea_simple(name) print hex(wf_addr), idc.generate_disasm_line(wf_addr, 0) for addr in idautils.CodeRefsTo(wf_addr, 0): functions_that_exit.append(idc.get_func_name(addr)) return functions_that_exit
def get_xref_code_to_func(func_addr): a = idautils.XrefsTo(func_addr, 1) addr = {} for xref in a: frm = xref.frm # ea in func start = idc.get_func_attr(frm, idc.FUNCATTR_START) # to_xref func addr func_name = idc.get_func_name(start) # to_xref func name addr[func_name] = [xref.iscode, start] return addr
def get_conflict(self): """ :return: None if there's no conflict, empty string if there's no change, data if there's a change. """ # TODO: Fill docstring, plus, make the function return 0,1,2 and save the current data by itself. if not idc.get_func_name(self.address): return None return ''
def CompileFuncNamesFromRangeAsText(start, end, sep): x = start s = "" while (x <= end): n = idc.get_func_name(x) if (not n.startswith("sub_")): s += " " + sep + " " + n x = NextFunction(x) return s
def RenameRangeWithAddr(start, end, s): x = start while (x <= end): n = idc.get_func_name(x) if (n.startswith("sub_")): RenameFuncWithAddr(x, s) else: NameCanonical(x, s, n) x = NextFunction(x)
def track_ke_event_callback_set(): logger = CustomLogger() m = CodeEmulator() at = ArgumentTracker() event_dict = {} target_addr = idaapi.get_name_ea(idaapi.BADADDR, "ke_event_callback_set") print "ke_event_callback_set: 0x{:X}".format(target_addr) for xref in XrefsTo(target_addr, 0): frm_func = idc.get_func_name(xref.frm) r1_ret = at.track_register(xref.frm, "r1") r0_ret = at.track_register(xref.frm, "r0") if r0_ret.has_key("target_ea") and r1_ret.has_key("target_ea"): start_ea = min(r0_ret['target_ea'], r1_ret['target_ea']) if m.emulate(start_ea, xref.frm): r1 = m.mu.reg_read(UC_ARM_REG_R1) r0 = m.mu.reg_read(UC_ARM_REG_R0) callback_func_name = idc.get_func_name(r1) if callback_func_name == "": define_func(r1, "event_{}_callback_func".format(r0)) callback_func_name = idc.get_func_name(r1) if r1 & 1: r1 -= 1 event_dict[r0] = r1 logger.log( "addr: 0x{:X}, event: 0x{:X}, callback: {} @ 0x{:X}". format(xref.frm, r0, callback_func_name, r1)) target_addr = idaapi.get_name_ea(idaapi.BADADDR, "ke_event_set") print "ke_event_set: 0x{:X}".format(target_addr) for xref in XrefsTo(target_addr, 0): r0_ret = at.track_register(xref.frm, "r0") if r0_ret.has_key("target_ea"): start_ea = r0_ret['target_ea'] if m.emulate(start_ea, xref.frm): r0 = m.mu.reg_read(UC_ARM_REG_R0) logger.log("addr: 0x{:X}, use event: {}".format(xref.frm, r0)) add_ref(xref.frm, event_dict[r0])
def strip_names(name_dict_path): names = {} for i, func_ea in enumerate(idautils.Functions()): n = idc.get_func_name(func_ea) new_name = "f_{i}".format(i=i) names[n] = new_name idc.set_name(func_ea, new_name) with open(name_dict_path, "w") as f: json.dump(names, f, indent=4) return names
def _getArgsDescription(ea: int) -> str: name = demangle_name(get_func_name(ea), get_inf_attr(INF_SHORT_DN)) # get from mangled name if not name: name = get_type(ea) # get from type if not name: return parse_function_args(ea) # cannot get params from the mangled name args_start = name.find('(') if args_start is not None and args_start != (-1): return name[args_start:] return ""
def _getFunctionNameAt(ea: int) -> str: name = get_func_name(ea) disable_mask = get_inf_attr(INF_SHORT_DN) demangled_name = demangle_name(name, disable_mask) if demangled_name is None: return name args_start = demangled_name.find('(') if args_start is None: return demangled_name return demangled_name[:args_start]
def obtain_function_by_name(func_name): """ Obtain a function in the list of functions for the application by name, or idc.BADADDR. :param func_name: Name of function to obtain :return: start_ea of function or idc.BADADDR """ for func in idautils.Functions(): if func_name == idc.get_func_name(func): return func return idc.BADADDR
def __init__(self, frm_va, to_va, old_to_va): """Create a new ObjcMethodXref object Arguments: frm_va {number} -- Virtual address location of the reference to_va {[type]} -- Virtual address that is pointed to by the reference old_to_va {[type]} -- Virtual address that was pointed to by the reference prior to patching """ self.frm_va = frm_va self.to_va = to_va self.old_to_va = old_to_va self.method_name = get_func_name(self.to_va)
def get_items_for_ea(self, ea): frm = [x.frm for x in idautils.XrefsTo(self.__ea)] items = [] for ea in frm: try: cfunc = idaapi.decompile(ea) self.functions.append(cfunc.entry_ea) self.items.append((ea, idc.get_func_name(cfunc.entry_ea), self.get_decompiled_line(cfunc, ea))) except Exception as e: print('could not decompile: %s' % (str(e), )) raise return
def get_symbol_name(from_ea, ea=None, allow_dummy=False): if ea is None: ea = from_ea global _FORCED_NAMES if ea in _FORCED_NAMES: return _FORCED_NAMES[ea] flags = idc.get_full_flags(ea) if not allow_dummy and idaapi.has_dummy_name(flags): return "" name = "" try: name = name or idc.get_name(ea, 0) #calc_gtn_flags(from_ea, ea)) except: pass try: name = name or idc.get_func_name(ea) except: pass return name
def get_items_for_type(self): x = self.target.operands['x'] m = self.target.operands['m'] xtype = x.type xtype.remove_ptr_or_array() typename = idaapi.print_tinfo('', 0, 0, idaapi.PRTYPE_1LINE, xtype, '', '') addresses = [] for ea in idautils.Functions(): try: cfunc = idaapi.decompile(ea) except: print('Decompilation of %x failed' % (ea, )) continue str(cfunc) for citem in cfunc.treeitems: citem = citem.to_specific_type if not (type(citem) == idaapi.cexpr_t and citem.opname in ('memptr', 'memref')): continue _x = citem.operands['x'] _m = citem.operands['m'] _xtype = _x.type _xtype.remove_ptr_or_array() _typename = idaapi.print_tinfo('', 0, 0, idaapi.PRTYPE_1LINE, _xtype, '', '') #~ print 'in', hex(cfunc.entry_ea), _typename, _m if not (_typename == typename and _m == m): continue parent = citem while parent: if type(parent.to_specific_type) == idaapi.cinsn_t: break parent = cfunc.body.find_parent_of(parent) if not parent: print('cannot find parent statement (?!)') continue if parent.ea in addresses: continue if parent.ea == idaapi.BADADDR: print('parent.ea is BADADDR') continue addresses.append(parent.ea) self.functions.append(cfunc.entry_ea) self.items.append(( parent.ea, idc.get_func_name(cfunc.entry_ea), self.get_decompiled_line(cfunc, parent.ea))) return []