def GetFuncItems(self, ea=None): result = [] for i in map(int, idautils.FuncItems(ea)): result.append(i) if result: pre = list(map(int, idautils.FuncItems(result[0] - 1))) post = list(map(int, idautils.FuncItems(result[-1] + 1))) result = pre + result + post return result
def getCurCallsAddr(self,funAddr): #参数为地址,获取当前函数所有调用的目标函数的地址以及调用指令的地址 #返回两个列表 li = [] #返回目标函数地址 li2 = [] #返回当前函数调用目标函数的代码地址 start = GetFunctionAttr(funAddr,FUNCATTR_START) if start == BADADDR: return li,li2 dism_addrs = list(idautils.FuncItems(start)) for addr in dism_addrs: insn = GetDisasm(addr) if 'call' in insn: ''' call eax, LoadLibrary, ds:GetProcAddr reg , near , o_mem , ''' name = GetOpnd(addr,0) #获取call 后面的字符串 OpType = GetOpType(addr,0) if OpType == o_reg: #回溯,查找对应寄存器的赋值,找函数的地址 #print '寄存器调用@ %X\n' % addr pass if OpType == o_near: nfunAddr = LocByName(name) if nfunAddr != BADADDR: li.append(nfunAddr) li2.append(addr) if OpType == o_mem: mfunAddr = GetOperandValue(addr,0) if mfunAddr != BADADDR: li.append(mfunAddr) li2.append(addr) return li,li2
def sequence3(out_path=config.path['outfolder']): FeatList = [] s = "" opcodelist_path = out_path + config.filename['opcodetmp'] # wait for IDA idaapi.autoWait() for func in idautils.Functions(): flags = idc.GetFunctionFlags(func) if flags & FUNC_LIB or flags & FUNC_THUNK: continue dism_addr = list(idautils.FuncItems(func)) for line in dism_addr: opcode = idc.GetMnem(line) s += str(opcode) + " " # 考虑到其他算法,这里不能去重 if opcode in s3_cutpoint: FeatList.append(s) s = "" # save the last sequence if s not in FeatList and s != "": FeatList.append(s) # write the sequences to the file f = open(opcodelist_path, 'w') f.write("\n".join(FeatList)) f.close() idc.Exit(0)
def get_ea(): while True: ea = yaunit.get_next_function() for eai in idautils.FuncItems(ea): flags = idaapi.get_flags_novalue(eai) if idaapi.isNum1(flags) and not idaapi.isEnum(flags, 1): return eai
def main(): for func in idautils.Functions(): #get function flags flags = idc.get_func_attr(func, FUNCATTR_FLAGS) # skip library & thunk functions if flags & FUNC_LIB or flags & FUNC_THUNK: continue dism_addr = list(idautils.FuncItems(func)) for ea in dism_addr: mnem = idc.print_insn_mnem(ea) if mnem == "call": highlight_insn(ea, CALL_COLOR) elif mnem == "rdtsc": highlight_insn(ea, ANITDEBUG_COLOR, "Possible Anti-Debugging") elif mnem == "xor": op1 = idc.print_operand(ea, 0) op2 = idc.print_operand(ea, 1) if op1 == op2: highlight_insn(ea, DEFAULT_COLOR, "{} = 0".format(op1)) else: highlight_insn(ea, XOR_COLOR, "Possible enc/dec") highlight_anti_debug()
def _get_api(sea): calls = 0 api = [] flags = idc.GetFunctionFlags(sea) # ignore library functions if flags & idc.FUNC_LIB or flags & idc.FUNC_THUNK: return calls, api # list of addresses addresses = list(idautils.FuncItems(sea)) for instr in addresses: tmp_api_address = "" if idaapi.is_call_insn(instr): for xref in idautils.XrefsFrom(instr, idaapi.XREF_FAR): if xref.to is None: calls += 1 continue tmp_api_address = xref.to break if tmp_api_address == "": calls += 1 continue api_flags = idc.GetFunctionFlags(tmp_api_address) if api_flags & idaapi.FUNC_LIB is True \ or api_flags & idaapi.FUNC_THUNK: tmp_api_name = idc.NameEx(0, tmp_api_address) if tmp_api_name: api.append(tmp_api_name) else: calls += 1 return calls, api
def getInsnCnt(ea): start = GetFunctionAttr(ea,FUNCATTR_START) if start == BADADDR: print '未能识别出当前的函数起始位置' return insn = list(idautils.FuncItems(start)) print "%s 函数有 %d 条指令\n" % (GetFunctionName(start),len(insn))
def main(self): for func in Functions(): if idc.SegName(func) == '__stubs': continue func_name = idc.GetFunctionName(func) print 'start parse ', func_name # if func_name != '-[JailbreakDetectionVC isJailbroken]': # continue self.cur_fun = func self.fun_start = idc.GetFunctionAttr(func, FUNCATTR_START) self.fun_end = idc.GetFunctionAttr(func, FUNCATTR_END) self.cur_fun_items = list(idautils.FuncItems(func)) regs = dict() regs['X0'] = self.getX0FromFuncName(func_name) regs['X1'] = 'Unknown' self._parse(regs, 0) self.conn.close()
def __init__(self, first_addr, string_addresses, imported_modules): self._first_addr = first_addr self._func_items = list(idautils.FuncItems(self._first_addr)) self._imported_modules = imported_modules self._string_addresses = string_addresses self._public_descriptions = [] self._public_desc_index = None self._num_of_pub_desc = 0 self._user_description = \ redb_client_descriptions.LocalDescription(self._first_addr) self._user_description.load_users() self._current_description = self._user_description # Get function attributes func_attr = redb_attributes.FuncAttributes(self._first_addr, self._func_items, self._string_addresses, self._imported_modules) self._primary_attributes = func_attr.get_primary_attrs() self._filtering_attributes = func_attr.get_filter_attrs() self._matching_grade_attributes = func_attr.get_mg_attrs() del func_attr gc.collect()
def _add_child_subs(self, root, ea, tid): if ea == 0 or root.text(4) == "y": return for x in idautils.FuncItems(ea): if idaapi.is_call_insn(x): fname, target_addr, is_api, callee_id = self._logged_call( x, tid) if self._valid_call(x, target_addr) and fname: current_root = QTreeWidgetItem(root, [ fname, hex(int(x)), "0", hex(int(target_addr)), "n", hex(int(is_api)), hex(int(tid)), hex(int(callee_id)) ]) current_root.setFlags(current_root.flags() & ~QtCore.Qt.ItemIsEditable) try: self._tags[get_api_tag(fname)].append( [root, current_root]) except KeyError: self._tags[get_api_tag(fname)] = [[root, current_root]] self._tags["All"].append(current_root) self._add_child_subs(current_root, target_addr, tid) root.setText(4, "y")
def run(self, arg): # 查找需要的函数 ea, ed = getSegAddr() search_result = [] for func in idautils.Functions(ea, ed): try: functionName = str(idaapi.ida_funcs.get_func_name(func)) demangled = idc.demangle_name(functionName, idc.get_inf_attr( idc.INF_SHORT_DN)) functionName = demangled if demangled else functionName if len(list(idautils.FuncItems(func))) > 10: # 如果是thumb模式,地址+1 arm_or_thumb = idc.get_sreg(func, "T") if arm_or_thumb: func += 1 search_result.append([hex(func), functionName]) except: pass so_path, so_name = getSoPathAndName() search_result = [f"{so_name}!{a}!{b}" for a, b in search_result] search_result = "\n".join(search_result) save_path = os.path.join(so_path, so_name.split(".")[0] + ".txt") with open(save_path, "w", encoding="utf-8")as F: F.write(search_result) print("使用方法如下:") print(f"frida-trace -UF -z {save_path}")
def InitRefList(self, start=None, end=None): self.func_ref_list = list() if start != idc.BADADDR: for item in idautils.FuncItems(start): # Check reference cross_refs = idautils.CodeRefsFrom(item, 1) temp_ref_list = list() # Convert from generator to list for ref in cross_refs: temp_ref_list.append(ref) # Collect ref_lists except temp_ref_list[0](next address) if len(temp_ref_list) >= 2: for i in range(1, len(temp_ref_list), 1): self.func_ref_list.append(temp_ref_list[i]) # Deduplication temp_ref_list = list(set(self.func_ref_list)) self.func_ref_list = list() self.func_ref_list.append(start) for ref in temp_ref_list: if ref >= start and ref < end: self.func_ref_list.append(ref) self.func_ref_list.sort()
def clear_colors(self): ea = idc.ScreenEA() for function_ea in idautils.Functions(idc.SegStart(ea), idc.SegEnd(ea)): for ins in idautils.FuncItems(function_ea): idc.SetColor(ins, idc.CIC_ITEM, 0xFFFFFFFF)
def _add_child(self, root, ea, tid, depth): if ea == 0 or root.text(4) == "y": return if depth > 30: logger = logging.getLogger(__name__) logger.info("Maximum recursion depth exceeded!") return for x in idautils.FuncItems(ea): if Maze().isCall(x, tid): fname, target, xrefID = Maze().getCallInfo(x, tid) if target: current_root = QTreeWidgetItem(root, [ fname, hex(int(x)), "0", hex(int(target)), "n", hex(int(0)), hex(int(tid)), hex(int(xrefID)) ]) current_root.setFlags(current_root.flags() & ~QtCore.Qt.ItemIsEditable) grp = get_api_tag(fname) if grp not in self._apiGrp: self._apiGrp[grp] = [] self._apiGrp[grp].append([root, current_root]) self._apiGrp["All"].append(current_root) self._add_child(current_root, target, tid, depth + 1) root.setText(4, "y")
def filter_package(potential_func,potential_func_list): recv_recall_chain = [] osintneting = 2 for p_func in potential_func : flag = False package_func = [] del recv_recall_chain[:] # 输入函数的父函数 get_caller(p_func, osintneting, package_func, recv_recall_chain) # package_func的子函数 for func in package_func: addr = get_name_ea(0, func.name) dism_addr = list(idautils.FuncItems(addr)) xref_froms = [] for ea in dism_addr: if ida_idp.is_call_insn(ea) is False: continue else: callee = get_first_fcref_from(ea) if callee != addr: xref_froms.append(hex(callee)) # 封装函数判断方法一:封装函数要求向下遍历只有对应函数 flag = judeg1(xref_froms, p_func, potential_func_list, func) # 封装函数判断方法二:封装函数和对应函数比较次数接近 if flag == False and len(xref_froms) != 0 : judge2(p_func,func, potential_func_list) print "----------" for i in potential_func_list: if i.is_packaged == True: print i.name, i.origi
def run(self, arg): # 查找需要的函数 ea, ed = getSegAddr() search_result = [] for func in idautils.Functions(ea, ed): try: functionName = str(idaapi.ida_funcs.get_func_name(func)) if len(list(idautils.FuncItems(func))) > 10: # 如果是thumb模式,地址+1 arm_or_thumb = idc.get_sreg(func, "T") if arm_or_thumb: func += 1 search_result.append(hex(func)) except: pass so_path, so_name = getSoPathAndName() search_result = [ f"-a '{so_name}!{offset}'" for offset in search_result ] search_result = " ".join(search_result) script_name = so_name.split(".")[0] + "_" + str(int( time.time())) + ".txt" save_path = os.path.join(so_path, script_name) with open(save_path, "w", encoding="utf-8") as F: F.write(search_result) print("使用方法如下:") print(f"frida-trace -UF -O {save_path}")
def colorize(): for seg in idautils.Segments(): heads = Heads(SegStart(seg), SegEnd(seg)) funcCalls = [] jumps = [] for i in heads: mnem = GetMnem(i) if mnem == "call": SetColor(i, CIC_ITEM, 0x00FFFF) if 'j' in mnem: SetColor(i, CIC_ITEM, 0xA9A9A9) for func in idautils.Functions(): flags = idc.GetFunctionFlags(func) #THUNK - function that call another function if (flags & FUNC_LIB) or (flags & FUNC_THUNK): continue #FuncItem - addresses of each instruction within function dism_addr = list(idautils.FuncItems(func)) for line in dism_addr: m = idc.GetMnem(line) if (m == 'call') or (m == 'jmp'): op = idc.GetOpType(line, 0) if (op == o_reg): #print "0x% x % s" % (line, idc.GetDisasm(line)) SetColor(line, CIC_ITEM, 0x00BFFF)
def get_func_symbols(ea): """ get all symbol/api calls from a function :param ea: offset within a function :return: return list of symbol/api """ offsets = [] dism_addr = list(idautils.FuncItems(ea)) for addr in dism_addr: if ida_idp.is_call_insn(addr): op_type = idc.get_operand_type(addr, 0) if op_type == 1: temp = idc.generate_disasm_line(addr, 0) # hack to extract api name if added as a comment to call register # sadly, idaapi.is_tilcmt isn't populated for api names if ";" in temp: temp_name = temp.split(";")[-1].strip() if idc.get_name_ea_simple( temp_name) and "@" not in temp_name: offsets.append((addr, temp_name)) else: continue elif op_type == 2: temp_name = Name(idc.get_operand_value(addr, 0)) if "@" not in temp_name: offsets.append((addr, temp_name)) else: op_addr = idc.get_operand_value(addr, 0) if is_lib(op_addr): temp_name = idc.get_func_name(op_addr) if "@" not in temp_name: offsets.append((addr, temp_name)) return offsets
def get_ref_funs(start_addr, platform): # print(start_addr) start_addr = GetFunctionAttr(start_addr, FUNCATTR_START) if start_addr == BADADDR: return {} ret = collections.OrderedDict() # 使用有序字典 # print("[+]Funstart@ %x" %start_addr) try: ret["%s %x" % (get_func_name(start_addr), start_addr)] = collections.OrderedDict() # print(ret) sub_tree = collections.OrderedDict() dism_addrs = list(idautils.FuncItems(start_addr)) # print(dism_addrs) for addr in dism_addrs: inst = GetDisasm(addr) if platform == "x86": keyword = "call" elif platform == "ARM": keyword = "BL" else: pass if keyword in inst: name = GetOpnd(addr, 0) #获取call 后面的字符串 sub_tree["%s %x" % (name, addr)] = name ret["%s %x" % (get_func_name(start_addr), start_addr)] = sub_tree except Exception as e: print("exception") print(e.message) return ret
def graph_down(ea, path=set()): """ Recursively collect all function calls. Copied with minor modifications from http://hooked-on-mnemonics.blogspot.com/2012/07/renaming-subroutine-blocks-and.html """ path.add(ea) # # extract all the call instructions from the current function # call_instructions = [] instruction_info = idaapi.insn_t() for address in idautils.FuncItems(ea): # decode the instruction if not idaapi.decode_insn(instruction_info, address): continue # check if this instruction is a call if not idaapi.is_call_insn(instruction_info): continue # save this address as a call instruction call_instructions.append(address) # # iterate through all the instructions in the target function (ea) and # inspect all the call instructions # for x in call_instructions: # TODO for r in idautils.XrefsFrom(x, idaapi.XREF_FAR): #print(0x%08X" % h, "--calls-->", "0x%08X" % r.to) if not r.iscode: continue # get the function pointed at by this call func = idaapi.get_func(r.to) if not func: continue # ignore calls to imports / library calls / thunks if (func.flags & (idaapi.FUNC_THUNK | idaapi.FUNC_LIB)) != 0: continue # # if we have not traversed to the destination function that this # call references, recurse down to it to continue our traversal # if r.to not in path: graph_down(r.to, path) return path
def Run(self): for function_ea in idautils.Functions(): for inst_ea in idautils.FuncItems(function_ea): if idaapi.isCode(idaapi.getFlags(inst_ea)): mnemonic = idc.GetMnem(inst_ea) if (mnemonic == 'rdmsr' or mnemonic == 'wrmsr'): msr_code = self.GetMsrCodeFromOperand(inst_ea) self.PrintMsrTable(msr_code, function_ea, inst_ea)
def data(self): h = self.keleven for ea in idautils.FuncItems(self.offset): h = self._cycle(h, idc.Byte(ea)) # go over all additional bytes of any instruction for i in range(ea + 1, ea + idc.ItemSize(ea)): h = self._cycle(h, idc.Byte(i)) return h
def get_succ(func_start): succ = set() for h in idautils.FuncItems(func_start): for r in idautils.XrefsFrom(h, 0): if r.type == fl_CF or r.type == fl_CN: #print hex(h), "-->", hex(r.to) succ.add(r.to) return succ
def CompileTextFromFunction(f,sep): s="" faddr = list(idautils.FuncItems(f)) for c in range(len(faddr)): for d in idautils.DataRefsFrom(faddr[c]): if idc.GetStringType(d) == 0 and idc.GetString(d): s += " "+ sep + " " + idc.GetString(d) return s
def find_operand_addr(self): while True: addr = yaunit.get_next_function() self.assertNotEqual(addr, idaapi.BADADDR) for ea in idautils.FuncItems(addr): flags = idaapi.get_flags_novalue(ea) if idaapi.isNum1(flags): return ea
def _data(cls, offset): md5 = hashlib.md5() for ea in idautils.FuncItems(offset): mnem_line = idc.GetMnem(ea) mnem_line = mnem_line.strip() mnem_line = mnem_line.lower() md5.update(mnem_line) return md5.hexdigest()
def function_lines(addresses, after=False): for address in addresses: for item in idautils.FuncItems(address): if not after: yield item else: if item > address: yield item
def _data(self): md5 = hashlib.md5() for offset in idautils.FuncItems(self.offset): mnem_line = idc.GetMnem(offset) mnem_line = mnem_line.strip() mnem_line = mnem_line.lower() md5.update(mnem_line) return md5.hexdigest()
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 CompileTextFromFunction(f,sep): s="" faddr = list(idautils.FuncItems(f)) for c in range(len(faddr)): for d in idautils.DataRefsFrom(faddr[c]): t = ida_nalt.get_str_type(d) if ((t==0) or (t==3)): s += " "+ sep + " " + idc.GetStrLitContents(d) return s