def run(self, arg):
        self.term()

        self.view = Initrefview_t()
        if not self.view.Create(WINDOW_NAME):
            return

        for start in idautils.Segments():
            segm = self.init_segm if self.is_seg_init(
                start) else self.non_init_segm
            segm.add((start, idaapi.getseg(start).end_ea))

        if not self.refs:
            self.generate_refs()

        self.display_refs()
        self.view.Show()
Beispiel #2
0
def rename_guids():
    labels = {}
    # Load GUIDs
    guids = dict(
        (str(GUID(array=v)), k) for k, v in efiguids.GUIDs.iteritems()
    )
    guids.update(dict((v, k) for k, v in local_guids.iteritems()))

    # Find all the data segments in this binary
    for seg_addr in idautils.Segments():
        seg = ida_segment.getseg(seg_addr)
        print "Processing data segment at 0x{:08x}".format(seg_addr)

        # Find any GUIDs we know about in the data segment
        cur_addr = seg.start_ea
        seg_end = seg.end_ea
        while cur_addr < seg_end:
            d = [ida_bytes.get_dword(cur_addr),
                 ida_bytes.get_dword(cur_addr+0x4),
                 ida_bytes.get_dword(cur_addr+0x8),
                 ida_bytes.get_dword(cur_addr+0xC)]
            if (d[0] == 0 and d[1] == 0 and d[2] == 0 and d[3] == 0) or \
               (
                d[0] == 0xFFFFFFFF and d[1] == 0xFFFFFFFF and
                d[2] == 0xFFFFFFFF and d[3] == 0xFFFFFFFF
               ):
                cur_addr += 0x10
            else:
                guid = GUID(bytes=struct.pack(
                    "<LLLL", d[0], d[1], d[2], d[3]
                ))
                gstr = str(guid)
                if gstr in guids.keys():
                    print "  - Found GUID {} ({}) at 0x{:08x}".format(
                        gstr, guids[gstr], cur_addr
                    )
                    struct_label = get_next_unused_label(
                        underscore_to_global(guids[gstr])
                    )
                    ida_name.set_name(cur_addr, struct_label)
                    labels[struct_label] = (cur_addr, guids[gstr])
                    cur_addr += 0x10
                else:
                    cur_addr += 0x08

    return labels
Beispiel #3
0
def initialize_data_offsets():
    """Convert offsets in data segments into offsets in IDA.

    Segment names must be initialized with segments.initialize_segments() first.
    """
    # Normally, for user-space programs, this operation would be dangerous because there's a good
    # chance that a valid userspace address would happen to show up in regular program data that is
    # not actually an address. However, since kernel addresses are numerically much larger, the
    # chance of this happening is much less.
    for seg in idautils.Segments():
        name = idc.get_segm_name(seg)
        if not (name.endswith('__DATA_CONST.__const') or name.endswith('__got')
                or name.endswith('__DATA.__data') or name.endswith('__DATA_CONST.__auth_ptr')):
            continue
        for word, ea in idau.ReadWords(seg, idc.get_segm_end(seg), addresses=True):
            if idau.is_mapped(word, value=False):
                idc.op_plain_offset(ea, 0, 0)
Beispiel #4
0
 def __init__(self, title, api_results, flags=0):
     Choose.__init__(self,
                     title, [["#", 6], ["Offset", 14], ["API Address", 14],
                             ["DLL", 20], ["API", 35]],
                     embedded=True,
                     width=140,
                     height=20,
                     flags=flags)
     self.row_count = 0
     self.base_address = [ea for ea in idautils.Segments()][0]
     self.scout = ApiScout()
     self.scout.setBaseAddress(self.base_address)
     self.api_results = api_results
     self.all_items = self.populate(api_results)
     self.items = self.populate(api_results)
     self.icon = 4
     self.selcount = 0
