Python idc.SegName() Examples

The following are 30 code examples of idc.SegName(). These examples are extracted from open source projects. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module idc , or try the search function .
Example #1
Source Project: python-idb   Author: williballenthin   File: dump_section_list.py    License: Apache License 2.0 8 votes vote down vote up
def print_section_list():
    for s in idautils.Segments():
        seg = idaapi.getseg(s)
        print("%s" % idc.SegName(s))
        print(" - start address: 0x%x" % seg.startEA)
        print(" - sclass: 0x%x" % seg.sclass)
        print(" - orgbase: 0x%x" % seg.orgbase)
        print(" - flags: 0x%x" % seg.flags)
        print(" - align: 0x%x" % seg.align)
        print(" - comb: 0x%x" % seg.comb)
        print(" - perm: 0x%x" % seg.perm)
        print(" - bitness: 0x%x" % seg.bitness)
        print(" - sel: 0x%x" % seg.sel)
        # print(' - defsr: 0x%x' % seg.defsr)
        print(" - type: 0x%x" % seg.type)
        print(" - color: 0x%x" % seg.color) 
Example #2
Source Project: idasec   Author: RobinDavid   File: configuration_file.py    License: GNU Lesser General Public License v2.1 6 votes vote down vote up
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) 
Example #3
Source Project: idasec   Author: RobinDavid   File: generic_analysis.py    License: GNU Lesser General Public License v2.1 6 votes vote down vote up
def post_analysis_stuff(self, results):
        if results.has_formula():
            self.action_selector.addItem(self.parent.HIGHLIGHT_CODE)
            self.action_selector.addItem(self.parent.GRAPH_DEPENDENCY)
            self.formula_area.setText(self.parent.results.formula)
        if results.has_values():
            self.action_selector.addItem(self.parent.DISASS_UNKNOWN_TARGET)
        self.action_selector.setEnabled(True)
        self.action_button.setEnabled(True)

        report = HTMLReport()
        report.add_title("Results", size=3)
        report.add_table_header(["address", "assertion", "status", "values"])
        addr = make_cell("%x" % results.target)
        status = make_cell(results.get_status(), color=results.color, bold=True)
        vals = ""
        for value in results.values:
            flag = idc.GetFlags(value)
            typ = self.type_to_string(flag)
            vals += "%x type:%s seg:%s fun:%s<br/>" % (value, typ, idc.SegName(value), idc.GetFunctionName(value))
        report.add_table_line([addr, make_cell(cgi.escape(results.query)), status, make_cell(vals)])
        report.end_table()
        data = report.generate()
        self.result_area.setHtml(data) 
Example #4
Source Project: mcsema   Author: lifting-bits   File: get_cfg.py    License: Apache License 2.0 6 votes vote down vote up
def is_ELF_got_pointer(ea):
  """Returns `True` if this is a pointer to a pointer stored in the
  `.got` section of an ELF binary. For example, `__gmon_start___ptr` is
  a pointer in the `.got` that will be fixed up to contain the address of
  the external function `__gmon_start__`. We don't want to treat
  `__gmon_start___ptr` as external because it is really a sort of local
  variable that will will resolve with a data cross-reference."""
  seg_name = idc.SegName(ea).lower()
  if ".got" not in seg_name:
    return False

  name = get_symbol_name(ea)
  target_ea = get_reference_target(ea)
  target_name = get_true_external_name(get_symbol_name(target_ea))

  if target_name not in name:
    return False

  return is_referenced_by(target_ea, ea) 
