Exemple #1
0
def is_ELF_thunk_by_structure(ea):
    """Try to manually identify an ELF thunk by its structure."""
    from util import *
    global _INVALID_THUNK_ADDR
    inst = None

    for i in range(4):  # 1 is good enough for x86, 4 for aarch64.
        inst, _ = decode_instruction(ea)
        if not inst:
            break
        # elif is_direct_jump(inst):
        #   ea = get_direct_branch_target(inst)
        #   inst = None
        if is_indirect_jump(inst) or is_direct_jump(inst):
            target_ea = get_reference_target(inst.ea)
            if not is_invalid_ea(target_ea):
                seg_name = idc.get_segm_name(target_ea).lower()
                if ".got" in seg_name or ".plt" in seg_name:
                    target_ea = get_reference_target(target_ea)
                    seg_name = idc.get_segm_name(target_ea).lower()

                if "extern" == seg_name:
                    return True, target_ea

        ea = inst.ea + inst.size

    return _INVALID_THUNK_ADDR
Exemple #2
0
    def calc_pe_size(self, image_base):
        # Blind guess at PE size based on contigious segments
        size = idc.get_segm_end(image_base) - image_base
        prev = idc.get_segm_start(image_base)
        offset = idc.get_next_seg(image_base)

        if offset == ida_idaapi.BADADDR:
            size = 0

        # Size based on contigious segments by address
        while offset != ida_idaapi.BADADDR and idc.get_segm_end(
                prev) == offset:
            size += idc.get_segm_end(offset) - offset
            prev = offset
            offset = idc.get_next_seg(offset)

        if size <= 0x1000:
            name = idc.get_segm_name(image_base)
            prev = idc.get_segm_start(image_base)
            offset = idc.get_next_seg(image_base)
            start = offset

            # Size based on contigious segments by name
            while offset != ida_idaapi.BADADDR and idc.get_segm_name(
                    prev) == name:
                prev = offset
                offset = idc.get_next_seg(offset)

            size = idc.get_segm_end(offset) - start

        self.ret = size
        return self.ret
Exemple #3
0
def fromDataToFunc(ea, deep):
    if deep > 5:
        print('No Xref function is found ' + hex(ea))
        return []
    funcs = []
    refs = idautils.DataRefsTo(ea)
    for r in refs:
        if idc.get_segm_name(r) == '.text':
            funcs.append(idc.get_func_attr(r, idc.FUNCATTR_START))
        elif idc.get_segm_name(r) == '.data' or idc.get_segm_name(r) == '.bss':
            # orign = r
            # r = r-1
            cnt = 1
            while not idc.get_name(r):
                r -= 1
                cnt += 1
                if cnt > 100:
                    print('cannot find a real label in .data' + hex(ea))
                    break
            if cnt < 100:
                funcs = funcs + fromDataToFunc(r, deep + 1)
        else:
            print("Ref in Seg {} at Addr {}".format(idc.get_segm_name(r), r))

    if not funcs:
        print('No Xref function is found ' + hex(ea))
    return funcs
