def callback(self, event, *args): if event == idaapi.hxe_populating_popup: form, phandle, vu = args if vu.item.citype == idaapi.VDI_FUNC or ( vu.item.citype == idaapi.VDI_EXPR and vu.item.e.is_expr() and vu.item.e.type.is_funcptr()): idaapi.attach_action_to_popup(form, phandle, ACTION_HX_REMOVERETTYPE, None) elif event == idaapi.hxe_double_click: vu, shift_state = args # auto jump to target if clicked item is xxx->func(); if vu.item.citype == idaapi.VDI_EXPR and vu.item.e.is_expr(): expr = idaapi.tag_remove(vu.item.e.print1(None)) if "->" in expr: # find target function name = expr.split("->")[-1] addr = idc.get_name_ea_simple(name) if addr == idaapi.BADADDR: # try class::function e = vu.item.e while e.x: e = e.x addr = idc.get_name_ea_simple( "%s::%s" % (str(e.type).split()[0], name)) if addr != idaapi.BADADDR: idc.jumpto(addr) return 1 return 0
def find_image4_validate_property_callback_interposer_ptr(ea): ea_list = list(idautils.XrefsTo(ea)) if ea_list[0].frm != ida_idaapi.BADADDR: ptr_ea = ea_list[0].frm print( "\t[+] _image4_validate_property_callback_interposer_ptr = 0x%x" % (ptr_ea)) idc.set_name(ptr_ea, "_image4_validate_property_callback_interposer_ptr", idc.SN_CHECK) ptr_ea_list = list(idautils.XrefsTo(ptr_ea)) i4_hash_ptr_ea = ptr_ea_list[0].frm + 8 src = idc.print_operand(i4_hash_ptr_ea, 1) i4_hash_ptr_ea = idc.get_name_ea_simple(src) print("\t[+] _image4_hash_init_ptr = 0x%x" % (i4_hash_ptr_ea)) idc.set_name(i4_hash_ptr_ea, "_image4_hash_init_ptr", idc.SN_CHECK) bl_ea = ptr_ea_list[0].frm + 8 + 16 dst = idc.print_operand(bl_ea, 0) i4d_ea = idc.get_name_ea_simple(dst) print("\t[+] _Img4DecodePerformTrustEvaluation = 0x%x" % (i4d_ea)) idc.set_name(i4d_ea, "_Img4DecodePerformTrustEvaluation", idc.SN_CHECK) return ptr_ea print( "\t[-] _image4_validate_property_callback_interposer_ptr = not found") print("\t[-] _image4_hash_init_ptr = not found") print("\t[-] _Img4DecodePerformTrustEvaluation = not found") return ida_idaapi.BADADDR
def _patchCalls(self): def do_patch_call(va): retval = False stub_loc = idc.get_name_ea_simple(self._stubname(nm)) # Preserve original disassembly and format new comment old_target = idc.print_operand(va, 0) orig_cmt = idc.get_cmt(va, 0) or '' new_cmt = '%s\n\t%s' % (g_patched_call_cmt, idc.GetDisasm(va)) if idc.get_operand_type(va, 0) == ida_ua.o_mem: retval = patch_import(va, self._stubname(nm)) new_cmt += '\n%s %s to %s)' % (g_cmt_pointed, old_target, self._stubname(nm)) elif idc.get_operand_type(va, 0) == ida_ua.o_reg: va_imp = self._get_imp_for_register_call(va, nm) if va_imp: patch_pointer_width(va_imp, stub_loc) retval = True else: logger.warn('Could not find import to patch call at %s' % (phex(va))) else: # Usually optype 7 otherwise # Won't work if displacement exceeds 32-bit operand size call_offset_loc = va + idc.get_item_size(va) if abs(call_offset_loc - stub_loc) > 0x100000000: msg = ('Call site at %s too far from %s (%s)' % (phex(va), self._stubname(nm), phex(stub_loc))) raise CodeGraftingDisplacementError(msg) retval = patch_call(va, self._stubname(nm)) if retval: if orig_cmt: new_cmt += '\n%s' % (orig_cmt) idc.set_cmt(va, new_cmt, 0) ida_xref.add_cref(va, stub_loc, ida_xref.fl_CN) return retval for names in self._emu_stubs.keys(): for nm in names: va = idc.get_name_ea_simple(nm) mykutils.for_each_call_to(do_patch_call, va) for nm, aliases in g_allocators_aliases.items(): for alias in aliases: # do_patch_call closure will turn <nm> into stub_<nm> mykutils.for_each_call_to(do_patch_call, idc.get_name_ea_simple(alias))
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 traverse(name): _set = set() queue = list() processed = set() print("[+] Looking for %s" % (name), end="") wf_addr = idc.get_name_ea_simple(name) print(" found at: %08x" % (wf_addr)) queue.append(wf_addr) processed.add(wf_addr) while queue: # print("%d more in Q1" % len(queue)) wf_addr = queue.pop() # print("Popped %08x - %s" % (wf_addr, get_name(wf_addr))) for xref in idautils.XrefsTo(wf_addr, 1): if xref.iscode == 1: fn_entry = idc.first_func_chunk(xref.frm) fn_name = get_name(fn_entry) _set.add(fn_entry) if fn_entry not in entrypoints and fn_entry not in processed: queue.append(fn_entry) processed.add(fn_entry) # else: # print("Entrypoint detected as calling function") # print("%s : %08x(%s) -> %08x -> %08x" % # (fn_name, fn_entry, fn_entry, xref.frm, xref.to)) return _set
def getFormatString(addr): op_num = 1 # idc.get_operand_type Return value #define o_void 0 // No Operand ---------- #define o_reg 1 // General Register (al, ax, es, ds...) reg #define o_mem 2 // Direct Memory Reference (DATA) addr #define o_phrase 3 // Memory Ref [Base Reg + Index Reg] phrase #define o_displ 4 // Memory Reg [Base Reg + Index Reg + Displacement] phrase+addr #define o_imm 5 // Immediate Value value #define o_far 6 // Immediate Far Address (CODE) addr #define o_near 7 // Immediate Near Address (CODE) addr #define o_idpspec0 8 // IDP specific type #define o_idpspec1 9 // IDP specific type #define o_idpspec2 10 // IDP specific type #define o_idpspec3 11 // IDP specific type #define o_idpspec4 12 // IDP specific type #define o_idpspec5 13 // IDP specific type # 如果第二个不是立即数则下一个 if (idc.get_operand_type(addr, op_num) != 5): op_num = op_num + 1 if idc.get_operand_type(addr, op_num) != 5: return "get fail" op_string = print_operand( addr, op_num).split(" ")[0].split("+")[0].split("-")[0].replace("(", "") string_addr = idc.get_name_ea_simple(op_string) if string_addr == BADADDR: return "get fail" string = str(get_strlit_contents(string_addr, -1, STRTYPE_TERMCHR)) return [string_addr, string]
def lookup_objc_runtime_function(self, fname): ''' Find a matching function (address,name) tuple in self.target_objc_msgsend Sometimes this name can have a register prepended to it, as with 'cs:selRef_setObject_forKey_' ''' register_reg = re.compile('.*:') if register_reg.match(fname): fname = re.sub(register_reg, '', fname) function_ea = idc.get_name_ea_simple(fname) # fname is found if function_ea != idc.BADADDR: if self.debugflag: print "Looking for function %s" % fname # iterate over objc runtime functions for name_tuple in self.target_objc_msgsend: addr, name = name_tuple if fname == name: if self.debugflag: print "Found match: 0x%08x\t%s" % (addr, name) return name_tuple return None
def get_encrypted_lib_table(): LoadLibraryA_ea = idc.get_name_ea_simple("LoadLibraryA") LoadLibraryA_ref = None if LoadLibraryA_ea != idaapi.BADADDR: for ref in idautils.CodeRefsTo(LoadLibraryA_ea, 1): LoadLibraryA_ref = ref break ENCRYPTED_LIB_TABLE_instruction_ea = LoadLibraryA_ref - 22 API_TABLE_start_instruction_ea = LoadLibraryA_ref - 16 if 'lea' not in idc.GetDisasm( ENCRYPTED_LIB_TABLE_instruction_ea) or 'lea' not in idc.GetDisasm( API_TABLE_start_instruction_ea): print(hex(ENCRYPTED_LIB_TABLE_instruction_ea)) print('Parsing fails...') return ENCRYPTED_LIB_TABLE_ea = idc.get_operand_value( ENCRYPTED_LIB_TABLE_instruction_ea, 1) ENCRYPTED_LIB_TABLE_ea -= 4 global API_TABLE_start_ea API_TABLE_start_ea = idc.get_operand_value(API_TABLE_start_instruction_ea, 1) global ENCRYPTED_LIB_TABLE # 3694 bytes ENCRYPTED_LIB_TABLE = idaapi.get_bytes(ENCRYPTED_LIB_TABLE_ea, 3694)
def main(): #jayutils.configLogger(__name__, logging.DEBUG) jayutils.configLogger(__name__, logging.INFO) logger = jayutils.getLogger('') logger.debug('Starting up in main') #name = idc.AskStr('CreateThread', 'Enter function to find args for') #argNum = idc.AskLong(6) filePath = jayutils.getInputFilepath() if filePath is None: self.logger.info('No input file provided. Stopping') return vw = jayutils.loadWorkspace(filePath) logger.debug('Loaded workspace') tracker = ArgTracker(vw) import idautils funcEa = idc.get_name_ea_simple('CreateThread') if funcEa == idc.BADADDR: logger.info('CreateThread not found. Returning now') return for xref in idautils.XrefsTo(funcEa): argsList = tracker.getPushArgs(xref.frm, 6) for argDict in argsList: print '-' * 60 pc, value = argDict[3] print '0x%08x: 0x%08x: 0x%08x' % (xref.frm, pc, value)
def get_ea_from_highlight(): view = idaapi.get_current_viewer() thing = ida_kernwin.get_highlight(view) if thing and thing[1]: # we have a highligh, is it a valid name ? ea = idc.get_name_ea_simple(thing[0]) if ea != idaapi.BADADDR: return ea # get name at screen ea ea = idc.get_screen_ea() name = idc.get_name(ea, idaapi.GN_DEMANGLED) if name and thing[0] in name: return ea # Try to get full highlight name place = idaapi.get_custom_viewer_place(view, False) if place and len(place) == 3: # (plate_t, x, y) ea = place[0].toea() far_code_refs = [xref.to for xref in idautils.XrefsFrom(ea, ida_xref.XREF_FAR)] if far_code_refs: return far_code_refs[0] # First xref # Reach now, we do not have any valid name, return current screen ea return idc.get_screen_ea()
def MakeEnum(enumName, offsetArray): print("enum class %s\r\n{" % enumName) for offset in offsetArray: if len(offset[0]) == 0: print("") continue if type(offset[1]) is str: print(" %s = %s," % (offset[0], offset[1])) continue fncValue = offset[1] if offset[1] != -1 else 0x0 locByName = idc.get_name_ea_simple(offset[0]) isMismatch = locByName == 0x0 if locByName == BADADDR: locByName = fncValue if locByName > idaapi.get_imagebase(): set_name(locByName, offset[0]) locByName = locByName - idaapi.get_imagebase() print(" %s = %s,%s" % (offset[0], hex(locByName), '// Possible mismatch' if isMismatch else '')) print("};\r\n")
def _get_arm_ref_candidate(mask, op_val, op_str, all_refs): global _BAD_ARM_REF_OFF, _ARM_REF_CANDIDATES try: op_name = op_str.split("@")[0][ 1:] # `#asc_400E5C@PAGE` -> `asc_400E5C`. ref_ea = idc.get_name_ea_simple(op_name) if (ref_ea & mask) == op_val: return ref_ea, mask, 0 except: pass # NOTE(pag): We deal with candidates because it's possible that this # instruction will have multiple references. In the case of # `@PAGE`-based offsets, it's problematic when the wrong base # is matched, because it really throws off the C++ side of things # because the arrangement of the lifted data being on the same # page is not guaranteed. _ARM_REF_CANDIDATES.clear() for ref_ea in all_refs: if (ref_ea & mask) == op_val: _ARM_REF_CANDIDATES.add(ref_ea) return ref_ea, mask, 0 if len(_ARM_REF_CANDIDATES): for candidate_ea in _ARM_REF_CANDIDATES: if candidate_ea == op_val: return candidate_ea, mask, 0 return _ARM_REF_CANDIDATES.pop(), mask, 0 return _BAD_ARM_REF_OFF
def filter_for_data(name_list): filtered = [] for name in name_list: ea = idc.get_name_ea_simple(name) if idc.is_data(ea): filtered.append(name) return filtered
def getFuncAddr(func_name): func_addr = idc.get_name_ea_simple(func_name) if func_addr != BADADDR: print(printFunc(func_name)) # print func_name + " Addr : 0x %x" % func_addr return func_addr return False
def find_macho_load(base_ea): pz_ea = idc.get_name_ea_simple("aPagezero") if pz_ea != ida_idaapi.BADADDR: if len(list(idautils.XrefsTo(pz_ea))) != 3: print("\t[-] _macho_load = not found") return ida_idaapi.BADADDR # in iBoot versions newer than 6603.x _macho_load seems inlined, # so the following heuristic isn't applicable func1_ea = idaapi.get_func(list( idautils.XrefsTo(pz_ea))[0].frm).start_ea func2_ea = idaapi.get_func(list( idautils.XrefsTo(pz_ea))[1].frm).start_ea func3_ea = idaapi.get_func(list( idautils.XrefsTo(pz_ea))[2].frm).start_ea if func2_ea != func3_ea: print("\t[-] _macho_load = not found") return ida_idaapi.BADADDR if func1_ea != func2_ea: print("\t[+] _macho_load = 0x%x" % (func2_ea)) idc.set_name(func2_ea, "_macho_load", idc.SN_CHECK) return func2_ea print("\t[-] _macho_load = not found") return ida_idaapi.BADADDR
def find_target_early_init(base_ea): ea_list = ida_search.find_imm(base_ea, ida_search.SEARCH_DOWN, 0x4A41) if ea_list[0] != ida_idaapi.BADADDR: func_ea = ida_funcs.get_func(ea_list[0]).start_ea print("\t[+] _target_early_init = 0x%x" % (func_ea)) idc.set_name(func_ea, "_target_early_init", idc.SN_CHECK) tei_ea = func_ea str_ea = ida_search.find_text(tei_ea, 1, 1, "All pre", ida_search.SEARCH_DOWN) if str_ea != ida_idaapi.BADADDR: f_ea = idaapi.get_func(str_ea).start_ea if tei_ea != f_ea: print("\t[-] _platform_not_supported = not found") return tei_ea bl_ea = str_ea + 8 dst = idc.print_operand(bl_ea, 0) pns_ea = idc.get_name_ea_simple(dst) print("\t[+] _platform_not_supported = 0x%x" % (pns_ea)) idc.set_name(pns_ea, "_platform_not_supported", idc.SN_CHECK) return tei_ea print("\t[-] _target_early_init = not found") return ida_idaapi.BADADDR
def __init__(self, ea=UseCurrentAddress, name=None): if name is not None and ea != self.UseCurrentAddress: raise ValueError( ("Either supply a name or an address (ea). " "Not both. (ea={!r}, name={!r})").format(ea, name)) elif name is not None: ea = idc.get_name_ea_simple(name) if ea == idc.BADADDR: raise exceptions.SarkNoFunction( "The supplied name does not belong to an existing function. " "(name = {!r})".format(name)) elif ea == self.UseCurrentAddress: ea = idc.here() elif ea is None: raise ValueError( "`None` is not a valid address. To use the current screen ea, " "use `Function(ea=Function.UseCurrentAddress)` or supply no `ea`." ) elif isinstance(ea, Line): ea = ea.ea self._func = get_func(ea) self._comments = Comments(self)
def get_virtual_func_address(name, tinfo=None, offset=None): """ :param name: method name :param tinfo: class tinfo :param offset: virtual table offset :return: address of the method """ address = idc.get_name_ea_simple(name) if address != idaapi.BADADDR: return address address = demangled_names.get(name, idaapi.BADADDR) if address != idaapi.BADADDR: return address + idaapi.get_imagebase() if tinfo is None or offset is None: return offset *= 8 udt_member = idaapi.udt_member_t() while tinfo.is_struct(): address = demangled_names.get(tinfo.dstr() + '::' + name, idaapi.BADADDR) if address != idaapi.BADADDR: return address + idaapi.get_imagebase() udt_member.offset = offset tinfo.find_udt_member(idaapi.STRMEM_OFFSET, udt_member) tinfo = udt_member.type offset = offset - udt_member.offset
def is_name_exist(name): addr = idc.get_name_ea_simple(name) # if name already exists, we need to assign new name with suffix if addr != idc.BADADDR: return True else: return False
def resolve_functions(self): self.addr = { "verifyNative": idc.get_name_ea_simple("BaseExecMgr::verifyNative"), "setJit": idc.get_name_ea_simple("BaseExecMgr::setJit"), "setInterp": idc.get_name_ea_simple("BaseExecMgr::setInterp"), "setInterpRet": prev_head( idc.find_func_end(idc.get_name_ea_simple("BaseExecMgr::setInterp")), idc.get_name_ea_simple("BaseExecMgr::setInterp")), "getMethodName": idc.get_name_ea_simple("MethodInfo::getMethodName"), "verifyJit": idc.get_name_ea_simple("BaseExecMgr::verifyJit"), "writePrologue": idc.get_name_ea_simple("CodegenLIR::writePrologue"), "hasReachableExceptionsRet": prev_head( idc.find_func_end(idc.get_name_ea_simple("Verifier::hasReachableExceptions")), idc.get_name_ea_simple("Verifier::hasReachableExceptions")) }
def dbg_bpt(self, tid, ea): f_ea = idc.get_func_attr(ea, 0) if f_ea == idc.BADADDR: return 0 funcname = idc.get_name(f_ea) print("hit breakpoint in thread %x at %s %x" % (tid, funcname, ea)) if funcname == "": return 0 if not funcname in self.hooks: return 0 """ if not ea in self.hooks[funcname]["bp"]: return 0 """ for name in self.hooks[funcname]["buffer"]: ea_buffer = idc.get_name_ea_simple(name) data = get_bytes(ea_buffer, 0x1000) print("dumping %s" % name) print("%s" % ["%02x" % ord(b) for b in data[:0x40]]) timestamp = time.time() dumpfile = os.path.join(self.dumpdir, "%s_%s_%f" % (funcname, name, timestamp)) with open(dumpfile, "wb") as f: f.write(data) print("wrote buffer dump to %s" % dumpfile) idaapi.continue_process() return 0
def find_do_go(base_ea): str_ea = idc.get_name_ea_simple("aCebilefciladrm") if str_ea != ida_idaapi.BADADDR: for xref in idautils.XrefsTo(str_ea): # IDA messes up this function, so I find it this way: func = idaapi.get_func(xref.frm) dg_ea = 0 if func != none: dg_ea = ida_search.find_binary(xref.frm, func.start_ea, prologues[0], 16, ida_search.SEARCH_UP) if dg_ea == ida_idaapi.BADADDR: dg_ea = ida_search.find_binary(xref.frm, func.start_ea, "FF ?? ?? D1", 16, ida_search.SEARCH_UP) else: dg_ea = ida_search.find_binary(xref.frm, base_ea, "FF ?? ?? D1", 16, ida_search.SEARCH_UP) ida_funcs.add_func(dg_ea) print("\t[+] _do_go = 0x%x" % (dg_ea)) idc.set_name(dg_ea, "_do_go", idc.SN_CHECK) return dg_ea print("\t[-] _do_go = not found") return ida_idaapi.BADADDR
def Update(self): self._tag_list_model.clear() self._function_list_model.clear() self._tag_list_model.setHorizontalHeaderLabels( ["Tag", "Function", "Address"]) self._function_list_model.setHorizontalHeaderLabels( ["Function", "Address", "Tags"]) for tag_name in self._tag_manager.tagList(): tag = self._tag_manager.tagList()[tag_name] tag_item = QtGui.QStandardItem(tag_name) self._tag_list_model.appendRow([tag_item]) for function_name in tag: function_name_item = QtGui.QStandardItem(function_name) address = idc.get_name_ea_simple(function_name) address_item = QtGui.QStandardItem("0x%X" % address) tag_item.appendRow( [QtGui.QStandardItem(), function_name_item, address_item]) for function_name in self._tag_manager.functionList(): tag_list = self._tag_manager.functionList()[function_name] function_name_item = QtGui.QStandardItem(function_name) address_item = QtGui.QStandardItem( "0x%X" % idc.get_name_ea_simple(function_name)) tag_list_string = "" for tag in tag_list: tag_list_string = tag_list_string + " " + tag tag_list_item = QtGui.QStandardItem(tag_list_string) self._function_list_model.appendRow( [function_name_item, address_item, tag_list_item]) self._function_list_view.expandAll() self._tag_list_view.expandAll() for i in range(0, 2): self._function_list_view.resizeColumnToContents(i) self._tag_list_view.resizeColumnToContents(i)
def enable_bp_ret(funcname): func_ea = idc.get_name_ea_simple(funcname) bps = [] for ea in idautils.FuncItems(func_ea): if idc.GetMnem(ea) == "retn": idc.add_bpt(ea) bps.append(ea) return bps
def find_env_get_uint(ea): bl_ea = ea + 12 dst = idc.print_operand(bl_ea, 0) egu_ea = idc.get_name_ea_simple(dst) print("\t[+] _env_get_uint = 0x%x" % (egu_ea)) idc.set_name(egu_ea, "_env_get_uint", idc.SN_CHECK) return egu_ea
def t_NAME(t): r'[a-zA-Z_\.][a-zA-Z0-9_\.]*' temp = idc.get_name_ea_simple(t.value) if temp == idaapi.BADADDR: t.value = int(t.value, 16) else: t.value = temp return t
def parse_location(loc): try: loc = int(loc, 16) except ValueError: try: loc = idc.get_name_ea_simple(loc) except: return idaapi.BADADDR return loc
def update(self, name, tinfo): self.name = name self.tinfo = tinfo self.name_modified = False self.tinfo_modified = False self.base_address = idc.get_name_ea_simple(self.name) if self.base_address != idaapi.BADADDR: self.base_address -= idaapi.get_imagebase()
def __init__(self, addr=None, name=None): if addr is not None: self.__ea = addr if name is not None: self.name = name elif name: self.__ea = get_name_ea_simple(name) else: raise ValueError
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