def calls_to(self) -> Iterable[int]: """Iterates addresses that call this function.""" for ea in self.xrefs_to: insn = ida_ua.insn_t() ida_ua.decode_insn(insn, ea) if ida_idp.is_call_insn(insn): yield ea
def calls_from(self) -> Iterable[Tuple[int, int]]: """Iterates call address and callee address of the calls within this function.""" for ea in self.heads(): insn = ida_ua.insn_t() ida_ua.decode_insn(insn, ea) if ida_idp.is_call_insn(insn): for xref in idautils.XrefsFrom(ea, idaapi.XREF_FAR): func_ea = xref.to if func_ea: yield ea, func_ea
def Callees(ea): pfn = ida_funcs.get_func(ea) callees = [] if pfn: for item in pfn: F = ida_bytes.get_flags(item) if ida_bytes.is_code(F): insn = ida_ua.insn_t() if ida_ua.decode_insn(insn, item): if ida_idp.is_call_insn(insn): if insn.ops[0].type in [ida_ua.o_near, ida_ua.o_far]: callees.append(insn.ops[0].addr) return list(dict.fromkeys(callees))
def IsPrevInsnCall(ea): """ Given a return address, this function tries to check if previous instruction is a CALL instruction """ global CallPattern if ea == ida_idaapi.BADADDR or ea < 10: return None for delta, opcodes in CallPattern: # assume caller's ea caller = ea + delta # get the bytes bytes = [x for x in idautils.GetDataList(caller, len(opcodes), 1)] # do we have a match? is it a call instruction? if bytes == opcodes: insn = ida_ua.insn_t() if ida_ua.decode_insn(insn, caller) and ida_idp.is_call_insn(insn): return caller return None
def show_graph(): f = ida_funcs.get_func(here()) if not f: print("Must be in a function") return # Iterate through all function instructions and take only call instructions result = [] tmp = ida_ua.insn_t() for x in [x for x in FuncItems(f.start_ea) if (ida_ua.decode_insn(tmp, x) and ida_idp.is_call_insn(tmp))]: for xref in XrefsFrom(x, idaapi.XREF_FAR): if not xref.iscode: continue t = get_func_name(xref.to) if not t: t = hex(xref.to) result.append(t) g = MyGraph(ida_funcs.get_func_name(f.start_ea), result) if g.Show(): return g else: return None
if idc.GetMnem(addr) == "mov" and "eax" in idc.GetOpnd(addr, 0): #print("Found mov dword at %s" % idc.GetDisasm(addr)) return idc.GetOpnd(addr, 1) def get_function(offset): for i in range(len(LINES)): # Treat each line as a dword in length if (i * 4) - 4 == offset: function_name = LINES[i].split()[2] return function_name for ea in idautils.Heads(): if ida_idp.is_call_insn(ea): # Get disassembly at call address (ea) code = idc.GetDisasm(ea) split = code.split() if split[0] != 'call': continue if split[1] != 'dword': continue if split[2] != 'ptr': continue # Assuming eax is where the function pointer table is stored if 'eax+' not in split[3]: continue
def is_call_insn(self, address): insn = ida_ua.insn_t() if ida_ua.decode_insn(insn, address) and ida_idp.is_call_insn(insn): return True return False