def find_all_segments(self, segment_names): segments = {name: None for name in segment_names} for seg_va in Segments(): seg_name = get_segm_name(seg_va) if seg_name in segment_names: segments[seg_name] = (seg_va, get_segm_end(seg_va)) return segments
def main(): idaapi.auto_wait() base = idaapi.get_imagebase() tif = idaapi.tinfo_t() f = open(os.environ.get("DESTPATH", "functype_"), 'w') for ea in Segments(): # only code segment if idaapi.segtype(ea) != idaapi.SEG_CODE: continue for fva in Functions(get_segm_start(ea), get_segm_end(ea)): func_name = get_func_name(fva) has_type = idaapi.get_tinfo(tif, fva) or idaapi.guess_tinfo( tif, fva) if not has_type: continue info = serialize(tif) if info is None: continue print( hex(fva - base)[:-1], "|", func_name, "|", tif, "|", len(info['args'])) f.write("0x%x|%s|%s\n" % (fva - base, func_name, json.dumps(info))) f.close() idaapi.qexit(0)
def getlen(self): # Lazy version if hasattr(self, "_getlen"): return self._getlen max_addr = SegEnd(list(Segments())[-1] - (self.offset + self.shift)) self._getlen = max_addr return max_addr
def getlen(self): # Lazy version if hasattr(self, "_getlen"): return self._getlen max_addr = get_segm_end( list(Segments())[-1] - (self.offset - self.base_address)) self._getlen = max_addr return max_addr
def all_valid_ea(): """Return all valid EA as a Python generator.""" from idautils import Segments from idc import SegStart, SegEnd for s in Segments(): ea = SegStart(s) while ea < SegEnd(s): yield ea ea = idaapi.nextaddr(ea)
def update_guids(path_to_db, seg_types=None): _load_guids_db(path_to_db) if seg_types: def filter_expr(x): return getseg(x).type in seg_types else: filter_expr = None for seg_beg in filter(filter_expr, Segments()): seg_end = get_segm_end(seg_beg) _process_segment(seg_beg, seg_end)
def ptrs(self): for seg_beg in filter(lambda x: getseg(x).type == SEG_DATA, Segments()): seg_end = get_segm_end(seg_beg) head = seg_beg while True: head = next_head(head, seg_end) if head == BADADDR: break head_ptr = Pointer(head) if head_ptr.type.rstrip(" *") == self.name: yield head_ptr
def dump_symbol_info(output_filename): """Dump information for BAP's symbolizer into output_filename.""" from idautils import Segments, Functions from idc import ( SegStart, SegEnd, GetFunctionAttr, FUNCATTR_START, FUNCATTR_END ) try: from idaapi import get_func_name2 as get_func_name # Since get_func_name is deprecated (at least from IDA 6.9) except ImportError: from idaapi import get_func_name # Older versions of IDA don't have get_func_name2 # so we just use the older name get_func_name def func_name_propagate_thunk(ea): current_name = get_func_name(ea) if current_name[0].isalpha(): return current_name func = idaapi.get_func(ea) temp_ptr = idaapi.ea_pointer() ea_new = idaapi.BADADDR if func.flags & idaapi.FUNC_THUNK == idaapi.FUNC_THUNK: ea_new = idaapi.calc_thunk_func_target(func, temp_ptr.cast()) if ea_new != idaapi.BADADDR: ea = ea_new propagated_name = get_func_name(ea) or '' # Ensure it is not `None` if len(current_name) > len(propagated_name) > 0: return propagated_name else: return current_name # Fallback to non-propagated name for weird times that IDA gives # a 0 length name, or finds a longer import name idaapi.autoWait() with open(output_filename, 'w+') as out: for ea in Segments(): fs = Functions(SegStart(ea), SegEnd(ea)) for f in fs: out.write('("%s" 0x%x 0x%x)\n' % ( func_name_propagate_thunk(f), GetFunctionAttr(f, FUNCATTR_START), GetFunctionAttr(f, FUNCATTR_END)))
def set_text_segment_rwe(): """ Update name, class, permissions of CODE segment to resolve elimination of "dead" code. Also set compiler to VC++. """ for seg in Segments(): if get_segm_name(seg) == ".text": set_segm_name(seg, ".code") set_segm_class(seg, "DATA") set_segm_attr(seg, SEGATTR_PERM, 0b111) # RWE print("Updating segment at " + hex(seg) + ":\nsegment name .text -> .code" + "\nsegment class = DATA" + "\nsegment permissions = RWE") break set_compiler_id(1) # Visual C++
def dump_loader_info(output_filename): """Dump information for BAP's loader into output_filename.""" from idautils import Segments import idc idaapi.autoWait() with open(output_filename, 'w+') as out: info = idaapi.get_inf_structure() size = "r32" if info.is_32bit else "r64" out.write("(%s %s (" % (info.get_proc_name()[1], size)) for seg in Segments(): out.write("\n(%s %s %d (0x%X %d))" % ( idaapi.get_segm_name(seg), "code" if idaapi.segtype(seg) == idaapi.SEG_CODE else "data", idaapi.get_fileregion_offset(seg), seg, idaapi.getseg(seg).size())) out.write("))\n")
def update_structs_from_xrefs(track_members=True): """ Find xrefs to a struct pointer and change all the offsets to be struct offsets. This is useful for updating references to function pointers in EFI tables. For example: mov rax, cs:qword_whatever call qword ptr [rax+150h] Becomes: mov rax, cs:gBootServices call [rax+EFI_BOOT_SERVICES.UninstallMultipleProtocolInterfaces] """ for seg_beg in Segments(): seg_end = get_segm_end(seg_beg) head = next_head(seg_beg, seg_end) while head != BADADDR: head_ptr = Pointer(head) if is_structure_type(head_ptr.type.rstrip(" *")): print("Updating structures for xref: %s" % head_ptr) struc = Structure(head_ptr.type.rstrip(" *")) _update_from_ptr(head_ptr, struc, track_members) head = next_head(head, seg_end)
from idautils import Segments, Functions, XrefsTo from idc import GetFunctionName, SegName, get_type from sys import exit current_function = GetFunctionName(get_screen_ea()) print('Will generate forwards for all calls from {}'.format(current_function)) called_functions = [] function_name_to_address = {} for segea in Segments(): if SegName(segea) != '.text': continue for funcea in Functions(segea, SegEnd(segea)): called_functions.extend( filter(lambda x: GetFunctionName(x.frm) == current_function, XrefsTo(funcea))) function_name_to_address[GetFunctionName(funcea)] = funcea called_functions = map(lambda x: GetFunctionName(x.to), called_functions) called_functions = list(set(called_functions)) print('It calls {} functions!'.format(len(called_functions))) def forwarder_generator(prototype, address): until_arguments = prototype[:prototype.find('(')].split(' ') arguments = prototype[prototype.find('(') + 1:-1] pointer_levels = ''