Exemple #4
0
def parse_strings():
    strings_added = 0
    retry = []
    text_seg = common.get_text_seg()
    if text_seg is None:
        common._debug('Failed to get text segment')
        return strings_added

    # This may be inherently flawed as it will only search for defined functions
    # and as of IDA Pro 6.95 it fails to autoanalyze many GO functions, currently
    # this works well since we redefine/find (almost) all the functions prior to
    # this being used. Could be worth a strategy rethink later one or on diff archs
    for addr in idautils.Functions(text_seg.startEA, text_seg.endEA):
        name = idc.GetFunctionName(addr)

        end_addr = idautils.Chunks(addr).next()[1]
        if (end_addr < addr):
            common._error('Unable to find good end for the function %s' % name)
            pass

        common._debug('Found function %s starting/ending @ 0x%x 0x%x' %
                      (name, addr, end_addr))

        while addr <= end_addr:
            if parse_str_ptr(addr):
                strings_added += 1
                addr = idc.FindCode(addr, idaapi.SEARCH_DOWN)
            elif is_string_patt(addr):
                if 'rodata' not in idc.get_segm_name(
                        addr) and 'text' not in idc.get_segm_name(addr):
                    common._debug('Should a string be in the %s section?' %
                                  idc.get_segm_name(addr))
                string_addr = idc.GetOperandValue(addr, 1)
                addr_3 = idc.FindCode(idc.FindCode(addr, idaapi.SEARCH_DOWN),
                                      idaapi.SEARCH_DOWN)
                string_len = idc.GetOperandValue(addr_3, 1)
                if string_len > 1:
                    if create_string(string_addr, string_len):
                        if create_offset(addr):
                            strings_added += 1
                    else:
                        # There appears to be something odd that goes on with IDA making some strings, always works
                        # the second time, so lets just force a retry...
                        retry.append((addr, string_addr, string_len))

                # Skip the extra mov lines since we know it won't be a load on any of them
                addr = idc.FindCode(addr_3, idaapi.SEARCH_DOWN)
            else:
                addr = idc.FindCode(addr, idaapi.SEARCH_DOWN)

    for instr_addr, string_addr, string_len in retry:
        if create_string(string_addr, string_len):
            if create_offset(instr_addr):
                strings_added += 1
        else:
            common._error(
                'Unable to make a string @ 0x%x with length of %d for usage in function @ 0x%x'
                % (string_addr, string_len, instr_addr))

    return strings_added
Exemple #5
0
 def BL(self, bl_addr):
     # OSMetaClass::OSMetaClass(this, className, superclass, classSize)
     X0, X1, X3 = (self.regs[n] for n in ('X0', 'X1', 'X3'))
     if (X0 and X1 and X3
             and idc.get_segm_name(X1).endswith("__cstring")
             and idc.get_segm_name(X0)):
         found_metaclass(X0, idc.get_strlit_contents(X1))
Exemple #6
0
def is_ELF_thunk_by_structure(ea):
    """Try to manually identify an ELF thunk by its structure."""
    from util import *
    global _INVALID_THUNK_ADDR

    seg_name = idc.get_segm_name(ea).lower()
    if ".plt" not in seg_name:
        return _INVALID_THUNK_ADDR

    inst, _ = decode_instruction(ea)
    if not inst or not (is_indirect_jump(inst) or is_direct_jump(inst)):
        return _INVALID_THUNK_ADDR

    target_ea = get_reference_target(inst.ea)
    if is_invalid_ea(target_ea):
        return _INVALID_THUNK_ADDR

    seg_name = idc.get_segm_name(target_ea).lower()
    if ".got" in seg_name or ".plt" in seg_name:
        target_ea = get_reference_target(target_ea)
        seg_name = idc.get_segm_name(target_ea).lower()

    if "extern" == seg_name:
        return True, target_ea

    return _INVALID_THUNK_ADDR
Exemple #7
0
    def find_pe(self, cursor=False):
        """Search IDB for possible MZ/PE headers"""
        info = idaapi.get_inf_structure()

        mz_headers = []

        # Check current cursor for MZ/PE?
        if cursor:
            # Get IDA cursor address
            addr = idc.here()

            # Get segment and end address
            s = idaapi.getseg(addr)
            e = idc.get_segm_end(addr)

            # 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 header
                        mz_headers.append([addr, idc.get_segm_name(addr), info.is_64bit()])

            self.ret = mz_headers
            return self.ret

        # 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 header
                            mz_headers.append([addr, idc.get_segm_name(s), info.is_64bit()])

                # Resume search from next address
                addr += 1

        self.ret = mz_headers
        return self.ret
Exemple #8
0
 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.get_segm_name(X1).endswith(
             "__TEXT.__cstring") or not idc.get_segm_name(X0):
         return
     found_metaclass(X0, ida_bytes.get_strlit_contents(X1), X3, reg['X2']
                     or None)
Exemple #9
0
    def get_global_seg_start(self, segs_name):
        global_seg_start = {}
        for seg in idautils.Segments():
            if idc.get_segm_name(seg) in segs_name:
                global_seg_start[idc.get_segm_name(seg)] = seg

        if not '.roooodata' in global_seg_start:
            start, _ = self.add_rodata_segment()
            global_seg_start['.roooodata'] = start
        self.global_seg_start = global_seg_start
        return global_seg_start