Example #5
Source Project: ida_kernelcache   Author: bazad   File: offset.py    License: MIT License 6 votes vote down vote up
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.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) 
Example #6
Source Project: ida_kernelcache   Author: bazad   File: stub.py    License: MIT License 6 votes vote down vote up
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) 
Example #7
Source Project: ida_kernelcache   Author: bazad   File: segment.py    License: MIT License 6 votes vote down vote up
def initialize_segments():
    """Rename the kernelcache segments in IDA according to the __PRELINK_INFO data.

    Rename the kernelcache segments based on the contents of the __PRELINK_INFO dictionary.
    Segments are renamed according to the scheme '[<kext>:]<segment>.<section>', where '<kext>' is
    the bundle identifier if the segment is part of a kernel extension. The special region
    containing the Mach-O header is renamed '[<kext>:]<segment>.HEADER'.
    """
    # First rename the kernel segments.
    _log(1, 'Renaming kernel segments')
    kernel_skip = ['__PRELINK_TEXT', '__PLK_TEXT_EXEC', '__PRELINK_DATA', '__PLK_DATA_CONST']
    _initialize_segments_in_kext(None, kernel.base, skip=kernel_skip)
    # Process each kext identified by the __PRELINK_INFO. In the new kernelcache format 12-merged,
    # the _PrelinkExecutableLoadAddr key is missing for all kexts, so no extra segment renaming
    # takes place.
    prelink_info_dicts = kernel.prelink_info['_PrelinkInfoDictionary']
    for kext_prelink_info in prelink_info_dicts:
        kext = kext_prelink_info.get('CFBundleIdentifier', None)
        mach_header = kext_prelink_info.get('_PrelinkExecutableLoadAddr', None)
        if kext is not None and mach_header is not None:
            orig_kext = idc.SegName(mach_header).split(':', 1)[0]
            if '.kpi.' not in kext and orig_kext != kext:
                _log(0, 'Renaming kext {} -> {}', orig_kext, kext)
            _log(1, 'Renaming segments in {}', kext)
            _initialize_segments_in_kext(kext, mach_header) 
Example #8
Source Project: ida_kernelcache   Author: bazad   File: segment.py    License: MIT License 6 votes vote down vote up
def kernelcache_kext(ea):
    """Return the name of the kext to which the given linear address belongs.

    Only works if segments have been renamed using initialize_segments().

    NOTE: Kexts are not well distinguished on the new iOS 12 merged kernelcache format. Do not rely
    on this function.
    """
    # TODO: This doesn't work on 12-merged kernelcaches!
    name = idc.SegName(ea) or ''
    if ':' in name:
        return idc.SegName(ea).split(':', 1)[0]
    if _kext_regions:
        for start, end, kext in _kext_regions:
            if start <= ea < end:
                return kext
    return None 
Example #9
Source Project: lua_re   Author: feicong   File: luac_proc.py    License: GNU Affero General Public License v3.0 5 votes vote down vote up
def init_seginfo(self):
        #print("seg len:%d\n" % len(list(idautils.Segments())))
        for seg in idautils.Segments():
            segname = idc.SegName(seg)
            if segname.startswith('func_'):
                self.segstarts[idc.SegStart(seg)] = segname
                self.segends[idc.SegEnd(seg)] = segname
                #print("segname:%s\n" % segname)
                #print("add_func() called ret:%d" % add_func(idc.SegStart(seg), idc.SegEnd(seg))) 
Example #10
Source Project: idasec   Author: RobinDavid   File: idasec_core.py    License: GNU Lesser General Public License v2.1 5 votes vote down vote up
def update_mapping(self):
        pass
        self.fun_mapping = {idc.GetFunctionName(x): (idaapi.get_func(x).startEA, idaapi.get_func(x).endEA-1) for x in
                            idautils.Functions()}
        self.seg_mapping = {idc.SegName(x): (idc.SegStart(x), idc.SegEnd(x)) for x in idautils.Segments()} 
Example #11
Source Project: idawilli   Author: williballenthin   File: yara_fn.py    License: Apache License 2.0 5 votes vote down vote up
def get_segments():
    '''
    fetch the segments in the current executable.
    '''
    for segstart in idautils.Segments():
         segend = idaapi.getseg(segstart).end_ea
         segsize = segend - segstart
         segname = str(idc.SegName(segstart)).rstrip('\x00')
         segbuf = get_segment_buffer(segstart)
         yield Segment(segstart, segend, segname, segbuf) 
Example #12
Source Project: mcsema   Author: lifting-bits   File: util.py    License: Apache License 2.0 5 votes vote down vote up
def is_tls_segment(ea):
  try:
    seg_name = idc.SegName(ea)
    return seg_name in (".tbss", ".tdata", ".tls")
  except:
    return False

# Returns `True` if `ea` looks like a thread-local thing. 
Example #13
Source Project: mcsema   Author: lifting-bits   File: util.py    License: Apache License 2.0 5 votes vote down vote up
def segment_contains_external_function_pointers(seg_ea):
  """Returns `True` if a segment contains pointers to external functions."""
  try:
    seg_name = idc.SegName(seg_ea)
    return seg_name.lower() in (".idata", ".plt.got")
  except:
    return False 
