def __init__(self, func): self.src = func ea = func.startEA self.ea = ea self.name = idaapi.get_func_name(ea) self.elts = [] if idaapi.is_func_tail(func): self.name += "_tail_" + str(ea) fr = idaapi.get_frame(func) struc_vars = [] if fr == None: self.frame = None else: self.frame = struct.frame_node(fr, func) struc_vars = self.frame.struct_vars while ea < func.endEA: if idaapi.isData(idaapi.getFlags(ea)): self.elts.append(data.data_node(ea, idaapi.next_not_tail(ea))) else: if ea == func.startEA and not (idaapi.is_func_tail(func)): self.elts.append(insn.insn_node(ea, struc_vars)) else: self.elts.append( names.name_wrap_insn(ea, insn.insn_node(ea, struc_vars))) ea = idaapi.next_head(ea, func.endEA)
def force_create_function(loc): """ Similar to create_function above, but a little more hackish (maybe). Makes a lot of assumptions about there being defined code, i.e. not obfsucated code. However, won't create a function that does not include the desired location, which will need to be fixed at a later date. :param loc: Location a function is needed at :return: True if function is created, False otherwise """ # Do a couple sanity checks. if idaapi.get_func(loc): append_debug('There\'s already a function here!') return False elif idc.isAlign(idc.GetFlags(loc)) or idc.GetMnem(loc) == 'nop' or \ (idaapi.isData(idc.GetFlags(loc)) and idc.Byte(loc) == 0x90): append_debug('Can\'t make a function out of aligns and/or nops!') return False start = _force_find_start(loc) end = _find_force_end(loc) if idc.MakeFunction(start, end): append_debug('Created a function 0x%X - 0x%X.' % (start, end)) return True else: append_debug('Failed to create a function 0x%X - 0x%X.' % (start, end)) return False
def __init__(self, func): self.src = func ea = func.startEA self.ea = ea self.name = idaapi.get_func_name(ea) self.elts = [] if idaapi.is_func_tail(func): self.name += "_tail_"+str(ea) fr = idaapi.get_frame(func) struc_vars = [] if fr == None: self.frame = None else: self.frame = struct.frame_node(fr, func) struc_vars = self.frame.struct_vars while ea < func.endEA: if idaapi.isData(idaapi.getFlags(ea)): self.elts.append(data.data_node(ea, idaapi.next_not_tail(ea))) else: if ea == func.startEA and not (idaapi.is_func_tail(func)): self.elts.append(insn.insn_node(ea, struc_vars)) else: self.elts.append(names.name_wrap_insn(ea, insn.insn_node(ea, struc_vars))) ea = idaapi.next_head(ea, func.endEA)
def create_function(location, find_start=True): ''' Description: Attempts to create a function using IDA's builtin functionality. If that fails build a assuming a start instruction of "push ebp", "push esp", "push esi", or "push edi" and an end instruction of "retn" (C2 or C3), excluding aligns and nops. Input: location - An address that should be within a function find_start - When False, assume location is the start of the function Output: True if it made a function, False otherwise. ''' # Do a couple sanity checks. if idaapi.get_func(location): append_debug('There\'s already a function here! (0x%X)' % location) return False elif idc.isAlign(idc.GetFlags(location)) or idc.GetMnem(location) == 'nop' or \ (idaapi.isData(idc.GetFlags(location)) and idc.Byte(location) == 0x90): append_debug('Can\'t make a function out of aligns and/or nops!') return False # Trace up as far as possible and have IDA do its thing. if ida_make_function(location): return True # Attempt to find the function ourselves. function_starts = _find_function_start(location) if find_start else [ location ] function_ends = _find_function_end(location) found_func = None if function_ends and function_starts: for function_start, function_end in itertools.product( function_starts, function_ends): if function_start < function_end: if idc.MakeFunction(function_start, function_end): append_debug('Created a function 0x%X - 0x%X.' % (function_start, function_end)) found_func = (function_start, function_end) break # Don't return here in case we have to split it yet. else: append_debug( 'Tried to create a function 0x%X - 0x%X, but IDA wouldn\'t do it.' % (function_start, function_end)) if found_func: split_funcs(*found_func) return True append_debug('Failed to find function based on location 0x%X.' % location) return False
def _check_is_jmp_wrapper(self, dis): # checks instructions like `jmp API` if dis.itype not in self._JMP_TYPES: return # handle call wrappers like jmp GetProcAddress if dis.Op1.type == idaapi.o_mem and dis.Op1.addr: # TODO: check is there better way to determine is the function a wrapper v = dis.Op1.addr if v and dis.itype == idaapi.NN_jmpni and idaapi.isData(idaapi.getFlags(v)) and self.__is_ptr_val(idaapi.getFlags(v)): v = self.__get_ptr_val(v) return v
def trim_func(ea, GetHead): """ Description: Steps until it hits something not a nop or not starts with 90 (nop opcode) nor an align or not byte 0xCC (Align 'opcode'). Input: ea - The location to adjust for nops and Aligns. EA must be a head. GetHead - either PrevHead or NextHead Output: The corrected EA. """ while idc.GetMnem(ea) == 'nop' or (idaapi.isData(idc.GetFlags(ea)) and idc.Byte(ea) == 0x90) or \ idc.isAlign(idc.GetFlags(ea)) or (not idc.isCode(idc.GetFlags(ea)) and idc.Byte(ea) == 0xCC): ea = GetHead(ea) return ea
def _un_nop(ea, HeadGetter): ''' Description: Steps until it hits something not a nop or not starts with 90 (nop opcode). Input: ea - The location to adjust for nops. EA must be a head. HeadGetter - either PrevHead or NextHead Output: The corrected EA. ''' while idc.GetMnem(ea) == 'nop' or (idaapi.isData(idc.GetFlags(ea)) and idc.Byte(ea) == 0x90): ea = HeadGetter(ea) return ea
def run(self, arg): idaapi.msg("[%s] Syncing with WS Server\n" % (self.wanted_name,)) self.addr = idaapi.get_screen_ea() if self.old_addr != self.addr: # check against idc.BADADDR and None before going if (self.addr is not None) and (self.addr != idc.BADADDR): # Code Address if idaapi.isCode(idaapi.getFlags(self.addr)): # don't set the address if it's already the qira_address if self.addr != self.qira_address: # debugging if DEBUG: idaapi.msg( "[%s] Qira Address 0x%x \n" % (self.wanted_name, self.addr,)) # Instruction Address self.set_qira_address(self.addr) self.update_address("iaddr", self.addr) # Data Address elif idaapi.isData(idaapi.getFlags(self.addr)): self.update_address("daddr", self.addr) # Tail Address elif idaapi.isTail(idaapi.getFlags(self.addr)): self.update_address("taddr", self.addr) # Unknown Address elif idaapi.isUnknown(idaapi.getFlags(self.addr)): self.update_address("uaddr", self.addr) # Head Address elif idaapi.isHead(idaapi.getFlags(self.addr)): self.update_address("haddr", self.addr) # Flow Address elif idaapi.isFlow(idaapi.getFlags(self.addr)): self.update_address("faddr", self.addr) # Var Address elif idaapi.isVar(idaapi.getFlags(self.addr)): self.update_address("vaddr", self.addr) # Data Address else: self.update_address("daddr", self.addr) self.old_addr = self.addr
def sanity_checks(location): """ Description: Do some basic checks to see if a function can be created containing the provided EA. Input: location - The EA to evaluate Output: True if a function can be created containing the provided EA False if a the provided EA was a nop or Align None if there is already a function containing the provided EA """ if idaapi.get_func(location): append_debug('There\'s already a function here! (0x%X)' % location) return None elif idc.isAlign(idc.GetFlags(location)) or idc.GetMnem(location) == 'nop' or \ (idaapi.isData(idc.GetFlags(location)) and idc.Byte(location) == 0x90): # Yes, the nop bit may be incorrect, but it's gonna be a very special case that needs a function with nops append_debug('Can\'t make a function including aligns and/or nops!') return False else: return True
def is_data(self): """Is the line data.""" return idaapi.isData(self.flags)
def is_data(self): """Is the location data.""" return idaapi.isData(self.flags)