Exemple #10
0
def getSegAddr():
    textStart=0
    textEnd=0
    end = 0
    for seg in idautils.Segments():
        if (idc.get_segm_name(seg)).lower()=='.text' or (idc.get_segm_name(seg)).lower()=='text':
            textStart=idc.get_segm_start(seg)
            textEnd=idc.get_segm_end(seg)
        tmp = idc.get_segm_end(seg)
        if end < tmp:
            end = tmp
    return textStart,textEnd,end
Exemple #11
0
    def bin_info(self, node_title, chunk_addr, chunk, with_size=True):
        line =  idaapi.COLSTR("%s " % node_title, idaapi.SCOLOR_NUMBER)
        line += idaapi.COLSTR("0x%x\n\n" % chunk_addr, idaapi.SCOLOR_INSN)

        chunk_info = ""
        if with_size:
            chunk_info += "size: 0x%x\n" % chunk.size

        chunk_info += "fd: 0x%x - %s\nbk: 0x%x - %s" % (chunk.fd, \
            idc.get_segm_name(chunk.fd), chunk.bk, idc.get_segm_name(chunk.bk))

        line += idaapi.COLSTR(chunk_info, idaapi.SCOLOR_DEFAULT)
        return line
Exemple #12
0
def getSegAddr():
    textStart = []
    textEnd = []

    for seg in idautils.Segments():
        if (idc.get_segm_name(seg)).lower() == '.text' or (
                idc.get_segm_name(seg)).lower() == 'text':
            tempStart = idc.get_segm_start(seg)
            tempEnd = idc.get_segm_end(seg)

            textStart.append(tempStart)
            textEnd.append(tempEnd)

    return min(textStart), max(textEnd)