Beispiel #5
0
def findMostUsedFunctions(count, notModified=False, disp=True):
    # type: (int, bool, bool) -> list[int]
    """
    Returns the functions with the highest count of xrefsTo. if notModified, only those that are in the format
    *_xxxxxxx are returned. if disp, the output is formatted and printed as well
    :param count: the number of the most used functions to find
    :param notModified: only functions with names ending in func_ea, or all functions
    :param disp: print the output
    :return: list of function linear addresses to the most used functions
    """
    funcXrefs = []

    if count <= 0: count = 1
    for i in range(count):
        funcXrefs.append((0, 0))

    for seg_ea in idautils.Segments():
        for func_ea in idautils.Functions(seg_ea, idc_bc695.SegEnd(seg_ea)):
            if notModified:
                name = Function.Function(func_ea).getName()
                if not ('_' in name
                        and name[name.rindex('_'):] == ('_%X' % func_ea)):
                    continue

            xrefs = Function.Function(func_ea).getXRefsTo()
            numXrefs = len(xrefs[0]) + len(xrefs[1])

            # add if more than least in the list and sort
            if numXrefs > funcXrefs[0][1]:
                funcXrefs[0] = (func_ea, numXrefs)
                funcXrefs = sorted(funcXrefs, key=lambda tup: tup[1])

    # reverse to display most common first
    funcXrefs = sorted(funcXrefs, key=lambda tup: tup[1], reverse=True)

    if disp:
        for func_ea, xrefCount in funcXrefs:
            print('%07x <%s::%s>: %d' %
                  (func_ea, mtcomm.ea2gf(func_ea),
                   Function.Function(func_ea).getName(), xrefCount))

    output = []
    for func_ea, xrefCount in funcXrefs:
        output.append(func_ea)
    return output
Beispiel #6
0
def __patch_indirect_call_instructions():
    for seg in idautils.Segments():
        for func in idautils.Functions(seg):
            function_name = idc.get_func_name(func)
            print('[+] Checking function "{}"'.format(function_name))
            for (startea, endea) in idautils.Chunks(func):
                for head in idautils.Heads(startea, endea):
                    m = idc.print_insn_mnem(head)
                    if m == 'call':
                        op = idc.get_operand_type(head, 0)
                        if op == idc.o_displ:
                            print('{}: 0x{:08x}: {}'.format(
                                function_name, head,
                                idc.generate_disasm_line(head, 0)))
                            ida_bytes.patch_word(head, 0x15ff)
                            print('{}: 0x{:08x}: {}'.format(
                                function_name, head,
                                idc.generate_disasm_line(head, 0)))
Beispiel #7
0
def initialize_stub_symbols(make_thunk=True):
    """Populate IDA with information about the stubs in an iOS kernelcache.

    Search through the kernelcache for stubs (__stubs sections) and rename each stub function
    according to the target function it calls.

    Arm64 only.

    Options:
        make_thunk: Set the thunk attribute for each stub function. Default is True.
    """
    next_stub = internal.make_name_generator(kernelcache_stub_suffix)
    for ea in idautils.Segments():
        segname = idc.SegName(ea)
        if not segname.endswith('__stubs'):
            continue
        _log(3, 'Processing segment {}', segname)
        _process_stubs_section(ea, make_thunk, next_stub)
Beispiel #8
0
def getAllSegments():
    segs = list()
    si = SegmInfo()
    i = 0
    for ea in idautils.Segments():
        seg = idaapi.getseg(ea)
        si.m_name = idc.SegName(ea)
        si.m_startAddr = int(idc.SegStart(ea))
        si.m_endAddr = int(idc.SegEnd(ea))
        si.m_className = idaapi.get_segm_class(seg)
        segs.append(si)
        print "[%d]" % (i)
        print "Segment name: %s" % (si.m_name)
        print "Segment start address: 0x%08x" % (si.m_startAddr)
        print "Segment end address: 0x%08x" % (si.m_endAddr)
        print "Segment class name: %s" % (si.m_className)
        i += 1
    return segs
def main():
    print("[*] Start Replace Symbolic Constant")

    for start in idautils.Segments():
        #if idc.get_segm_name(start) != '.text':
        #    continue
        ea = start
        end = idc.get_segm_end(start)
        while ea < end:
            ea = idc.next_head(ea, end)
            op = idc.print_insn_mnem(ea)
            if op == "call":
                api = is_replace_api(ea)
                if api == False:
                    continue
                replace_sym_const(ea, api)

    print("[*] Finished Replace Symbolic Constant")