Example #14
Source Project: mcsema   Author: lifting-bits   File: util.py    License: Apache License 2.0 5 votes vote down vote up
def is_external_segment(ea):
  """Returns `True` if the segment containing `ea` looks to be solely containing
  external references."""
  global _NOT_EXTERNAL_SEGMENTS

  seg_ea = idc.SegStart(ea)
  if seg_ea in _NOT_EXTERNAL_SEGMENTS:
    return False

  if seg_ea in _EXTERNAL_SEGMENTS:
    return True

  if is_external_segment_by_flags(ea):
    _EXTERNAL_SEGMENTS.add(seg_ea)
    return True

  ext_types = []
  seg_name = idc.SegName(seg_ea).lower()
  
  if IS_ELF:
    if ".got" in seg_name or ".plt" in seg_name:
      _EXTERNAL_SEGMENTS.add(seg_ea)
      return True

  elif IS_PE:
    if ".idata" == seg_name:  # Import table.
      _EXTERNAL_SEGMENTS.add(seg_ea)
      return True

  _NOT_EXTERNAL_SEGMENTS.add(seg_ea)
  return False 
Example #15
Source Project: mcsema   Author: lifting-bits   File: util.py    License: Apache License 2.0 5 votes vote down vote up
def is_constructor_segment(ea):
  """Returns `True` if the segment containing `ea` belongs to global constructor section"""
  seg_ea = idc.SegStart(ea)
  seg_name = idc.SegName(seg_ea).lower()
  if seg_name in [".init_array", ".ctor"]:
    return True
  return False 
Example #16
Source Project: mcsema   Author: lifting-bits   File: util.py    License: Apache License 2.0 5 votes vote down vote up
def is_destructor_segment(ea):
  """Returns `True` if the segment containing `ea` belongs to global destructor section"""
  seg_ea = idc.SegStart(ea)
  seg_name = idc.SegName(seg_ea).lower()
  if seg_name in [".fini_array", ".dtor"]:
    return True
  return False 
Example #17
Source Project: mcsema   Author: lifting-bits   File: exception.py    License: Apache License 2.0 5 votes vote down vote up
def recover_frame_entries(seg_ea):
  if seg_ea == idc.BADADDR:
    return

  DEBUG("Recover entries from section : {}".format(idc.SegName(seg_ea)))
  ea = idc.SegStart(seg_ea)
  end_ea = idc.SegEnd(seg_ea)
  while ea != idc.BADADDR and ea < end_ea:
    ea = format_entries(ea) 
Example #18
Source Project: mcsema   Author: lifting-bits   File: exception.py    License: Apache License 2.0 5 votes vote down vote up
def recover_exception_table():
  """ Recover the CIE and FDE entries from the segment .eh_frame
  """
  seg_eas = [ea for ea in idautils.Segments() if not is_invalid_ea(ea)]
  
  for seg_ea in seg_eas:
    seg_name = idc.SegName(seg_ea)
    if seg_name in [".eh_frame", "__eh_frame"]:
      recover_frame_entries(seg_ea)
      break

  recover_rtti() 
Example #19
Source Project: mcsema   Author: lifting-bits   File: get_cfg.py    License: Apache License 2.0 5 votes vote down vote up
def recover_region(M, region_name, region_ea, region_end_ea, exported_vars):
  """Recover the data and cross-references from a segment. The data of a
  segment is stored verbatim within the protobuf, and accompanied by a
  series of variable and cross-reference entries."""

  seg_name = idc.SegName(region_ea)

  DEBUG("Recovering region {} [{:x}, {:x}) in segment {}".format(
      region_name, region_ea, region_end_ea, seg_name))

  seg = idaapi.getseg(region_ea)

  # An item spans two regions. This may mean that there's a reference into
  # the middle of an item. This happens with strings.
  item_size = idc.ItemSize(region_end_ea - 1)
  if 1 < item_size:
    DEBUG("  ERROR: Segment should probably include {} more bytes".format(
        item_size - 1))

  S = M.segments.add()
  S.ea = region_ea
  S.data = read_bytes_slowly(region_ea, region_end_ea)
  S.read_only = (seg.perm & idaapi.SEGPERM_WRITE) == 0
  S.is_external = is_external_segment_by_flags(region_ea)
  S.is_thread_local = is_tls_segment(region_ea)
  S.name = seg_name.format('utf-8')
  S.is_exported = region_ea in exported_vars

  if region_name != seg_name:
    S.variable_name = region_name.format('utf-8')

  DEBUG_PUSH()
  recover_region_cross_references(M, S, region_ea, region_end_ea)
  recover_region_variables(M, S, region_ea, region_end_ea, exported_vars)
  DEBUG_POP() 
