Beispiel #1
0
 def find_all_segments(self, segment_names):
     segments = {name: None for name in segment_names}
     for seg_va in Segments():
         seg_name = get_segm_name(seg_va)
         if seg_name in segment_names:
             segments[seg_name] = (seg_va, get_segm_end(seg_va))
     return segments
Beispiel #2
0
def main():
    idaapi.auto_wait()
    base = idaapi.get_imagebase()
    tif = idaapi.tinfo_t()

    f = open(os.environ.get("DESTPATH", "functype_"), 'w')

    for ea in Segments():
        # only code segment
        if idaapi.segtype(ea) != idaapi.SEG_CODE:
            continue

        for fva in Functions(get_segm_start(ea), get_segm_end(ea)):
            func_name = get_func_name(fva)
            has_type = idaapi.get_tinfo(tif, fva) or idaapi.guess_tinfo(
                tif, fva)

            if not has_type:
                continue

            info = serialize(tif)
            if info is None:
                continue

            print(
                hex(fva - base)[:-1], "|", func_name, "|", tif, "|",
                len(info['args']))
            f.write("0x%x|%s|%s\n" % (fva - base, func_name, json.dumps(info)))

    f.close()
    idaapi.qexit(0)
Beispiel #3
0
 def getlen(self):
     # Lazy version
     if hasattr(self, "_getlen"):
         return self._getlen
     max_addr = SegEnd(list(Segments())[-1] - (self.offset + self.shift))
     self._getlen = max_addr
     return max_addr
Beispiel #4
0
 def getlen(self):
     # Lazy version
     if hasattr(self, "_getlen"):
         return self._getlen
     max_addr = get_segm_end(
         list(Segments())[-1] - (self.offset - self.base_address))
     self._getlen = max_addr
     return max_addr
Beispiel #5
0
def all_valid_ea():
    """Return all valid EA as a Python generator."""
    from idautils import Segments
    from idc import SegStart, SegEnd
    for s in Segments():
        ea = SegStart(s)
        while ea < SegEnd(s):
            yield ea
            ea = idaapi.nextaddr(ea)
Beispiel #6
0
def update_guids(path_to_db, seg_types=None):
    _load_guids_db(path_to_db)
    if seg_types:

        def filter_expr(x):
            return getseg(x).type in seg_types

    else:
        filter_expr = None
    for seg_beg in filter(filter_expr, Segments()):
        seg_end = get_segm_end(seg_beg)
        _process_segment(seg_beg, seg_end)
 def ptrs(self):
     for seg_beg in filter(lambda x: getseg(x).type == SEG_DATA,
                           Segments()):
         seg_end = get_segm_end(seg_beg)
         head = seg_beg
         while True:
             head = next_head(head, seg_end)
             if head == BADADDR:
                 break
             head_ptr = Pointer(head)
             if head_ptr.type.rstrip(" *") == self.name:
                 yield head_ptr
Beispiel #8
0
def dump_symbol_info(output_filename):
    """Dump information for BAP's symbolizer into output_filename."""
    from idautils import Segments, Functions
    from idc import (
        SegStart, SegEnd, GetFunctionAttr,
        FUNCATTR_START, FUNCATTR_END
    )

    try:
        from idaapi import get_func_name2 as get_func_name
        # Since get_func_name is deprecated (at least from IDA 6.9)
    except ImportError:
        from idaapi import get_func_name
        # Older versions of IDA don't have get_func_name2
        # so we just use the older name get_func_name

    def func_name_propagate_thunk(ea):
        current_name = get_func_name(ea)
        if current_name[0].isalpha():
            return current_name
        func = idaapi.get_func(ea)
        temp_ptr = idaapi.ea_pointer()
        ea_new = idaapi.BADADDR
        if func.flags & idaapi.FUNC_THUNK == idaapi.FUNC_THUNK:
            ea_new = idaapi.calc_thunk_func_target(func, temp_ptr.cast())
        if ea_new != idaapi.BADADDR:
            ea = ea_new
        propagated_name = get_func_name(ea) or ''  # Ensure it is not `None`
        if len(current_name) > len(propagated_name) > 0:
            return propagated_name
        else:
            return current_name
            # Fallback to non-propagated name for weird times that IDA gives
            #     a 0 length name, or finds a longer import name

    idaapi.autoWait()

    with open(output_filename, 'w+') as out:
        for ea in Segments():
            fs = Functions(SegStart(ea), SegEnd(ea))
            for f in fs:
                out.write('("%s" 0x%x 0x%x)\n' % (
                    func_name_propagate_thunk(f),
                    GetFunctionAttr(f, FUNCATTR_START),
                    GetFunctionAttr(f, FUNCATTR_END)))
Beispiel #9
0
    def set_text_segment_rwe():
        """
        Update name, class, permissions of CODE segment to resolve elimination of "dead" code.
        Also set compiler to VC++.
        """
        for seg in Segments():
            if get_segm_name(seg) == ".text":
                set_segm_name(seg, ".code")
                set_segm_class(seg, "DATA")
                set_segm_attr(seg, SEGATTR_PERM, 0b111)  # RWE

                print("Updating segment at " + hex(seg) +
                      ":\nsegment name .text -> .code" +
                      "\nsegment class = DATA" + "\nsegment permissions = RWE")

                break

        set_compiler_id(1)  # Visual C++
Beispiel #10
0
def dump_loader_info(output_filename):
    """Dump information for BAP's loader into output_filename."""
    from idautils import Segments
    import idc

    idaapi.autoWait()

    with open(output_filename, 'w+') as out:
        info = idaapi.get_inf_structure()
        size = "r32" if info.is_32bit else "r64"
        out.write("(%s %s (" % (info.get_proc_name()[1], size))
        for seg in Segments():
            out.write("\n(%s %s %d (0x%X %d))" % (
                idaapi.get_segm_name(seg),
                "code" if idaapi.segtype(seg) == idaapi.SEG_CODE else "data",
                idaapi.get_fileregion_offset(seg),
                seg, idaapi.getseg(seg).size()))
        out.write("))\n")
Beispiel #11
0
def update_structs_from_xrefs(track_members=True):
    """
    Find xrefs to a struct pointer and change all the offsets to be struct offsets. This is useful for updating
    references to function pointers in EFI tables.

    For example:
    mov     rax, cs:qword_whatever
    call    qword ptr [rax+150h]

    Becomes:
    mov     rax, cs:gBootServices
    call    [rax+EFI_BOOT_SERVICES.UninstallMultipleProtocolInterfaces]
    """

    for seg_beg in Segments():
        seg_end = get_segm_end(seg_beg)
        head = next_head(seg_beg, seg_end)
        while head != BADADDR:
            head_ptr = Pointer(head)
            if is_structure_type(head_ptr.type.rstrip(" *")):
                print("Updating structures for xref: %s" % head_ptr)
                struc = Structure(head_ptr.type.rstrip(" *"))
                _update_from_ptr(head_ptr, struc, track_members)
            head = next_head(head, seg_end)
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 = ''