Beispiel #10
0
def preprocessBinary():
    # loop through every instruction and
    # keep a list of jump tables references in the
    # data section. These are used so we can
    # avoid generating unwanted function entry points
    for seg_ea in idautils.Segments():
        for head in idautils.Heads(seg_ea, idc.SegEnd(seg_ea)):
            if idc.isCode(idc.GetFlags(head)):
                si = idaapi.get_switch_info_ex(head)
                if si is not None and isUnconditionalJump(head):
                    DEBUG("Found a jmp based switch at: {0:x}\n".format(head))
                    esize = si.get_jtable_element_size()
                    base = si.jumps
                    count = si.get_jtable_size()
                    for i in xrange(count):
                        fulladdr = base+i*esize
                        DEBUG("Address accessed via JMP: {:x}\n".format(fulladdr))
                        ACCESSED_VIA_JMP.add(fulladdr)
Beispiel #11
0
 def getModuleFunctions(self):
     """
     This traverses all segments, and all defined modules to retrieve all functions with that module name.
     :return: a list of Functions that are in this module, saved in the database.
     """
     output = []
     for seg_ea in idautils.Segments():
         for func_ea in idautils.Functions(idc_bc695.SegStart(seg_ea),
                                           idc_bc695.SegEnd(seg_ea)):
             func = Function.Function(func_ea)
             # if the function starts with '<moduleName>'...
             funcName = func.getName()
             inModel = len(funcName) >= len(
                 self.name) + 1 and funcName[0:len(self.name) +
                                             1] == self.name + '_'
             if inModel:
                 output.append(func)
     return output
Beispiel #12
0
def _get_memory():
    """
    stolen from Dan aka @push_pnx
    copies bytes from IDB into memory that yara scans
    :return:
    """
    result = ""
    segments_starts = [ea for ea in idautils.Segments()]
    offsets = []
    start_len = 0
    for start in segments_starts:
        end = idc.get_segm_end(start)
        # range or xrange can fail on 64-bit addresses due to an overflow
        for ea in _wowrange(start, end):
            result += chr(idc.Byte(ea))
        offsets.append((start, start_len, len(result)))
        start_len = len(result)
    return result, offsets
Beispiel #13
0
def seh():
	print "Searching places where SEH are set..."
	founds = []
	
	for seg in idautils.Segments():
		heads = list(Heads(SegStart(seg), SegEnd(seg)))
		for i,ea in enumerate(heads):
			mnem = GetMnem(ea)
			
			if (mnem == 'push') and ('fs:0' in GetOpnd(ea, 0)) and ('security_cookie' not in GetOpnd(heads[i+1], 1)):
				SetColor(ea, CIC_ITEM, 0xFF00FF)
				SetColor(heads[i-1], CIC_ITEM, 0xFF00FF)
				SetColor(heads[i+1], CIC_ITEM, 0xFF00FF)
				
				founds.append(hex(ea))
				MakeComm(heads[i-1], "SEH CREATING")
				
	print "Finished. Addresses were highlighted", founds
	printSehImports()
Beispiel #14
0
    def search_idb(self):
        """Search IDB for possible MZ/PE headers"""
        # Determine pointer display width
        info = idaapi.get_inf_structure()

        if info.is_64bit():
            width = 16
        else:
            width = 8

        # Search all segments
        for seg in idautils.Segments():
            s = idc.get_segm_start(seg)
            e = idc.get_segm_end(seg)
            addr = s

            while True:
                # Find first byte of MZ header
                addr = ida_bytes.find_byte(addr, e - addr, 0x4d, 0)

                if addr == ida_idaapi.BADADDR or addr >= e:
                    break

                # Check for MZ magic
                if ida_bytes.get_word(addr) == 0x5a4d:
                    # Ensure the PE header is in the segment
                    e_lfanew = ida_bytes.get_dword(addr + 0x3c)

                    if addr + e_lfanew + 1 < e:
                        # Check for PE magic
                        if ida_bytes.get_word(addr + e_lfanew) == 0x4550:
                            # Found possible MZ/PE file
                            self.form.runtime.log("0x{:0{w}x} - {}".format(
                                addr, idc.get_segm_name(s), w=width))

                            self.form.map_pe(image_base=addr,
                                             filename="{} - 0x{:0{w}x}".format(
                                                 idc.get_segm_name(s),
                                                 addr,
                                                 w=width))

                # Resume search from next address
                addr += 1
