def processAllSegments(self): for seg in idautils.Segments(): segStart = idc.SegStart(seg) segEnd = idc.SegEnd(seg) if self.params.searchPushArgs: self.lookForOpArgs(segStart, segEnd) if self.params.searchDwordArray: self.lookForDwordArray(segStart, segEnd)
def has_segment_type(ea, expected_seg_type): """Returns true if the segment containing `ea` has the type `seg_type`.""" seg = idc.SegStart(ea) if seg == idc.BADADDR: return False seg_type = idc.GetSegmentAttr(seg, idc.SEGATTR_TYPE) return seg_type == expected_seg_type
def main(): for ea in idautils.Segments(): if idc.SegName(ea) == ".text": start = idc.SegStart(ea) end = idc.SegEnd(ea) print '.text %x-%x' % (start, end) add_xrefs(start, end) return 1
def recover_frame_entries(seg_ea): if seg_ea == idc.BADADDR: return DEBUG("Recover entries from section : {}".format(idc.SegName(seg_ea))) ea = idc.SegStart(seg_ea) end_ea = idc.SegEnd(seg_ea) while ea != idc.BADADDR and ea < end_ea: ea = format_entries(ea)
def GetROSections(): seg_addrs_readonly = [] for seg in idautils.Segments(): seg_start_ea = idc.SegStart(seg) seg_end_ea = idc.SegEnd(seg) flags = idc.GetSegmentAttr(seg, idc.SEGATTR_PERM) if flags & 6: # Flags 4 means read-only seg_addrs_readonly.append([seg_start_ea, seg_end_ea]) return seg_addrs_readonly
def recordText(self): for seg_ea in idautils.Segments(): print('seg: %s' % idc.SegName(seg_ea)) if idc.SegName(seg_ea) == '.text': start = idc.SegStart(seg_ea) end = idc.SegEnd(seg_ea) print('text at 0x%x - 0x%x' % (start, end)) gdbProt.Evalx('SendGDBMonitor("@cgc.recordText(0x%x, 0x%x)");' % (start, end)) break
def processDataSegments(M, new_eas): for n in xrange(idaapi.get_segm_qty()): seg = idaapi.getnseg(n) ea = seg.startEA segtype = idc.GetSegmentAttr(ea, idc.SEGATTR_TYPE) if segtype in [idc.SEG_DATA, idc.SEG_BSS]: start = idc.SegStart(ea) end = idc.SegEnd(ea) addDataSegment(M, start, end, new_eas)
def get_functions(): ''' enumerate the functions in the currently loaded module. Yields: int: address of the function. ''' startea = idc.BeginEA() for fva in idautils.Functions(idc.SegStart(startea), idc.SegEnd(startea)): yield fva
def get_list_of_functions(self): '''Get all functions list.''' seg_ea = idc.BeginEA() functions_list = {} for func_ea in idautils.Functions(idc.SegStart(seg_ea), idc.SegEnd(seg_ea)): function_name = self.maybe_demangle(idc.GetFunctionName(func_ea)) functions_list[function_name] = func_ea return functions_list
def analyse_subroutines(): """Goes through all the subroutines that IDA's initial auto analysis discovers.""" log.info("Analysing subroutines") exported_eas = find_exported_eas() log.info("IDA identified {} exported functions".format(len(exported_eas))) subs = set() sub_eas = set() # Work list. sub_eas.update(exported_eas) # Get all subroutines that IDA recognised. for seg_ea in idautils.Segments(): min_ea, max_ea = idc.SegStart(seg_ea), idc.SegEnd(seg_ea) sub_eas.update(idautils.Functions(min_ea, max_ea)) log.info("IDA identified {} functions".format(len(sub_eas))) bad_sub_eas = set() for sub_ea in sub_eas: if has_segment_type(sub_ea, idc.SEG_CODE): sub = program.get_subroutine(sub_ea) # Mark `ea` as a subroutine. # Iteratively analyse the blocks in subroutines. This may discover new # subroutines because our block analysis can be more aggressive than what # IDA finds. while len(sub_eas): sub_ea = sub_eas.pop() if not has_segment_type(sub_ea, idc.SEG_CODE): log.warning( "Not analysing subroutine at non-code address {:08x}".format( sub_ea)) continue sub = program.get_subroutine(sub_ea) if sub in subs: log.debug("Skipping {:08x}; already analysed.".format(sub_ea)) continue subs.add(sub) if idc.hasName(sub_ea): sub.name = idc.GetFunctionName(sub_ea) # Mark this subroutine as exported. if sub_ea in exported_eas: sub.visibility = program.Subroutine.VISIBILITY_EXPORTED analyse_subroutine(sub) sub_eas.update(get_called_subroutines(sub)) return subs
def load_symbols_from_ida(self): for ea, name in idautils.Names(): flag = idc.GetFlags(ea) if not idc.hasUserName(flag): continue seg_ea = idc.SegStart(ea) seg_name = idc.SegName(ea) if seg_name not in self.sections: continue sym_type = 'function' if idc.isCode(flag) else 'object' self.symbols[name] = (seg_name, ea - seg_ea, sym_type)
def update_mapping(self): pass self.fun_mapping = { idc.GetFunctionName(x): (idaapi.get_func(x).startEA, idaapi.get_func(x).endEA - 1) for x in idautils.Functions() } self.seg_mapping = { idc.SegName(x): (idc.SegStart(x), idc.SegEnd(x)) for x in idautils.Segments() }
def is_external_segment_by_flags(ea): try: seg_ea = idc.SegStart(ea) seg_type = idc.GetSegmentAttr(seg_ea, idc.SEGATTR_TYPE) if seg_type == idc.SEG_XTRN: _EXTERNAL_SEGMENTS.add(seg_ea) return True else: return False except: return False
def promptForRange(self): #check if a range has already been selected - if so skip prompt start = idc.SelStart() if start != idc.BADADDR: self.logger.info('Processing range 0x%08x - 0x%08x', self.params.startAddr, self.params.endAddr) self.params.startAddr = start self.params.endAddr = idc.SelEnd() else: self.logger.info('Processing current segment only') self.params.startAddr = idc.SegStart(idc.here()) self.params.endAddr = idc.SegEnd(idc.here())
def get_sections(): """Get section names and start/end addrs from IDA database """ sections = {} for ea in idautils.Segments(): curr = {} curr["start"] = idc.SegStart(ea) curr["end"] = idc.SegEnd(ea) sections[idc.SegName(ea)] = curr return sections
def is_invalid_ea(ea): """Returns `True` if `ea` is not valid, i.e. it doesn't point into any valid segment.""" if idc.BADADDR == ea: return True try: idc.GetSegmentAttr(idc.SegStart(ea), idc.SEGATTR_TYPE) return False # If we get here, then it must be a valid ea! except: return True
def is_external_segment_by_flags(ea): """Returns `True` if IDA believes that `ea` belongs to an external segment.""" try: seg_ea = idc.SegStart(ea) seg_type = idc.GetSegmentAttr(seg_ea, idc.SEGATTR_TYPE) if seg_type == idc.SEG_XTRN: _EXTERNAL_SEGMENTS.add(seg_ea) return True else: return False except: return False
def processCode(self): if (self.params.startAddr==idc.BADADDR) and (self.params.endAddr==idc.BADADDR): self.logger.info('Processing current segment only') #self.processAllSegments() self.params.startAddr = idc.SegStart(idc.here()) self.params.endAddr = idc.SegEnd(idc.here()) else: self.logger.info('Processing range 0x%08x - 0x%08x', self.params.startAddr, self.params.endAddr) if self.params.searchDwordArray: self.lookForDwordArray(self.params.startAddr, self.params.endAddr) if self.params.searchPushArgs: self.lookForOpArgs(self.params.startAddr, self.params.endAddr)
def getSegsInfo(): ''' Returns a list of all segments in the form: (name, segstart, segend) ''' segments = list(idautils.Segments()) res = [] for s in segments: res.append((idc.SegName(s), idc.SegStart(s), idc.SegEnd(s))) return res
def isExternalReference(ea): # see if this is in an internal or external code ref ext_types = [idc.SEG_XTRN] seg = idc.SegStart(ea) if seg == idc.BADADDR: raise Exception("Could not get segment addr for: {0:x}\n".format(ea)) segtype = idc.GetSegmentAttr(seg, idc.SEGATTR_TYPE) if segtype in ext_types: return True return False
def get_instruction_dictionary(ea): insts = dict() for func in idautils.Functions(idc.SegStart(ea), idc.SegEnd(ea)): f_end = FindFuncEnd(func) for head in Heads(func, f_end): if not isCode(GetFlags(head)): continue mnem = GetMnem(head) if mnem not in insts: insts[mnem] = list() insts[mnem].append(head) return insts
def analyse_data(pointer_size): """Go through the data sections and look for possible tables of code pointers.""" log.info("Analysing the data section for simple code refs") for seg_ea in idautils.Segments(): seg_type = idc.GetSegmentAttr(seg_ea, idc.SEGATTR_TYPE) if seg_type != idc.SEG_DATA: continue min_ea, max_ea = idc.SegStart(seg_ea), idc.SegEnd(seg_ea) if 8 == pointer_size: scan_data_for_code_refs(min_ea, max_ea, idc.Qword, 8) scan_data_for_code_refs(min_ea, max_ea, idc.Dword, 4)
def iter_lines(): """ Iterate through all line addresses in the IDB Yields addresses of all lines. """ for ea in idautils.Segments(): seg_start = idc.SegStart(ea) seg_end = idc.SegEnd(ea) cur_addr = seg_start while (cur_addr < seg_end) and (cur_addr != idaapi.BADADDR): yield cur_addr cur_addr = idc.NextHead(cur_addr)
def processAllSegments(self): for seg in idautils.Segments(): if using_ida7api: segStart = idc.get_segm_start(seg) segEnd = idc.get_segm_end(seg) else: segStart = idc.SegStart(seg) segEnd = idc.SegEnd(seg) if self.params.searchPushArgs: self.lookForOpArgs(segStart, segEnd) if self.params.searchDwordArray: self.lookForDwordArray(segStart, segEnd)
def querySignatures(): path = idaapi.get_input_file_path() print('path is %s' % path) parts = path.split('/') index = 0 cndex = 0 sig_dir = '/tmp' if 'CBs' in parts: for p in parts: if p == 'CBs': cindex = index + 1 break else: index += 1 common = path.split('/')[5] + "_01" common = parts[cindex] + "_01" rcb_file = os.path.join(sig_dir, common) + ".json" elif '_MG' in path: rcb = os.path.basename(path) parts = rcb.split('_') rebuild = parts[0] + '_' + parts[1] + '_' + parts[3] rcb_file = os.path.join(sig_dir, rebuild) + ".json" else: rcb = os.path.basename(path) csid = rcb.split('-')[1] look_for = sig_dir + '/*%s*.json' % csid flist = glob.glob(look_for) if len(flist) == 0: print('no json found for %s' % look_for) sys.exit(1) for f in flist: print(f) rcb_file = f if f.startswith('CB'): break print('found json of %s' % rcb_file) with open(rcb_file) as fh: print('got blocks from %s' % rcb_file) base_json = json.load(fh) ea = idc.get_screen_ea() #print('find match for 0x%x' % ea) #findMatch(base_json, idc.get_screen_ea()) seg_start = idc.SegStart(ea) seg_end = idc.SegEnd(ea) print('%d functions in base' % len(base_json)) print('seg_start/end %x %x' % (seg_start, seg_end)) for function_ea in idautils.Functions(seg_start, seg_end): print('try %x' % function_ea) findMatch(base_json, function_ea)
def get_boot_services(self): """ found boot services in idb """ code = list(idautils.Functions())[0] start = idc.SegStart(code) end = idc.SegEnd(code) for ea in range(start, end): for service_name in self.BOOT_SERVICES_OFFSET: if (idc.GetMnem(ea) == "call" and \ idc.get_operand_value(ea, 0) == self.BOOT_SERVICES_OFFSET[service_name] ): if self.gBServices[service_name].count(ea) == 0: self.gBServices[service_name].append(ea)
def _get_segments(self, attr): segments = [] start = idc.BADADDR end = idc.BADADDR seg = idc.FirstSeg() while seg != idc.BADADDR: if idc.GetSegmentAttr(seg, idc.SEGATTR_TYPE) == attr: start = idc.SegStart(seg) end = idc.SegEnd(seg) segments.append((start, end)) seg = idc.NextSeg(seg) return segments
def isExternalReference(ea): # see if this is in an internal or external code ref DEBUG("Testing {0:x} for externality\n".format(ea)) ext_types = [idc.SEG_XTRN] seg = idc.SegStart(ea) if seg == idc.BADADDR: DEBUG("WARNING: Could not get segment addr for: {0:x}\n".format(ea)) return False segtype = idc.GetSegmentAttr(seg, idc.SEGATTR_TYPE) if segtype in ext_types: return True return False
def ida_indirect_bfcs(): bfcs = [] for seg in idautils.Segments(): for head in idautils.Heads(idc.SegStart(seg), idc.SegEnd(seg)): if idc.isCode(idc.GetFlags(head)): ins = idautils.DecodeInstruction(head) if ins is not None: if ins.get_canon_feature() & idaapi.CF_JUMP: if ins.itype in ida_dynamic_jump_types or \ ins.itype in ida_dynamic_call_types or \ ins.itype in ida_dynamic_ret_types: if ins.ea not in bfcs: bfcs.append(ins.ea) return bfcs
def find_vftable_gcc(seg): seg_start = idc.SegStart(seg) seg_end = idc.SegEnd(seg) cur_addr = seg symbol = "" last_add_addr = 0 while cur_addr <= seg_end - 8: #32 is 4 data = idc.Qword(cur_addr) #32 is Dword hasRtti = 0 # 寻找他的rtti,第一项有交叉引用,第二项在rodata段,为类名 rttiptr = idc.Qword(cur_addr) if (rodata_start <= rttiptr < rodata_end) or ( (hasdrr == 1) and (drrdata_start <= rttiptr < drrdata_end)): rttixrefs = list(idautils.XrefsTo(rttiptr)) if len(rttixrefs) != 0: nameptr = idc.Qword(rttiptr + 8) if rodata_start <= nameptr < rodata_end: hasRtti = 1 # rttiptr上一项<=0,下一项为虚函数或者为0 if (struct.unpack( 'q', struct.pack('Q', idc.Qword(cur_addr - 8)))[0] <= 0) and ((text_start <= idc.Qword(cur_addr + 8) < text_end) or (idc.Qword(cur_addr + 8) == 0)): rtti_addr = idc.Qword(cur_addr) if rtti_addr not in rtti_list: symbol = idc.GetOpnd(cur_addr, 0) symbol = re.sub(r'^offset ', '', symbol) class_list[symbol] = dict() class_list[symbol]["addr"] = rtti_addr class_list[symbol]["base"] = list() class_list[symbol]["function_list"] = list() rtti_list.append(rtti_addr) # 若找到rttiptr,添加的函数为0(只有前两项),函数在代码段上,函数在extern段中 if len(symbol) != 0: if ((data == 0) and (len(class_list[symbol]["function_list"]) < 2)) or ( text_start <= data < text_end) or (extern_start <= data < extern_end): class_list[symbol]["function_list"].append( hex(data).strip("L")) else: symbol == "" cur_addr += 8