コード例 #1
0
ファイル: idapython.py プロジェクト: goodygamee/oisp
def ChunkMovePart(inner_start, inner_end_ex, function_address):
    # maybe the given range covers multiple chunks
    result = []
    fn_print("MACRO move 0x%x-0x%x to 0x%x" %
             (inner_start, inner_end_ex, function_address))

    DisableAutoAnalysis()

    current_inner_start = inner_start
    while current_inner_start < inner_end_ex:
        chunk_start = idc.GetFchunkAttr(current_inner_start,
                                        idc.FUNCATTR_START)
        chunk_end_ex = idc.GetFchunkAttr(current_inner_start, idc.FUNCATTR_END)

        new_inner_end_ex = inner_end_ex
        if chunk_end_ex < inner_end_ex:
            new_inner_end_ex = chunk_end_ex

        result.extend(
            _ChunkMovePart(current_inner_start, new_inner_end_ex,
                           function_address))

        current_inner_start = idc.GetFchunkAttr(current_inner_start,
                                                idc.FUNCATTR_END)
        while not InsIsCode(current_inner_start):
            current_inner_start = idc.NextHead(current_inner_start)
            assert current_inner_start != BADADDR
        #endwhile
    #endwhile

    EnableAutoAnalysis()

    return result
コード例 #2
0
ファイル: database.py プロジェクト: wzr/toolbag
def guessrange(ea):
    '''Try really hard to get boundaries of the block at specified address'''
    start, end = function.getRange(ea)
    if function.contains(start, ea) and not (ea >= start and ea < end):
        return (idc.GetFchunkAttr(ea, idc.FUNCATTR_START),
                idc.GetFchunkAttr(ea, idc.FUNCATTR_END))
    return start, end
コード例 #3
0
 def __chunks(cls, ea):
     '''enumerates all chunks in a function '''
     res = idc.FirstFuncFchunk(ea)
     while res != idc.BADADDR:
         (start, end) = idc.GetFchunkAttr(res, idc.FUNCATTR_START), idc.GetFchunkAttr(res, idc.FUNCATTR_END)
         yield start,end
         res = idc.NextFuncFchunk(ea, res)
     return
コード例 #4
0
    def iterFuncChunks(self, ea):
        start = self.funcStart(ea)
        end = self.funcEnd(ea)

        if not start or not end:
            return []

        current = idc.FirstFuncFchunk(start)
        chunks = [current]

        while True:
            next = idc.NextFuncFchunk(start, current)

            if next != idc.BADADDR:
                current = next
                chunks.append(next)
            else:
                break

        res = []
        for chunk in chunks:
            chunk_end = idc.GetFchunkAttr(chunk, idc.FUNCATTR_END)
            res.extend(list(self.iterInstructions(chunk, chunk_end)))

        return res
コード例 #5
0
ファイル: idapython.py プロジェクト: goodygamee/oisp
def FunctionChunks(addr):
    result = []
    entry = idc.GetFunctionAttr(addr, idc.FUNCATTR_START)

    chunk = idc.FirstFuncFchunk(entry)
    if chunk == BADADDR:
        return result

    # list the function chunks
    result.append([chunk, idc.GetFchunkAttr(chunk, idc.FUNCATTR_END)])
    while chunk != BADADDR:
        chunk = idc.NextFuncFchunk(entry, chunk)
        if chunk != BADADDR:
            result.append([chunk, idc.GetFchunkAttr(chunk, idc.FUNCATTR_END)])

    return result
コード例 #6
0
def enumerate_function_chunks(f_start):
    """
    The function gets a list of chunks for the function.
    @f_start - first address of the function
    @return - list of chunks
    """
    # Enumerate all chunks in the function
    chunks = list()
    first_chunk = idc.FirstFuncFchunk(f_start)
    chunks.append((first_chunk, idc.GetFchunkAttr(first_chunk,
                                                  idc.FUNCATTR_END)))
    next_chunk = first_chunk
    while next_chunk != 0xffffffffL:
        next_chunk = idc.NextFuncFchunk(f_start, next_chunk)
        if next_chunk != 0xffffffffL:
            chunks.append(
                (next_chunk, idc.GetFchunkAttr(next_chunk, idc.FUNCATTR_END)))
    return chunks