def enumerate_function_names():
    func_name = dict()
    for seg_ea in idautils.Segments():
        # For each of the functions
        function_ea = seg_ea
        while function_ea != 0xffffffffL:
            function_name = idc.GetFunctionName(function_ea)
            # if already analyzed
            if func_name.get(function_name, None) != None:
                function_ea = idc.NextFunction(function_ea)
                continue
            image_base = idaapi.get_imagebase(function_ea)
            addr = function_ea - image_base
            addr = str(hex(addr))
            addr = addr.replace("L", "")
            addr = addr.replace("0x", "")
            func_name[function_name] = get_list_of_function_instr(function_ea)
            function_ea = idc.NextFunction(function_ea)
    return func_name
Beispiel #16
0
    def get_architecture_name(self):
        """Fetch the name to be used to identify the architecture."""

        # Get the addressing mode of the first segment in the IDB and
        # set it to describe the module in the database.
        # This would need to be rethought for the cases where addressing
        # might change withing a module.
        #
        bitness = idc.GetSegmentAttr(
            list(idautils.Segments())[0], idc.SEGATTR_BITNESS)

        if bitness == 0:
            bitness = 16
        elif bitness == 1:
            bitness = 32
        elif bitness == 2:
            bitness = 64

        return '%s-%d' % (self.arch_name, bitness)
Beispiel #17
0
def _find_prelink_info_segments():
    """Find all candidate __PRELINK_INFO segments (or sections).

    We try to identify any IDA segments with __PRELINK_INFO in the name so that this function will
    work both before and after automatic rename. A more reliable method would be parsing the
    Mach-O.
    """
    segments = []
    # Gather a list of all the possible segments.
    for seg in idautils.Segments():
        name = idc.get_segm_name(seg)
        if '__PRELINK_INFO' in name or name == '__info':
            segments.append(seg)
    if len(segments) < 1:
        _log(0, 'Could not find any __PRELINK_INFO segment candidates')
    elif len(segments) > 1:
        _log(1, 'Multiple segment names contain __PRELINK_INFO: {}',
                [idc.get_segm_name(seg) for seg in segments])
    return segments
def _collect_metaclasses():
    """Collect OSMetaClass information from all kexts in the kernelcache."""
    # Collect associations from class names to metaclass instances and vice versa.
    metaclass_to_classname_builder = _OneToOneMapFactory()
    metaclass_to_class_size = dict()
    metaclass_to_meta_superclass = dict()

    def found_metaclass(metaclass, classname, class_size, meta_superclass):
        metaclass_to_classname_builder.add_link(metaclass, classname)
        metaclass_to_class_size[metaclass] = class_size
        metaclass_to_meta_superclass[metaclass] = meta_superclass

    for ea in idautils.Segments():
        segname = idc.get_segm_name(ea)
        if not _should_process_segment(ea, segname):
            continue
        _log(2, 'Processing segment {}', segname)
        _process_mod_init_func_section_for_metaclasses(ea, found_metaclass)
    # Filter out any class name (and its associated metaclasses) that has multiple metaclasses.
    # This can happen when multiple kexts define a class but only one gets loaded.
    def bad_classname(classname, metaclasses):
        _log(0, 'Class {} has multiple metaclasses: {}', classname,
             ', '.join(['{:#x}'.format(mc) for mc in metaclasses]))

    # Filter out any metaclass (and its associated class names) that has multiple class names. I
    # have no idea why this would happen.
    def bad_metaclass(metaclass, classnames):
        _log(0, 'Metaclass {:#x} has multiple classes: {}', metaclass,
             ', '.join(classnames))

    # Return the final dictionary of metaclass info.
    metaclass_to_classname = metaclass_to_classname_builder.build(
        bad_metaclass, bad_classname)
    metaclass_info = dict()
    for metaclass, classname in list(metaclass_to_classname.items()):
        meta_superclass = metaclass_to_meta_superclass[metaclass]
        superclass_name = metaclass_to_classname.get(meta_superclass, None)
        metaclass_info[metaclass] = classes.ClassInfo(
            classname, metaclass, None, None,
            metaclass_to_class_size[metaclass], superclass_name,
            meta_superclass)
    return metaclass_info