Exemple #13
0
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.get_segm_name(segment) == segment_name:
            g_logger.warning('Segment ' + segment_name + ' already exists')
            return idc.get_segm_start(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.set_segm_name(new_segment_start, segment_name):
        raise FailedToAppendSegmentException('Could not rename segment')
    if not idc.set_segm_class(new_segment_start, 'DATA'):
        raise FailedToAppendSegmentException('Could not set segment class')
    if not idc.set_segm_alignment(new_segment_start, idc.saRelPara):
        raise FailedToAppendSegmentException('Could not align segment')
    if not idc.set_segm_addressing(new_segment_start, 1):  # 1 -- 32 bit
        raise FailedToAppendSegmentException(
            'Could not set segment addressing')
    return new_segment_start
Exemple #14
0
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.get_segm_name(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)
Exemple #15
0
  def get_segments_memory(self):
    memory = b""
    step_size = self.entropy_cfg['step_size']
    segments  = OrderedDict()

    for ea in filter(self.segment_filter, idautils.Segments()):
      seg_name = idc.get_segm_name(ea)
      segm  = idaapi.get_segm_by_name(seg_name)
      data = idaapi.get_bytes(segm.start_ea, segm.size())
      assert len(data) == segm.size()

      start_offset = len(memory)
      end_offset   = (start_offset+len(data))

      seg_info = {
        'segm': segm,
        'entropy': entropy(data),
        'offsets': [
          start_offset ,
          end_offset
        ],
        'chart_offsets': [
          start_offset // step_size,
          end_offset // step_size
        ]
      }
      segments[seg_name] = seg_info
      memory += data

    self.data = memory
    self.data_size = len(memory)
    self.segments = segments
Exemple #16
0
def get_header_idb():
    """get file header from idb"""
    if idc.get_segm_name(0) == "HEADER":
        header = bytearray(
            [idc.get_wide_byte(ea) for ea in range(0, idc.get_segm_end(0))])
        return header
    return bytearray(b"")
Exemple #17
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
def method_list(ea):
    if not ea:
        return

    count = ida_bytes.get_dword(ea + 4)
    name = idc.get_segm_name(ea)
    first = ea + 8

    def post14format(addr):
        for _ in range(3):
            data = ida_bytes.get_bytes(addr, 4)
            offset, = struct.unpack('<i', data)
            yield addr + offset
            addr += 4
        
    is14 = name and (name.endswith(':__objc_const_ax') or name.endswith(':__objc_methlist'))
    for i in range(count):
        if is14:
            # iOS 14
            yield Post14Method(*post14format(first + i * 12))

        else:
            ea_method_t = first + i * Objc2Method.length
            data = ida_bytes.get_bytes(ea_method_t, Objc2Method.length)
            yield Objc2Method(data)
Exemple #19
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:
                            common._error(
                                'Failed to name pointer @ 0x%02x for %s' %
                                (data_ref, name))

                data_ref = idaapi.get_next_dref_to(addr, data_ref)

    common._info("\nRename %d function pointers.\n" % renamed)
Exemple #20
0
def get_value_type(ea):
    addr_type = T_VALUE

    if not idaapi.is_loaded(ea):
        return addr_type

    segm_name = idc.get_segm_name(ea)
    segm = idaapi.getseg(ea)
    flags = idc.get_full_flags(ea)
    is_code = idc.is_code(flags)

    if "stack" in segm_name.lower() or \
    (dbg.stack_segm and dbg.stack_segm.start_ea == segm.start_ea):
        addr_type = T_STACK

    elif "heap" in segm_name.lower():
        addr_type = T_HEAP

    elif not is_code and segm.perm & idaapi.SEGPERM_READ and \
    segm.perm & idaapi.SEGPERM_WRITE and \
    segm.perm & idaapi.SEGPERM_EXEC:
        addr_type = T_RWX

    elif is_code or \
    (segm.perm & idaapi.SEGPERM_READ and segm.perm & idaapi.SEGPERM_EXEC):
        addr_type = T_CODE

    elif segm.perm & idaapi.SEGPERM_READ and \
    segm.perm & idaapi.SEGPERM_WRITE:
        addr_type = T_DATA

    elif segm.perm & idaapi.SEGPERM_READ:
        addr_type = T_RODATA

    return addr_type
 def get_data_refs(self):
     xrefs = list(idautils.XrefsTo(self.addr))
     return len([
         x for x in xrefs
         if (x.type == idautils.ida_xref.dr_O
             and 'data' in idc.get_segm_name(x.frm).lower())
     ])
Exemple #22
0
    def __init__(self, show_extra_fields):
        self.addr = None
        self.flags = None
        self.show_extra_fields = show_extra_fields
        self.names = [
            'Name', 'Address', 'Segment', 'Length', 'Locals', 'Arguments'
        ]

        self.handlers = {
            0: lambda: None,
            1: lambda: self.fmt(self.addr),
            2: lambda: '{}'.format(idc.get_segm_name(self.addr)),
            3: lambda: self.fmt(idc.get_func_attr(self.addr, idc.FUNCATTR_END) - self.addr),
            4: lambda: self.fmt(idc.get_func_attr(self.addr, idc.FUNCATTR_FRSIZE)),
            5: lambda: self.fmt(idc.get_func_attr(self.addr, idc.FUNCATTR_ARGSIZE))
        }

        if self.show_extra_fields:
            self.names.extend(['R', 'F', 'L', 'S', 'B', 'T', '='])
            # TODO: add Lumina column info
            self.handlers.update({
                6:  lambda: self.is_true(not self.flags & idc.FUNC_NORET, 'R'),
                7:  lambda: self.is_true(self.flags & idc.FUNC_FAR, 'F'),
                8:  lambda: self.is_true(self.flags & idc.FUNC_LIB, 'L'),
                9:  lambda: self.is_true(self.flags & idc.FUNC_STATIC, 'S'),
                10: lambda: self.is_true(self.flags & idc.FUNC_FRAME, 'B'),
                11: lambda: self.is_true(idc.get_type(self.addr), 'T'),
                12: lambda: self.is_true(self.flags & idc.FUNC_BOTTOMBP, '=')
            })
Exemple #23
0
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.get_segm_start(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.get_segm_name(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
def main():
    for segstart, segend, segname in enum_segments():
        if segname not in ('.rdata', 'UPX1'):
            continue

        print(segname)
        for src, dst, size in find_pointers(segstart, segend):
            if idc.get_segm_name(dst) not in (".text", "UPX0"):
                continue

            if is_code(dst):
                continue

            print("new function pointer: 0x%x -> 0x%x" % (src, dst))

            ida_auto.auto_make_code(dst)
            ida_auto.auto_make_proc(dst)

            ida_bytes.del_items(src, size)
            ida_bytes.create_data(src,
                                  idc.FF_QWORD if size == 8 else idc.FF_DWORD,
                                  size, idc.BADADDR)
            # this doesn't seem to always work :-(
            idc.op_plain_offset(src, -1, 0)
            ida_name.set_name(src, "j_%s_%x" % (src, dst))
Exemple #25
0
def segment_contains_external_function_pointers(seg_ea):
    """Returns `True` if a segment contains pointers to external functions."""
    try:
        seg_name = idc.get_segm_name(seg_ea)
        return seg_name.lower() in (".idata", ".plt.got")
    except:
        return False
Exemple #26
0
def is_destructor_segment(ea):
  """Returns `True` if the segment containing `ea` belongs to global destructor section"""
  seg_ea = idc.get_segm_start(ea)
  seg_name = idc.get_segm_name(seg_ea).lower()
  if seg_name in [".fini_array", ".dtor"]:
    return True
  return False
Exemple #27
0
def translate_ea(offset):
    for s in idautils.Segments():
        if idc.get_segm_name(s) == ".text":
            return offset + s

    print('translate_ea fails..')
    return None
Exemple #28
0
def translate_ea_to_offset(ea):
    for s in idautils.Segments():
        if idc.get_segm_name(s) == ".text":
            return ea - s

    print('translate_ea_to_offset fails...')
    return None
Exemple #29
0
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.get_segm_start(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.get_segm_name(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
Exemple #30
0
def segment_contains_external_function_pointers(seg_ea):
  """Returns `True` if a segment contains pointers to external functions."""
  try:
    seg_name = idc.get_segm_name(seg_ea)
    return seg_name.lower() in (".idata", ".plt.got")
  except:
    return False
Exemple #31
0
def get_all_func():
    num = 0
    content = []
    for func in idautils.Functions():
        seg_perm = idc.get_segm_attr(func,SEGATTR_PERM)         # 段属性
        if(5 !=seg_perm):
            continue
        seg_name = idc.get_segm_name(func)                      # 段名
        if(".plt" == seg_name):
            continue
        
        func_name = idc.get_func_name(func)                     # 函数名
        func_flags = hex(idc.get_func_attr(func,FUNCATTR_FLAGS))# 函数信息
        func_head = hex(idc.get_func_attr(func,FUNCATTR_START)) # 函数头
        func_end = hex(idc.get_func_attr(func,FUNCATTR_END))    # 函数尾

        l = []
        l.append(num)
        l.append(seg_name)
        l.append(seg_perm)
        l.append(func_name)
        l.append(func_flags)
        l.append(func_head)
        l.append(func_end)
        content.append(l)
        
        num += 1
        #print(l)
    return content
Exemple #32
0
def is_destructor_segment(ea):
    """Returns `True` if the segment containing `ea` belongs to global destructor section"""
    seg_ea = idc.get_segm_start(ea)
    seg_name = idc.get_segm_name(seg_ea).lower()
    if seg_name in [".fini_array", ".dtor"]:
        return True
    return False
Exemple #33
0
def create_string(addr, string_len):
    # if idaapi.get_segm_name(addr) is None:
    if idc.get_segm_name(addr) is None:
        common._debug(
            'Cannot load a string which has no segment - not creating string @ 0x%02x'
            % addr)
        return False

    common._debug('Found string load @ 0x%x with length of %d' %
                  (addr, string_len))
    # This may be overly aggressive if we found the wrong area...
    if idc.GetStringType(addr) is not None and idc.GetString(
            addr) is not None and len(idc.GetString(addr)) != string_len:
        common._debug(
            'It appears that there is already a string present @ 0x%x' % addr)
        idc.MakeUnknown(addr, string_len, idc.DOUNK_SIMPLE)
        idaapi.autoWait()

    if idc.GetString(addr) is None and idc.MakeStr(addr, addr + string_len):
        idaapi.autoWait()
        return True
    else:
        # If something is already partially analyzed (incorrectly) we need to MakeUnknown it
        idc.MakeUnknown(addr, string_len, idc.DOUNK_SIMPLE)
        idaapi.autoWait()
        if idc.MakeStr(addr, addr + string_len):
            idaapi.autoWait()
            return True
        common._debug('Unable to make a string @ 0x%x with length of %d' %
                      (addr, string_len))

    return False
Exemple #34
0
def recover_frame_entries(seg_ea):
  if seg_ea == idc.BADADDR:
    return

  DEBUG("Recover entries from section : {}".format(idc.get_segm_name(seg_ea)))
  ea = idc.get_segm_start(seg_ea)
  end_ea = idc.get_segm_end(seg_ea)
  while ea != idc.BADADDR and ea < end_ea:
    ea = format_entries(ea)
Exemple #35
0
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.get_segm_name(seg_ea)
    if seg_name in [".eh_frame", "__eh_frame"]:
      recover_frame_entries(seg_ea)
      break
Exemple #36
0
def main():
    print("[*] loading crypto constants")
    for const in non_sparse_consts:
        const["byte_array"] = convert_to_byte_array(const)

    for start in idautils.Segments():
        print("[*] searching for crypto constants in %s" % idc.get_segm_name(start))
        ea = start
        while ea < idc.get_segm_end(start):
            bbbb = list(struct.unpack("BBBB", idc.get_bytes(ea, 4)))
            for const in non_sparse_consts:
                if bbbb != const["byte_array"][:4]:
                    continue
                if map(lambda x:ord(x), idc.get_bytes(ea, len(const["byte_array"]))) == const["byte_array"]:
                    print(("0x%0" + str(digits) + "X: found const array %s (used in %s)") % (ea, const["name"], const["algorithm"]))
                    idc.set_name(ea, const["name"])
                    if const["size"] == "B":
                        idc.create_byte(ea)
                    elif const["size"] == "L":
                        idc.create_dword(ea)
                    elif const["size"] == "Q":
                        idc.create_qword(ea)
                    idc.make_array(ea, len(const["array"]))
                    ea += len(const["byte_array"]) - 4
                    break
            ea += 4

        ea = start
        if idc.get_segm_attr(ea, idc.SEGATTR_TYPE) == 2:
            while ea < idc.get_segm_end(start):
                d = ida_bytes.get_dword(ea)
                for const in sparse_consts:
                    if d != const["array"][0]:
                        continue
                    tmp = ea + 4
                    for val in const["array"][1:]:
                        for i in range(8):
                            if ida_bytes.get_dword(tmp + i) == val:
                                tmp = tmp + i + 4
                                break
                        else:
                            break
                    else:
                        print(("0x%0" + str(digits) + "X: found sparse constants for %s") % (ea, const["algorithm"]))
                        cmt = idc.get_cmt(idc.prev_head(ea), 0)
                        if cmt:
                            idc.set_cmt(idc.prev_head(ea), cmt + ' ' + const["name"], 0)
                        else:
                            idc.set_cmt(idc.prev_head(ea), const["name"], 0)
                        ea = tmp
                        break
                ea += 1
    print("[*] finished")
Exemple #37
0
def is_invalid_ea(ea):
  """Returns `True` if `ea` is not valid, i.e. it doesn't point into any
  valid segment."""
  if (idc.BADADDR == ea) or \
    (idc.get_segm_name(ea) == "LOAD"):
    return True

  try:
    idc.get_segm_attr(idc.get_segm_start(ea), idc.SEGATTR_TYPE)
    return False  # If we get here, then it must be a valid ea!
  except:
    return True
Exemple #38
0
def get_destructor_segment():
  """Returns the start address of the global destructor section"""
  for seg_ea in idautils.Segments():
    seg_name = idc.get_segm_name(seg_ea).lower()
    if seg_name in [".fini_array", ".dtor"]:
      return seg_ea;
Exemple #39
0
def is_tls_segment(ea):
  try:
    seg_name = idc.get_segm_name(ea)
    return seg_name in (".tbss", ".tdata", ".tls")
  except:
    return False