def getFuncEALike(funcName): found = False for ea in Functions(): iterFuncName = GetFunctionName(ea) if iterFuncName.find(funcName) != -1: print('0x{:x}'.format(ea), iterFuncName) found = True if not found: print('not found')
def dump_tinfos(self, tmp_file): tinfo_map = {} ea = 0 num_tinfos = 0 while True: ea = NextFunction(ea) if ea == BADADDR: break fun = get_func(ea) fn_name = GetFunctionName(ea) tinfo, parsed_tinfo, fields = self.parse_tinfo(fun.startEA) if tinfo is None: continue reconstituted = self.unparse_tinfo(parsed_tinfo) if tinfo == reconstituted: tinfo_map[fn_name] = (parsed_tinfo, fields) num_tinfos += 1 else: print "f**k" ea = fun.startEA Jump(ea) print tinfo.encode("string_escape") print reconstituted.encode("string_escape") break self.send_message(tmp_file, tinfo_map) print "dumped %d tinfos" % num_tinfos
def GetFunctionDemangledName(xref_addr): """ Return the demanlged name of a function at a given address 'xref_addr'. """ tmp = GetFunctionName(xref_addr) name = Demangle(tmp, GetLongPrm(INF_SHORT_DN)) return name if name else tmp
def __init__(self, database, ea): """Initialize the object. :param Database database: Database that stores this function. :param int ea: Start address of the function. """ #: Database that stores this function self.database = database #: Start address of this function self.ea = ea #: Symbol of this function self.symbol = GetFunctionName(ea) #: Demangled name of this function self.demangled_name = GetFuncOffset(ea) #: All strings that are used in this function self.string_eas = set() self._strings = None #: All function addresses that call this function self.xref_to_eas = set(self._get_xref_to_calls(ea)) self._xrefs_to = None #: All function addresses that are called by this function self.xref_from_eas = set(self._get_xref_from_calls(ea)) self._xrefs_from = None #: Boolean that indicated if the function has been renamed self.renamed = False
def type_one_function(self, tinfo_map): fn_name = GetFunctionName(here()) if not fn_name: print "you're not in a function lol" return if fn_name not in tinfo_map: print "I don't know of this %s" % fn_name return tinfo, fields = tinfo_map[fn_name] fn_loc = LocByName(fn_name) current_tinfo_ = GetTinfo(fn_loc) packed = self.unparse_tinfo(tinfo) if current_tinfo_ is not None: current_tinfo, current_fields = current_tinfo_ if packed == current_tinfo and fields == current_fields: print "already the same" return ret = ApplyType(fn_loc, (packed, fields)) if ret: print "success: %#x %s" % (fn_loc, fn_name) open_pseudocode(fn_loc, False) else: print "failed :(" print fn_name print packed.encode("string_escape") print fields.encode("string_escape")
def _fill_functions(self): """Fill the ``functions`` dict.""" functions = self.functions for ea in Functions(): if GetFunctionName(ea).startswith('_ZThn'): continue functions[ea] = Function(self, ea)
def main(): bbsum = 0 for fva in idautils.Functions(): function = idaapi.get_func(fva) flowchart = idaapi.FlowChart(function) print("Function %s starting at 0x%x consists of %d basic blocks\n" % (GetFunctionName( function.startEA), function.startEA, flowchart.size)) bbsum += flowchart.size print("Total BB number is %d\n" % bbsum)
def __init__(self, frm_va, to_va, old_to_va): """Create a new ObjcMethodXref object Arguments: frm_va {number} -- Virtual address location of the reference to_va {[type]} -- Virtual address that is pointed to by the reference old_to_va {[type]} -- Virtual address that was pointed to by the reference prior to patching """ self.frm_va = frm_va self.to_va = to_va self.old_to_va = old_to_va self.method_name = GetFunctionName(self.to_va)
def __init__(self, method_va, segment_map): """Do not instantiate directly Arguments: method_va segment_map """ Message("Found method at virtual address: 0x%x\n" % method_va) self.method_va = method_va self.segment_map = segment_map self.name_pointer = Qword(method_va) self.method_type = Qword(method_va + self.OBJC_METHOD_TYPE_OFFSET) self.method_pointer_va = method_va + self.OBJC_METHOD_IMP_OFFSET self.method_pointer = Qword(self.method_pointer_va) self.patched_xrefs = [] objc_selrefs = segment_map["__objc_selrefs"] objc_msgrefs = segment_map["__objc_msgrefs"] objc_const = segment_map["__objc_const"] Message("Method name: %s\n" % GetFunctionName(self.method_pointer)) is_msg_ref, selector_ref, const_ref_count = self.get_xref( objc_selrefs, objc_msgrefs, objc_const) self.is_msg_ref = is_msg_ref self.const_ref_count = const_ref_count if not selector_ref: Message("No selref found.\n") self.selector_ref = None return if const_ref_count == 1: #We can only work with unambiguous situations where there is exactly one const reference #to the selector. self.selector_ref = selector_ref else: Message( "Selector ref count not exactly 1. Potentially ambiguous: %d" % const_ref_count) # Otherwise this same selector is used by more than one class. (Or none at all) self.selector_ref = None return self.sel_ref_va = self.selector_ref.frm if is_msg_ref: # adjust pointer to beginning of message ref struct to get xrefs self.sel_ref_va -= POINTER_SIZE Message("selref VA: 0x%X - function VA: 0x%X\n" % (self.sel_ref_va, self.method_pointer)) #Find all the references to this *selref* (note: not the string itself but the selref) #These should precede calls to the method #Patch the references to the selref with a reference to the method implementation self.walk_selector_refs()
def findPatchString(config): patchStringByteArray = [] for funcAddr in Functions(): if GetFunctionName(funcAddr) == config['srcFnName']: print('found ea for ' + config['name']) break for byteIndex in xrange(0, config['patchLength']): func_byte_char = GetManyBytes(funcAddr + config['offset'] + byteIndex, 1) if func_byte_char is not None: patchStringByteArray.append('{:02x}'.format(ord(func_byte_char))) PATCH_STRING = ' '.join(patchStringByteArray) print('patch found for ' + config['name'] + ' >> ' + PATCH_STRING) return PATCH_STRING
def renamed(self, ea, new_name, local_name): struct_id = GetStrucIdByName(GetConstName(ea)) is_struct = struct_id != 0xffffffffffffffff and struct_id != 0xffffffff if is_struct: Warning( "IDASynergy still does not support renaming of structs.\nBy renaming it, other collaborators will get this struct deleted and a new one added\nIf you want to avoid this, please rename it to its old name." ) return IDP_Hooks.renamed(self, ea, new_name, local_name) if Name(ea) != "" and GetFunctionName( ea) != "": # If renaming a function... self.data_io.apply_modification("functions", (ea, new_name)) return IDP_Hooks.renamed(self, ea, new_name, local_name)
def _get_xref_to_calls(ea): """Return a generator to iterate over all function addresses which call the given function. :param int ea: Start address of the function. """ for xref in XrefsTo(ea): if xref.type not in CALL_JUMP_FLAGS: continue if GetFunctionName(xref.to).startswith('_ZThn'): continue yield xref.to
def findFuncBinary(self, funcName, funcBinary): for funcAddr in Functions(): if GetFunctionName(funcAddr) == funcName: self.ea = funcAddr break if self.ea is None: return self self.endEa = GetFunctionAttr(self.ea, FUNCATTR_END) if len(funcBinary) > 0: self.ea = FindBinary(self.ea, SEARCH_DOWN | SEARCH_NOSHOW, funcBinary, 16) # print('{:x} {:x} {:x}'.format(self.ea, binaryEA, self.ea + binaryEA)) if self.ea > self.endEa: self.ea = None return self
def add_method_xref(self, xref): Message("Adding cross reference to method implementation for %s\n" % GetFunctionName(self.method_pointer)) add_dref(xref.frm, self.method_pointer, dr_I | XREF_USER) offset = self.method_pointer - xref.frm instruction_bytes = get_bytes(xref.frm, self.ARM64_INSTRUCTION_SIZE) #TODO: are there other instructions that could reference a method selector #and then move the selector reference into a register? arm64_ldr = AArch64LDRInstruction(instruction_bytes) arm64_ldr.patch_offset(offset) PatchDword(xref.frm, arm64_ldr.instruction_int) return ObjcMethodXref(xref.frm, self.method_pointer, xref.to)
def add_method_xref(self, xref): Message("Adding cross reference to method implementation for %s\n" % GetFunctionName(self.method_pointer)) #TODO: clean this up so it's more clear how we're parsing and patching the instruction #TODO: handle other potential instructions that could place a method selref into a register #TODO: sanity check what instruction we're actually working with before blindly deciding # it's a 7-byte mov instruction add_dref(xref.frm, self.method_pointer, dr_I | XREF_USER) #offset is a rip-relative offset that gets added to rip and dereferenced #when this instruction is executed, rip will be pointing to the next instruction #meaning it has been incremented by 7 (the length of the mov instruction) offset = self.method_pointer - xref.frm - self.X86_64_MOV_INSTRUCTION_SIZE #this replaces mov RSI, &selector with: # mov RSI, &method #xref.frm is the address of the mov instruction #+3 (4th byte of the instruction) #is where the RIP-relative operand is that #will get dereferenced as a pointer PatchDword(xref.frm + 3, offset) return ObjcMethodXref(xref.frm, self.method_pointer, xref.to)
def getFuncEA(funcName): for ea in Functions(): iterFuncName = GetFunctionName(ea) if iterFuncName == funcName: return ea print('{} not found'.format(funcName))
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 = ''
def GetFunctionDemangledName(xref_addr): tmp = GetFunctionName(xref_addr) name = Demangle(tmp, GetLongPrm(INF_SHORT_DN)) return name if name else tmp
__author__ = 'HuyNA' # # Reference Lister # # List all functions and all references to them in the current section. # # Implemented using direct IDA Plugin API calls # from idaapi import * # Get current ea ea = get_screen_ea() # Get segment class seg = getseg(ea) # Loop from segment start to end func = get_func(seg.startEA) while func is not None and func.startEA < seg.endEA: funcea = func.startEA print "Function %s at 0x%x" % (GetFunctionName(funcea), funcea) ref = get_first_cref_to(funcea) while ref != BADADDR: print " called from %s(0x%x)" % (get_func_name(ref), ref) ref = get_next_cref_to(funcea, ref) func = get_next_func(funcea)
def add_func(self, func): IDP_Hooks.add_func(self, func) self.data_io.apply_modification( "functions", (func.startEA, GetFunctionName(func.startEA))) return 0