Beispiel #19
0
def _listUpdatedSymbols(elfPath):
    """
    Searches through the symtable in the elfPath, and computes a list of name_eas, and their
    new names
    :param elfPath: path of the elf file to process
    :return: list of (name_ea, [(new_name, isLocal)])
    """
    # TODO [DESIGN]: function exists in Srch too. Remove redundancy
    output = []
    symTable = _getSymTable(elfPath)

    # compute all names in RAM and ROM
    names = []
    for seg_ea in idautils.Segments():
        # skip BIOS
        if seg_ea == 0:
            continue
        for head in idautils.Heads(seg_ea, idc_bc695.SegEnd(seg_ea)):
            if idc.Name(head):
                names.append((head, idc.Name(head)))

    for ea, name in names:
        if ea in symTable or ea+1 in symTable:

            # increment by 1 for thumb function symbols
            if ea+1 in symTable and idc.isCode(idc.GetFlags(ea)):
                name_ea = ea+1
            else:
                name_ea = ea

            # check if the name exists in the symTable
            nameInSymTable = False
            for symName, isLocal in symTable[name_ea]:
                if name == symName:
                    nameInSymTable = True

            # a name change was detected
            if not nameInSymTable:
                output.append((ea, symTable[name_ea]))


    return output
Beispiel #20
0
def _find_prelink_info_segment():
    """Find the __PRELINK_INFO segment.

    We try to identify a unique segment with __PRELINK_INFO in the name so that this function will
    work both before and after automatic rename. A more reliable method would be parsing the
    Mach-O.
    """
    segments = []
    for seg in idautils.Segments():
        name = idc.SegName(seg)
        if '__PRELINK_INFO' in name:
            segments.append(seg)
    if len(segments) < 1:
        _log(0, 'No segment name contains __PRELINK_INFO')
    elif len(segments) > 1:
        _log(0, 'Multiple segment names contain __PRELINK_INFO: {}',
             [idc.SegName(seg) for seg in segments])
    else:
        return segments[0]
    return None
Beispiel #21
0
def initialize_data_offsets():
    """Convert offsets in data segments into offsets in IDA.

    This function should only be run on 11-normal style kernelcaches.

    Segment names must be initialized with segments.initialize_segments() first.
    """
    assert kernel.kernelcache_format == kernel.KC_11_NORMAL, 'Wrong kernelcache format'
    # Normally, for user-space programs, this operation would be dangerous because there's a good
    # chance that a valid userspace address would happen to show up in regular program data that is
    # not actually an address. However, since kernel addresses are numerically much larger, the
    # chance of this happening is much less.
    for seg in idautils.Segments():
        name = idc.SegName(seg)
        if not (name.endswith('__DATA_CONST.__const') or name.endswith('__got')
                or name.endswith('__DATA.__data')):
            continue
        for word, ea in idau.ReadWords(seg, idc.SegEnd(seg), addresses=True):
            if idau.is_mapped(word, value=False):
                idc.OpOff(ea, 0, 0)
Beispiel #22
0
def getx86CodeSize(ea=None):
    '''
    For a given EA, finds the code size. Returns 16 for-16bit, 32 for 32-bit, or 64 for 64-bit.
    If no EA is given, searches through all segments for a code segment to use.
    '''
    if ea is None:
        for seg in idautils.Segments():
            if idc.GetSegmentAttr(seg, idc.SEGATTR_TYPE) == idc.SEG_CODE:
                ea = seg
                break
    if ea is None:
        raise RuntimeError('Could not find code segment to use for getx86CodeSize')
    bitness = idc.GetSegmentAttr(ea, idc.SEGATTR_BITNESS)
    if bitness == 0:
        return 16
    elif bitness == 1:
        return 32
    elif bitness == 2:
        return 64
    raise RuntimeError('Bad bitness')