Example #20
Source Project: DIE   Author: ynvb   File: IDAConnector.py    License: MIT License 5 votes vote down vote up
def is_system_lib(ea):
    """
    Returns true if a segment belongs to a system library, in which case we don't want to recursively hook calls.
    Covers Windows, Linux, Mac, Android, iOS
    @param ea: an effective address within a function
    """

    name = idc.SegName(ea)

    if not name:
        return False

    # the below is for Windows kernel debugging
    if name == 'nt':
        return True

    sysfolders = [re.compile("\\\\windows\\\\", re.I), re.compile("\\\\Program Files ", re.I), re.compile("/usr/", re.I), \
                  re.compile("/system/", re.I), re.compile("/lib/", re.I)]

    m = idc.GetFirstModule()
    while m:
        path = idc.GetModuleName(m)
        if re.search(name, path):
            if any(regex.search(path) for regex in sysfolders):
                return True
            else:
                return False
        m = idc.GetNextModule(m)

    return False 
Example #21
Source Project: ida_kernelcache   Author: bazad   File: collect_classes.py    License: MIT License 5 votes vote down vote up
def _process_mod_init_func_for_metaclasses(func, found_metaclass):
    """Process a function from the __mod_init_func section for OSMetaClass information."""
    _log(4, 'Processing function {}', idc.GetFunctionName(func))
    def on_BL(addr, reg):
        X0, X1, X3 = reg['X0'], reg['X1'], reg['X3']
        if not (X0 and X1 and X3):
            return
        _log(5, 'Have call to {:#x}({:#x}, {:#x}, ?, {:#x})', addr, X0, X1, X3)
        # OSMetaClass::OSMetaClass(this, className, superclass, classSize)
        if not idc.SegName(X1).endswith("__TEXT.__cstring") or not idc.SegName(X0):
            return
        found_metaclass(X0, idc.GetString(X1), X3, reg['X2'] or None)
    _emulate_arm64(func, idc.FindFuncEnd(func), on_BL=on_BL) 
