Ejemplo n.º 1
0
    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)
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
    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)
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
    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
Ejemplo n.º 6
0
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
Ejemplo n.º 7
0
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
Ejemplo n.º 8
0
    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
Ejemplo n.º 9
0
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
Ejemplo n.º 10
0
 def is_data(self):
     """Is the line data."""
     return idaapi.isData(self.flags)
Ejemplo n.º 11
0
 def is_data(self):
     """Is the location data."""
     return idaapi.isData(self.flags)
Ejemplo n.º 12
0
 def is_data(self):
     """Is the line data."""
     return idaapi.isData(self.flags)