Beispiel #23
0
def get_sections():
    """
    Get section names and start/end addrs from IDA database

    :return: Dict containing section info
    """

    sections = {}
    for ea in idautils.Segments():
        segm = ida_segment.getseg(ea)
        name = ida_segment.get_segm_name(segm)
        if name == 'LOAD':
            continue

        curr = {}
        curr['start'] = segm.start_ea
        curr['end'] = segm.end_ea
        sections[name] = curr

    return sections
Beispiel #24
0
def parse_func_pointer():
    renamed = 0
    for segea in idautils.Segments():
        for addr in idautils.Functions(segea, idc.SegEnd(segea)):
        #for addr in idautils.Functions(text_seg.startEA, text_seg.endEA):
            name = idc.GetFunctionName(addr)

            # Look at data xrefs to the function - find the pointer that is located in .rodata
            data_ref = idaapi.get_first_dref_to(addr)
            while data_ref != idc.BADADDR:
                if 'rodata' in idc.get_segm_name(data_ref):
                    # Only rename things that are currently listed as an offset; eg. off_9120B0
                    if 'off_' in idc.GetTrueName(data_ref):
                        if idc.MakeNameEx(data_ref, ('%s_ptr' % name), flags=idaapi.SN_FORCE):
                            idaapi.autoWait()
                            renamed += 1
                        else:
                            log._error('Failed to name pointer @ 0x%02x for %s' % (data_ref, name))

                data_ref = idaapi.get_next_dref_to(addr, data_ref)
Beispiel #25
0
 def add_rodata_segment(self):
     last_seg_end = idc.get_first_seg()
     # print(hex(last_seg_end))
     for s in idautils.Segments():
         start = idc.get_segm_start(s)
         end = idc.get_segm_end(s)
         if int(start) != int(last_seg_end):
             # found
             idaapi.add_segm(0, last_seg_end, start, "roooodata", "CONST")
             print("Adding segment from 0x%x to 0x%x" %
                   (last_seg_end, start))
             print("OK")
             break
         else:
             last_seg_end = end
     idc.plan_and_wait(ida_ida.inf_get_min_ea(), ida_ida.inf_get_max_ea())
     # idc.plan_and_wait(idc.MinEA(), idc.MaxEA())
     self.start = last_seg_end
     self.end = start
     return last_seg_end, start
Beispiel #26
0
 def create_call_map(self, ftype):
     assert_ida_available()
     import idc
     import idautils
     seg_mapping = {
         idc.SegName(x): (idc.SegStart(x), idc.SegEnd(x))
         for x in idautils.Segments()
     }
     imports = seg_mapping[".idata"] if ftype == PE else seg_mapping['.plt']
     start, stop = seg_mapping[".text"]
     current = start
     while current <= stop:
         inst = current
         if idc.GetMnem(inst) in ["call", "jmp"]:
             value = idc.GetOperandValue(inst, 0)
             name = idc.GetOpnd(inst, 0)
             if imports[0] <= value <= imports[1]:
                 entry = self.config.call_map.add()
                 entry.address = inst
                 entry.name = name
         current = idc.NextHead(current, stop)
Beispiel #27
0
def init_strings(force=False, target_seg_name=None):
    global string_initialized
    if not force and string_initialized:
        return

    for ea in idautils.Segments():
        seg = ida_segment.getseg(ea)
        seg_name = ida_segment.get_segm_name(seg)

        # We only check target segment since it may take too much time.
        if target_seg_name and seg_name == target_seg_name:
            continue

        print("Initializing %x -> %x (%s)" %
              (seg.start_ea, seg.end_ea, seg_name))

        # TODO: we may use other strategy to find string pointers
        analyze_str_ptr(seg.start_ea, seg.end_ea)

    analyze_ida_str()
    string_initialized = True