Example #22
Source Project: ida_kernelcache   Author: bazad   File: collect_classes.py    License: MIT License 5 votes vote down vote up
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.SegName(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 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 
Example #23
Source Project: ida_kernelcache   Author: bazad   File: offset.py    License: MIT License 5 votes vote down vote up
def initialize_offset_symbols():
    """Populate IDA with information about the offsets in an iOS kernelcache.

    Search through the kernelcache for global offset tables (__got sections), convert each offset
    into an offset type in IDA, and rename each offset according to its target.

    This function does nothing in the newer 12-merged format kernelcache.
    """
    next_offset = internal.make_name_generator(kernelcache_offset_suffix)
    for ea in idautils.Segments():
        segname = idc.SegName(ea)
        if not segname.endswith('__got'):
            continue
        _log(2, 'Processing segment {}', segname)
        _process_offsets_section(ea, next_offset) 
Example #24
Source Project: python-idb   Author: williballenthin   File: yara_fn.py    License: Apache License 2.0 5 votes vote down vote up
def get_segments():
    """
    fetch the segments in the current executable.
    """
    for segstart in idautils.Segments():
        segend = idaapi.getseg(segstart).endEA
        segsize = segend - segstart
        segname = str(idc.SegName(segstart)).rstrip("\x00")
        segbuf = get_segment_buffer(segstart)
        yield Segment(segstart, segend, segname, segbuf) 
Example #25
Source Project: flare-ida   Author: fireeye   File: objc2_xrefs_helper.py    License: Apache License 2.0 5 votes vote down vote up
def find_all_segments(self,segment_names):
        segments={name:None for name in segment_names}
        for seg_va in Segments():
            seg_name=SegName(seg_va)
            if seg_name in segment_names:
                segments[seg_name]=(seg_va,SegEnd(seg_va))
        return segments 
Example #26
Source Project: flare-ida   Author: fireeye   File: __init__.py    License: Apache License 2.0 5 votes vote down vote up
def append_segment(segment_name):
    """ Add a new segment to the IDB file and return its starting address.
    Information about function arguments will be stored here. Only works if the
    segment name is not used yet. This does not affect the original binary.

    Arguments:
    segment_name -- the name of the segment to be added
    """
    for segment in idautils.Segments():
        if idc.SegName(segment) == segment_name:
            g_logger.warning('Segment ' + segment_name + ' already exists')
            return idc.SegStart(segment)

    new_segment_start = get_end_of_last_segment()
    g_logger.debug('Adding new segment at 0x%08x' % new_segment_start)
    if not idc.AddSeg(new_segment_start, (new_segment_start+NEW_SEGMENT_SIZE),
                      0, 1, 0, idaapi.scPub) == 1:
        raise FailedToAppendSegmentException('Could not add segment')
    # set new segment's attributes
    if not idc.RenameSeg(new_segment_start, segment_name):
        raise FailedToAppendSegmentException('Could not rename segment')
    if not idc.SetSegClass(new_segment_start, 'DATA'):
        raise FailedToAppendSegmentException('Could not set segment class')
    if not idc.SegAlign(new_segment_start, idc.saRelPara):
        raise FailedToAppendSegmentException('Could not align segment')
    if not idc.SetSegAddressing(new_segment_start, 1):  # 1 -- 32 bit
        raise FailedToAppendSegmentException(
            'Could not set segment addressing')
    return new_segment_start 
Example #27
Source Project: dsc_fix   Author: deepinstinct   File: dsc_fix.py    License: GNU General Public License v3.0 5 votes vote down vote up
def make_islands_xrefs_force_bl_call(ea, verbose=True):
    """ makes all BL references to a branch islands as call """
    segname = idc.SegName(ea)
    if verbose:
        print "[+] forcing bl call on: %s [0x%X]" % (segname, ea)
    if "branch_islands" in segname:
        idc.SetFunctionFlags(ea, idc.GetFunctionFlags(ea) & (0xffffffff - 1))
        for x in idautils.XrefsTo(ea):
            make_islands_xrefs_force_bl_call(x.frm)
        return
    idc.ArmForceBLCall(ea) 
Example #28
Source Project: dsc_fix   Author: deepinstinct   File: dsc_fix.py    License: GNU General Public License v3.0 5 votes vote down vote up
def label_and_fix_branch_islands(dsc_file, adrfind, jmp_to_code):
    """ labels, comments and fixes code flow on branch islands """
    jmpaddrs = sorted(set(jmp_to_code.keys()))
    dsc_file.seek(0)
    header = dsc_header(dsc_file)
    dsc_file.seek(header.images_offset)
    i = 0
    jmpaddrslen = len(jmpaddrs)
    for addr in jmpaddrs:
        print "status: 0x%X %d/%d" % (addr, i, jmpaddrslen)
        res = adrfind.find(addr)
        if not res:
            print "[!] coudln't find addr for addr:", addr
        dylib_path, dsc_offset, macho_offset = res
        exportname = adrfind.get_export_name_for_addr(addr)
        if _IN_IDA:
            eas = jmp_to_code[addr]
            for ea in eas:
                idc.MakeRptCmt(ea, "%s'%s" % (dylib_path, exportname))
                if "branch_islands" in idc.SegName(ea):
                    make_name(ea, exportname)
                    # patch them to "RET" so they would return
                    memcpy(ea, "\xC0\x03\x5F\xD6")
                    make_islands_xrefs_force_bl_call(ea)
        else:
            print "[+] \\\\ %s" % exportname
        i += 1 
Example #29
Source Project: mcsema   Author: lifting-bits   File: get_cfg.py    License: Apache License 2.0 4 votes vote down vote up
def is_ELF_thunk_by_structure(ea):
  """Try to manually identify an ELF thunk by its structure."""
  global _INVALID_THUNK_ADDR

  if ".plt" not in idc.SegName(ea).lower():
    return _INVALID_THUNK_ADDR

  # Scan through looking for a branch, either direct or indirect.
  inst = None
  for i in range(4):  # 1 is good enough for x86, 4 for aarch64.
    inst, _ = decode_instruction(ea)
    if not inst:
      return _INVALID_THUNK_ADDR
    # elif is_direct_jump(inst):
    #   ea = get_direct_branch_target(inst)
    #   inst = None
    elif is_indirect_jump(inst) or is_direct_jump(inst):
      ea = inst.ea
      break
    else:
      ea = inst.ea + inst.size
      inst = None

  if not inst:
    return _INVALID_THUNK_ADDR

  target_ea = get_reference_target(inst.ea)
  if ".got.plt" == idc.SegName(target_ea).lower():
    target_ea = get_reference_target(target_ea)

  # For AArch64, the thunk structure is something like:
  #     .plt:000400470 .atoi
  #     .plt:000400470    ADRP            X16, #off_411000@PAGE
  #     .plt:000400474    LDR             X17, [X16,#off_411000@PAGEOFF]
  #     .plt:000400478    ADD             X16, X16, #off_411000@PAGEOFF
  #     .plt:00040047C    BR              X17 ; atoi
  #
  # With:
  #
  #     extern:000411070 ; int atoi(const char *nptr)
  #     extern:000411070                 IMPORT atoi
  

  # For x86, the thunk structure is something like:
  #   
  #     .plt:00041F10 _qsort      proc near         
  #     .plt:00041F10         jmp   cs:off_31F388
  #     .plt:00041F10 _qsort      endp
  #     
  # With:
  # 
  #     .got.plt:0031F388 off_31F388    dq offset qsort
  #
  # With
  #     extern:0031F388 ; void qsort(void *base, ...)
  #     extern:0031F388                 extrn qsort:near 

  if is_invalid_ea(target_ea):
    return _INVALID_THUNK_ADDR
  
  return True, target_ea 
Example #30
Source Project: ida_kernelcache   Author: bazad   File: segment.py    License: MIT License 4 votes vote down vote up
def _initialize_segments_in_kext(kext, mach_header, skip=[]):
    """Rename the segments in the specified kext."""
    def log_seg(segname, segstart, segend):
        _log(3, '+ segment {: <20} {:x} - {:x}  ({:x})', segname, segstart, segend,
            segend - segstart)
    def log_sect(sectname, sectstart, sectend):
        _log(3, '  section {: <20} {:x} - {:x}  ({:x})', sectname, sectstart, sectend,
                sectend - sectstart)
    def log_gap(gapno, start, end, mapped):
        mapped = 'mapped' if mapped else 'unmapped'
        _log(3, '  gap     {: <20} {:x} - {:x}  ({:x}, {})', gapno, start, end,
            end - start, mapped)
    def process_region(segname, name, start, end):
        assert end >= start
        if segname in skip:
            _log(2, 'Skipping segment {}', segname)
            return
        newname = '{}.{}'.format(segname, name)
        if kext:
            newname = '{}:{}'.format(kext, newname)
        if start == end:
            _log(2, 'Skipping empty region {} at {:x}', newname, start)
            return
        ida_segstart = idc.SegStart(start)
        if ida_segstart == idc.BADADDR:
            _log(0, "IDA doesn't think this is a real segment: {:x} - {:x}", start, end)
            return
        ida_segend = idc.SegEnd(ida_segstart)
        if start != ida_segstart or end != ida_segend:
            _log(0, 'IDA thinks segment {} {:x} - {:x} should be {:x} - {:x}', newname, start, end,
                    ida_segstart, ida_segend)
            return
        _log(2, 'Rename {:x} - {:x}: {} -> {}', start, end, idc.SegName(start), newname)
        idc.SegRename(start, newname)
    def process_gap(segname, gapno, start, end):
        mapped = idau.is_mapped(start)
        log_gap(gapno, start, end, mapped)
        if mapped:
            name = 'HEADER' if start == mach_header else '__gap_' + str(gapno)
            process_region(segname, name, start, end)
    for segname, segstart, segend, sects in _macho_segments_and_sections(mach_header):
        log_seg(segname, segstart, segend)
        lastend = segstart
        gapno   = 0
        for sectname, sectstart, sectend in sects:
            if lastend < sectstart:
                process_gap(segname, gapno, lastend, sectstart)
                gapno += 1
            log_sect(sectname, sectstart, sectend)
            process_region(segname, sectname, sectstart, sectend)
            lastend = sectend
        if lastend < segend:
            process_gap(segname, gapno, lastend, segend)
            gapno += 1