def _convert_address_to_function(func):
    """Convert an address that IDA has classified incorrectly into a proper function."""
    # If everything goes wrong, we'll try to restore this function.
    orig = idc.FirstFuncFchunk(func)
    # If the address is not code, let's undefine whatever it is.
    if not idc.isCode(idc.GetFlags(func)):
        if not is_mapped(func):
            # Well, that's awkward.
            return False
        item = idc.ItemHead(func)
        itemend = idc.ItemEnd(func)
        if item != idc.BADADDR:
            _log(1, 'Undefining item {:#x} - {:#x}', item, itemend)
            idc.MakeUnkn(item, idc.DOUNK_EXPAND)
            idc.MakeCode(func)
            # Give IDA a chance to analyze the new code or else we won't be able to create a
            # function.
            idc.Wait()
            idc.AnalyseArea(item, itemend)
    else:
        # Just try removing the chunk from its current function. IDA can add it to another function
        # automatically, so make sure it's removed from all functions by doing it in loop until it
        # fails.
        for i in range(1024):
            if not idc.RemoveFchunk(func, func):
                break
    # Now try making a function.
    if idc.MakeFunction(func) != 0:
        return True
    # This is a stubborn chunk. Try recording the list of chunks, deleting the original function,
    # creating the new function, then re-creating the original function.
    if orig != idc.BADADDR:
        chunks = list(idautils.Chunks(orig))
        if idc.DelFunction(orig) != 0:
            # Ok, now let's create the new function, and recreate the original.
            if idc.MakeFunction(func) != 0:
                if idc.MakeFunction(orig) != 0:
                    # Ok, so we created the functions! Now, if any of the original chunks are not
                    # contained in a function, we'll abort and undo.
                    if all(idaapi.get_func(start) for start, end in chunks):
                        return True
            # Try to undo the damage.
            for start, _ in chunks:
                idc.DelFunction(start)
    # Everything we've tried so far has failed. If there was originally a function, try to restore
    # it.
    if orig != idc.BADADDR:
        _log(0, 'Trying to restore original function {:#x}', orig)
        idc.MakeFunction(orig)
    return False
Exemple #2
0
def ida_make_function(location):
    '''
    Description:
        From the first non-function byte, attempt to make a function.

    Input:
        location - The EA at which IDA should attempt to make a function.

    Output:
        True if it succeeded, False otherwise.
    '''
    function_start = location
    ea = location
    while not (idaapi.get_func(ea) or idc.isAlign(idc.GetFlags(ea))):
        function_start = ea
        ea = idc.PrevHead(ea)
    function_start = _un_nop(function_start, idc.NextHead)

    if idc.MakeFunction(function_start):
        last_mnem = idc.GetMnem(
            idc.ItemHead(idaapi.get_func(function_start).endEA - 1))
        if 'ret' not in last_mnem and 'jmp' not in last_mnem:
            idc.DelFunction(function_start)
            append_debug(
                'Created a function at 0x%X, but there wasn\'t a jmp or ret at the end.'
                % function_start)
            return False
        else:
            append_debug('Created a function 0x%X.' % function_start)
            return True
    else:
        return False
Exemple #3
0
    def OnDeleteLine(self, n):
        ans = idaapi.askyn_c(
            1,
            "HIDECANCEL\nAre you sure you want to delete function [%s] @ [%s]?"
            % (self.items[n][3], self.items[n][4]))
        if ans == 1:
            asms = Assembler.LoadSavedAssemblers()
            item = int(self.items[n][2], 16)
            if asms != None and len(asms.keys()) > 0:
                for asm in asms.itervalues():
                    if asm.functions.has_key(item):
                        print "Removed [%08x]!" % item
                        del asm.functions[item]
                        asm.SaveState()

            opty_ea = int(self.items[n][4], 16)
            print "set_name[%08x]" % opty_ea
            idc.MakeComm(opty_ea, "")
            idaapi.set_name(opty_ea, "")
            idc.DelFunction(opty_ea)

            comment = idc.Comment(item)
            comment = re.sub(r"(?i)OPTY@\[[\d+abcdef]+\];\s*", "", comment)
            idc.MakeComm(item, comment)

        self.populate_items()
        return n