Beispiel #28
0
    def __init__(self, fmt='[+] srch (IDB/binary searching utils)'):
        """
        This module is responsible for printing disassemblies and necessary compoents
        of disassemblies
        """
        super(srch, self).__init__(fmt)

        self.registerCommand(self, self.nextarm, "nextarm", "<search_ea> [ui=True]")
        self.registerCommand(self, self.nextascii, "nextascii", "<search_ea> [ui=True]")
        self.registerCommand(self, self.nextfakeinst, "nextfakeinst", "<search_ea> [ui=True]")
        self.registerCommand(self, self.nextname, "nextname", "<search_ea> [ui=True]")
        self.registerCommand(self, self.nextknown, "nextknown", "<search_ea> [ui=True]")
        self.registerCommand(self, self.nextbin, "nextbin", "<search_ea> [ui=True]")
        self.registerCommand(self, self.nextred, "nextred", "<search_ea> [ui=True]")
        self.registerCommand(self, self.nextimmref, "nextimmref", "<search_ea> [ui=True]")

        # figure out the very last ea reachable
        self.end_ea = 0
        for seg in idautils.Segments():
            if idc.SegEnd(seg) > self.end_ea:
                self.end_ea = idc.SegEnd(seg)
def run_yara_on_segment(rule_text,
                        name=None,
                        start_ea=None,
                        callback_func=_yara_callback):
    '''
    Description:
        Applies yara rule to the bytes in the specified segment and returns raw results.
        Segments may be specified by name or start EA, but one or the other is required.
        Clears the matches each time to prevent duplicates.

    Input:
        name - The name of the target segment
        start_ea - The start EA of the target segment
        callback_func - A pointer to the callback function for YARA's matching to use

    Output:
        Returns a list of YARA's match results with items (location, description)
    '''
    global _YARA_MATCHES, FROM_FILE
    _YARA_MATCHES = []
    FROM_FILE = False

    if name is None and start_ea is None:
        raise Exception(
            "Either a segment name or start EA are required to YARA scan a specific segment."
        )

    rule = yara.compile(source=rule_text)
    found_segment = False
    for seg in map(idaapi.getseg, idautils.Segments()):
        if seg.startEA == start_ea or idaapi.get_segm_name(
                seg.startEA) == name:
            found_segment = True
            for bites in _read_bytes(seg.startEA, seg.endEA):
                rule.match(data=bites, callback=callback_func)

    if not found_segment:
        append_debug("Failed to find segment \"" + name + "\"")

    return _YARA_MATCHES
Beispiel #30
0
 def rename_supposed_guids(self):
     EFI_GUID = "EFI_GUID *"
     for seg in idautils.Segments():
         if idc.SegName(seg) == ".data":
             seg_start = idc.SegStart(seg)
             seg_end = idc.SegEnd(seg)
             break
     ea = seg_start
     while (ea <= seg_end - 15):
         prot_name = ""
         if idc.Name(ea).find("unk_") != -1:
             find = False
             CurrentGuid = []
             CurrentGuid.append(idc.Dword(ea))
             CurrentGuid.append(idc.Word(ea + 4))
             CurrentGuid.append(idc.Word(ea + 6))
             for addr in range(ea + 8, ea + 16, 1):
                 CurrentGuid.append(idc.Byte(addr))
             for name in self.Protocols["Edk2Guids"]:
                 if self.Protocols["Edk2Guids"][name] == CurrentGuid:
                     prot_name = name + "_" + hex(ea)
                     find = True
                     break
             for name in self.Protocols["EdkGuids"]:
                 if self.Protocols["EdkGuids"][name] == CurrentGuid:
                     prot_name = name + "_" + hex(ea)
                     find = True
                     break
             for name in self.Protocols["AmiGuids"]:
                 if self.Protocols["AmiGuids"][name] == CurrentGuid:
                     prot_name = name + "_" + hex(ea)
                     find = True
                     break
             if (find and \
                 idc.Name(ea) != prot_name and \
                 CurrentGuid[0] != 0
                 ):
                 idc.SetType(ea, EFI_GUID)
                 idc.MakeName(ea, prot_name)
         ea += 1