コード例 #7
0
def init(tests):
    # workaround ida 6.95 function chunks which should really be functions
    for ea in [0x6718f260, 0x671a5250]:
        numrefs = idc.GetFchunkAttr(ea, idc.FUNCATTR_REFQTY)
        if numrefs <= 1:
            continue
        for idx in range(numrefs, 0, -1):
            idc.RemoveFchunk(idc.GetFchunkReferer(ea, idx - 1), ea)
        idc.MakeFunction(ea)
    idc.Wait()
    YaCo.start_tests()
コード例 #8
0
ファイル: idapython.py プロジェクト: goodygamee/oisp
def _ChunkMovePart(inner_start, inner_end_ex, function_address):
    moved_blocks = []

    fn_print("MICRO move 0x%x-0x%x to 0x%x" %
             (inner_start, inner_end_ex, function_address))
    outer_function = idc.GetFunctionAttr(inner_start, idc.FUNCATTR_START)
    outer_start = idc.GetFchunkAttr(inner_start, idc.FUNCATTR_START)
    outer_end_ex = idc.GetFchunkAttr(inner_start, idc.FUNCATTR_END)

    function_address2 = idc.GetFunctionAttr(function_address,
                                            idc.FUNCATTR_START)

    if outer_start == 0xffffffff:
        fn_print("outer start not defined")
        outer_start = inner_start
    if outer_end_ex == 0xffffffff:
        fn_print("outer end not defined")
        outer_end_ex = inner_end_ex

    if function_address2 == outer_function:
        fn_print("don't move, already in function")
        return moved_blocks

    # remove chunk from function
    remove_chunk_ok = True
    if outer_function == BADADDR:
        fn_print("already hanging 0x%x-0x%x" % (outer_start, outer_end_ex))
    else:
        fn_print("remove 0x%x-0x%x from 0x%x" %
                 (outer_start, outer_end_ex, outer_function))
        remove_chunk_ok = FunctionRemoveChunk(outer_start)
        moved_blocks.append([outer_start, outer_end_ex])

        if not remove_chunk_ok:
            fn_print("  could not remove chunk")

            chunks = FunctionChunks(outer_start)
            if len(chunks) == 1:
                fn_print("  deleting function, moving entire chunk")
                if (inner_start != outer_start) or (inner_end_ex !=
                                                    outer_end_ex):
                    fn_print("  changed function bounds!")
                remove_chunk_ok = idaapi.del_func(outer_start)
                assert remove_chunk_ok
                inner_start = outer_start
                inner_end_ex = outer_end_ex
            else:
                fn_print("  function contains chunks %s" %
                         [['0x%x-0x%x' % (i, j)] for i, j in chunks])

                # to disable function chunk isolation
                # return moved_blocks

                if (chunks[0][0] <= inner_start) and (inner_start <
                                                      chunks[0][1]):
                    fn_print(
                        "have to move first chunk, need to work around this..."
                    )

                    fn_print("removing all but first chunk")
                    for i in range(1, len(chunks)):
                        remove_chunk_ok_2 = FunctionRemoveChunk(chunks[i][0])
                        assert remove_chunk_ok_2

                        current_address = chunks[i][0]
                        while current_address < chunks[i][1]:
                            assert InsIsData(current_address) or InsIsHanging(
                                current_address
                            ), "0x%x does not hang nor is data" % current_address
                            current_address = idc.NextHead(current_address)
                        #endwhile
                    #endfor

                    fn_print(
                        "create new function starting at second chunk (0x%x-0x%x)"
                        % (chunks[1][0], chunks[1][1]))
                    create_function_ok = FunctionCreateAt(
                        chunks[1][0], chunks[1][1])
                    moved_blocks.append([chunks[1][0], chunks[1][1]])
                    assert create_function_ok

                    if len(chunks) > 2:
                        for i in range(2, len(chunks)):
                            moved_blocks_sub = _ChunkMovePart(
                                chunks[i][0], chunks[i][1], chunks[1][0])
                            moved_blocks.extend(moved_blocks_sub)
                            assert len(moved_blocks_sub) > 0
                        #endfor
                    #endif

                    fn_print(
                        "finally removing entire function for first chunk")
                    remove_chunk_ok = idaapi.del_func(chunks[0][0])
                    moved_blocks.append([chunks[0][0], chunks[0][1]])
                    assert remove_chunk_ok

                    for i in range(1, len(chunks)):
                        ii = chunks[i][0]
                        while ii < chunks[i][1]:
                            assert not InsIsHanging(ii), "0x%x hangs" % ii
                            ii = idc.NextHead(ii)
                        #endif
                    #endfor

                    inner_start = outer_start
                    inner_end_ex = outer_end_ex
                else:
                    assert False
                #endif
            #endif
        #endif
    #endif

    assert remove_chunk_ok

    move_block_ok = False

    # regular move
    # append the desired part to the correct function
    restored_whole_chunk = False

    fn_print("moving 0x%x-0x%x" % (inner_start, inner_end_ex))

    move_block_ok = FunctionAppendChunk(function_address, inner_start,
                                        inner_end_ex)
    fn_print("   move-block %d" % move_block_ok)

    if not move_block_ok:
        if outer_start == outer_function:
            fn_print(
                "error-restore: start of function 0x%x-(0x%x-0x%x)-0x%x to 0x%x"
                % (outer_start, inner_start, inner_end_ex, outer_end_ex,
                   outer_function))
            assert outer_end_ex == inner_end_ex
            restored_whole_chunk = FunctionCreateAt(outer_start, outer_end_ex)
            moved_blocks.append([outer_start, outer_end_ex])
            assert restored_whole_chunk
        else:
            fn_print("restoring 0x%x-0x%x to 0x%x" %
                     (outer_start, outer_end_ex, outer_function))
            restored_whole_chunk = FunctionAppendChunk(outer_function,
                                                       outer_start,
                                                       outer_end_ex)
            moved_blocks.append([outer_start, outer_end_ex])
            if not restored_whole_chunk:
                real_function = idc.GetFunctionAttr(outer_start,
                                                    idc.FUNCATTR_START)
                should_be_function = outer_function
                if real_function == should_be_function:
                    restored_whole_chunk = True
                else:
                    fn_print("0x%x/0x%x" % (real_function, should_be_function))
            #endif
            assert restored_whole_chunk
    else:
        moved_blocks.append([inner_start, inner_end_ex])

    if not restored_whole_chunk:
        # add PRE-part to original function, if needed
        if outer_start < inner_start:
            fn_print(" prefix...")

            if InsIsHanging(outer_start):
                prefixmove = FunctionAppendChunk(outer_function, outer_start,
                                                 inner_start)
                moved_blocks.append([outer_start, inner_start])
                if not prefixmove:
                    fn_print(
                        "could not restore prefix 0x%x-0x%x, instead adding it to the new function too"
                        % (outer_start, inner_start))
                    prefixmove = FunctionAppendChunk(function_address,
                                                     outer_start, inner_start)
                    assert prefixmove
                    moved_blocks.append(
                        [outer_start, inner_start, function_address])
                else:
                    fn_print("restored prefix 0x%x-0x%x" %
                             (outer_start, inner_start))
                #endif
            #endif
        #endif

        # add POST-part to original function, if needed
        if inner_end_ex < outer_end_ex:
            fn_print(" postfix...")

            post_start = inner_end_ex
            while post_start < outer_end_ex:
                if InsIsData(post_start):
                    # skip data
                    post_start = idc.NextHead(post_start)
                else:
                    # found start of a block of code
                    subpost_start = post_start
                    fn_print("found subpost start 0x%x" % subpost_start)

                    subpost_end = idc.NextHead(subpost_start)
                    while subpost_end < outer_end_ex:
                        if not InsIsHanging(subpost_end):
                            break
                        subpost_end = idc.NextHead(subpost_end)
                    #endwhile subpost_start

                    # don't go past the end of the section
                    E = section_end(subpost_start)
                    if subpost_end > E:
                        subpost_end = E

                    fn_print("found subpost 0x%x-0x%x" %
                             (subpost_start, subpost_end))
                    postfixmove = FunctionAppendChunk(outer_function,
                                                      subpost_start,
                                                      subpost_end)
                    moved_blocks.append([subpost_start, subpost_end])
                    if not postfixmove:
                        fn_print(
                            "could not restore postfix 0x%x-0x%x, instead adding it to the new function too"
                            % (subpost_start, subpost_end))
                        postfixmove = FunctionAppendChunk(
                            function_address, subpost_start, subpost_end)
                        if not postfixmove:
                            DumpDatabase('assertion.idb')
                        assert postfixmove
                        moved_blocks.append([subpost_start, subpost_end])
                    else:
                        fn_print("restored postfix 0x%x-0x%x" %
                                 (subpost_start, subpost_end))
                    #endif

                    post_start = subpost_end
                #endif
            #endwhile post_start
        #endif
    #endif

    ii = outer_start
    while ii < outer_end_ex:
        assert not InsIsHanging(ii), "0x%x hangs" % ii
        ii = idc.NextHead(ii)
    #endif

    return moved_blocks