Exemple #4
0
def try_make_function(function_start, function_end=idc.BADADDR, target_location=None, require_term=True,
                      end_mnem_bytes=None):
    """
    Description:
        Given a function location, attempt to create a function.
        If function creation fails, delete any partially created functions.
        If function creation succeeds, ensure all of the function's bytes are analyzed as code.

    Input:
        function_start - The startEA of the function to create
        function_end - The endEA of the function to create. IDA will calculate if not provided.
        target_location - If provided, fail function creation if it does not include this EA
        require_term - If provided, fail function creation if the last instruction is not a ret or jmp
        end_mnem_bytes - If provided, fail function creation if the last instruction is not the provided bytes
                         Instructions are entered as space separated bytes (i.e. '55' for 'push ebp')

    Output:
        Returns a tuple (function_start, function_end) for the created function if successful, None otherwise
    """
    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))
            if require_term:
                last_mnem_ea = idc.ItemHead(idaapi.get_func(function_start).endEA - 1)
                last_mnem = idc.GetMnem(last_mnem_ea)
                if (end_mnem_bytes is None and 'ret' not in last_mnem and 'jmp' not in last_mnem) or \
                        (end_mnem_bytes and idaapi.get_many_bytes(last_mnem_ea, idc.ItemSize(last_mnem_ea)).encode('hex').upper() != end_mnem_bytes.upper()):
                    idc.DelFunction(function_start)
                    append_debug(
                        'Deleted function at 0x%X - the function didn\'t end with the correct mnem/bytes.' % function_start)
                    return
            if target_location is not None:
                if function_start <= target_location < idaapi.get_func(function_start).endEA:
                    idc.AnalyzeArea(function_start, idaapi.get_func(function_start).endEA)
                    return function_start, function_end
                else:
                    idc.DelFunction(function_start)
                    append_debug(
                        'Deleted function at 0x%X - the function didn\'t contain the target location.' % function_start)
                    return
        else:
            append_debug(
                'Tried to create a function 0x%X - 0x%X, but IDA wouldn\'t do it.' % (function_start, function_end))
    else:
        append_debug('The end address was not greater than the start address!')
Exemple #5
0
def split_funcs(startEA, endEA):
    '''
    Description:
        Attempt to split the function we created into a bunch of smaller functions based on
        aligns we find in the middle of the func. If we do successfully split, recurse on
        the remainder of the original function.

    Input:
        startEA - The beginning of the function
        endEA - The end of the function

    Output:
        The IDB is updated with the resulting functions
    '''
    ea = startEA
    while ea < endEA:
        # We found an align so delete the function and try to make 2 new ones in its place.
        if idaapi.isAlign(idc.GetFlags(ea)) and idc.DelFunction(startEA):
            # Make the first function.
            if idc.MakeFunction(startEA, _un_nop(ea, idc.NextHead)):
                # We found an align, now get past them.
                while idaapi.isAlign(idc.GetFlags(ea)):
                    ea += idc.ItemSize(ea)

                # Make the second function and recurse to ensure it doesn't need split too.
                if idc.MakeFunction(_un_nop(ea, idc.PrevHead), endEA):
                    append_debug('Split 0x%X - 0x%X at 0x%X.' %
                                 (startEA, endEA, ea))
                    split_funcs(ea, endEA)
                    return
                else:  # We failed to make the second function, so delete the first.
                    idc.DelFunction(startEA)

            # Splitting failed - rebuild the original function.
            idc.MakeFunction(startEA, endEA)
            append_debug('Almost split 0x%X - 0x%X at 0x%X.' %
                         (startEA, endEA, ea))

        ea += idc.ItemSize(ea)
Exemple #6
0
    def make_code(self, object_version, address):
        # delete function if previously defined
        idc.DelFunction(address)

        # make code if not already exist
        idc.MakeCode(address)

        # code label name
        self.make_name(object_version, address, False)

        # apply view
        self.make_view(object_version, address)

        # apply hidden area
        self.make_hidden_area(object_version, address)
 def OnDeleteLine(self, n):
     ea = self.items[n][2]
     idc.DelFunction(ea)
     return n