Beispiel #1
0
def main():
    kbase = min(Segments())
    define_funcs = []
    define_data = []

    # Add functions
    for ea in Functions():
        fname = idc.get_name(ea)
        ftype = idc.get_type(ea)
        fslide = ea - kbase
        if fname.startswith('sub_'):
            continue
        if ftype is None:
            if TYPED_FUNCS_ONLY:
                continue
            ftype = 'uint64_t (...)'
        define_funcs.append((fname, fslide, ftype))

    # Add data
    for ea, _ in Names():
        dname = idc.get_name(ea)
        dtype = idc.get_type(ea)
        dslide = ea - kbase
        flags = GetFlags(ea)
        if idc.is_code(flags) or idc.is_strlit(flags):
            continue
        if dtype is None:
            if TYPED_DATA_ONLY:
                continue
            dtype = 'void'
        define_data.append((dname, dslide, dtype))

    # Generate source files
    generate_sdk(define_funcs, define_data)
Beispiel #2
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
Beispiel #3
0
def main():
    kbase = min(Segments())
    define_funcs = []
    define_data = []

    # Add functions
    for ea in Functions():
        fname = idc.get_name(ea)
        ftype = idc.get_type(ea)
        fslide = ea - kbase
        if fname.startswith('sub_'):
            continue
        if ftype is None:
            if TYPED_FUNCS_ONLY:
                continue
            ftype = 'uint64_t (...)'
        define_funcs.append((fname, fslide, ftype))

    # Add data
    for ea, _ in Names():
        dname = idc.get_name(ea)
        dtype = idc.get_type(ea)
        dslide = ea - kbase
        flags = GetFlags(ea)
        if idc.is_code(flags) or idc.is_strlit(flags):
            continue
        if dtype is None:
            if TYPED_DATA_ONLY:
                continue
            dtype = 'void'
        define_data.append((dname, dslide, dtype))

    # Generate source files
    generate_sdk(define_funcs, define_data)
Beispiel #4
0
def crefs_from(ea, only_one=False, check_fixup=True):
  flags = idc.get_full_flags(ea)
  if not idc.is_code(flags):
    return

  fixup_ea = idc.BADADDR
  seen = False
  has_one = only_one
  if check_fixup:
    fixup_ea = idc.get_fixup_target_off(ea)
    if not is_invalid_ea(fixup_ea) and is_code(fixup_ea):
      seen = only_one
      has_one = True
      yield fixup_ea

    if has_one and _stop_looking_for_xrefs(ea):
      return

  for target_ea in _xref_generator(ea, idaapi.get_first_cref_from, idaapi.get_next_cref_from):
    if target_ea != fixup_ea and not is_invalid_ea(target_ea):
      seen = only_one
      yield target_ea
      if seen:
        return

  if not seen and ea in _CREFS_FROM:
    for target_ea in _CREFS_FROM[ea]:
      seen = only_one
      yield target_ea
      if seen:
        return
Beispiel #5
0
def crefs_from(ea, only_one=False, check_fixup=True):
    flags = idc.get_full_flags(ea)
    if not idc.is_code(flags):
        return

    fixup_ea = idc.BADADDR
    seen = False
    has_one = only_one
    if check_fixup:
        fixup_ea = idc.get_fixup_target_off(ea)
        if not is_invalid_ea(fixup_ea) and is_code(fixup_ea):
            seen = only_one
            has_one = True
            yield fixup_ea

        if has_one and _stop_looking_for_xrefs(ea):
            return

    for target_ea in _xref_generator(ea, idaapi.get_first_cref_from,
                                     idaapi.get_next_cref_from):
        if target_ea != fixup_ea and not is_invalid_ea(target_ea):
            seen = only_one
            yield target_ea
            if seen:
                return

    if not seen and ea in _CREFS_FROM:
        for target_ea in _CREFS_FROM[ea]:
            seen = only_one
            yield target_ea
            if seen:
                return
Beispiel #6
0
def dump_type(ea):
    flags = idaapi.get_flags(ea)
    if idc.is_code(flags):
        return "block" if idaapi.get_func(ea) else "code"
    if idc.is_data(flags):
        return "data"
    return "unexplored"
Beispiel #7
0
def base64_decode(std):
    addr = idc.BADADDR
    ea = idc.get_screen_ea()
    flags = idaapi.get_flags(ea)

    if idc.is_strlit(flags):
        addr = ea   #  cursor is on the string
    elif idc.is_code(flags):
        addr = idc.get_first_dref_from(ea)  # get data reference from the instruction

    if addr == idc.BADADDR:
        plg_print("No string or reference to the string found\n")
        return

    b64str_enc = None
    try:
        b64str_enc = idc.get_strlit_contents(addr, -1, idc.get_str_type(addr))
    except:
        pass

    if not b64str_enc:
        plg_print("Could not get string at address 0x%X" % addr)
        return

    try:
        b64str_dec = base64.standard_b64decode(b64str_enc) if std else base64.urlsafe_b64decode(b64str_enc)
    except Exception as e:
        plg_print("Could not decode. %s" % str(e))
        return

    if b64str_dec:
        plg_print("Base64 decode of string '%s':" % b64str_enc)
        process_data_result(ea, bytearray(b64str_dec))
Beispiel #8
0
    def is_code(self):
        """
            Property indicating if this element is some code.
            Wrapper on ``idc.is_code`` .

            :return: True if current element is code, False otherwise.
            :rtype: bool
        """
        return idc.is_code(self.flags)
Beispiel #9
0
    def instr_iter(self):
        """
            Return a generator of :class:`BipInstr` corresponding to the
            instructions of the basicblock. This implementation will be just
            a little more performant than the :meth:`instr` property.

            :return: A generator of object :class:`BipInstr` .
        """
        for h in idautils.Heads(self.ea, self.end):
            if idc.is_code(ida_bytes.get_full_flags(h)):
                yield bip.base.instr.BipInstr(h)
Beispiel #10
0
    def instr(self):
        """
            Return a list of :class:`BipInstr` corresponding to the instructions
            of the basicblock.

            :return: A list of object :class:`BipInstr` .
        """
        return [
            bip.base.instr.BipInstr(h)
            for h in idautils.Heads(self.ea, self.end)
            if idc.is_code(ida_bytes.get_full_flags(h))
        ]
Beispiel #11
0
def convert_pointer_to_offset(ea):
    # If this is code, skip it.
    flags = idc.get_full_flags(ea)
    if idc.is_code(flags):
        return
    # If the value at this address does not point into the kernelcache, skip it.
    value = idc.get_qword(ea)
    if not is_mapped(value, 8):
        return
    # Convert this value to a qword (in case it's unaligned) and then convert it into an
    # offset.
    idc.create_qword(ea)
    idc.op_plain_offset(ea, 0, 0)
Beispiel #12
0
def trim_func(ea, GetHead):
    """
    Description:
        Steps until it hits something not a nop or not starts with 90 (nop opcode) nor an align or not byte 0xCC (Align 'opcode').

    Input:
        ea - The location to adjust for nops and Aligns. EA must be a head.
        GetHead - either prev_head or next_head

    Output:
        The corrected EA.
    """
    while idc.print_insn_mnem(ea) == 'nop' or (idaapi.is_data(idc.get_full_flags(ea)) and idc.get_wide_byte(ea) == 0x90) or \
            idc.is_align(idc.get_full_flags(ea)) or (not idc.is_code(idc.get_full_flags(ea)) and idc.get_wide_byte(ea) == 0xCC):
        ea = GetHead(ea)
    return ea
Beispiel #13
0
def get_ea_from_highlight():
    view = idaapi.get_current_viewer()
    thing = ida_kernwin.get_highlight(view)
    if thing and thing[1]:
        # we have a highligh, is it a valid name ?
        ea = idc.get_name_ea_simple(thing[0])
        if ea != idaapi.BADADDR:
            return ea
        else:
            # Try to get full highlight name
            place = idaapi.get_custom_viewer_place(view, False)
            if place and len(place) == 3:   # (plate_t, x, y)
                ea = place[0].toea()
                far_code_refs = [xref.to for xref in idautils.XrefsFrom(ea, ida_xref.XREF_FAR) \
                                 if idc.is_code(idc.get_full_flags(xref.to))]
                if far_code_refs:
                    return far_code_refs[0]

    # Reach now, we do not have any valid name, return current screen ea
    return idc.get_screen_ea()
Beispiel #14
0
    def make(cls, ea=None):
        """
            Class method for defining an instruction. If auto-analysis is
            enable in IDA this may define also the following instructions.
            If the instruction is already define, this instruction just
            returns it.

            :param ea: The address at which to define the instruction, if None
                the current screen address is used.
            :return: The :class:`BipInstr` for this address.
            :raise RuntimeError: If it was not possible to define the address
                as code.
        """
        if ea is None:
            ea = ida_kernwin.get_screen_ea()
        if idc.is_code(
                ida_bytes.get_full_flags(ea)):  # if we already have code
            return cls(ea)
        if ida_ua.create_insn(ea) == 0:
            raise RuntimeError(
                "Unable to create instruction at 0x{:X}".format(ea))
        return cls(ea)
Beispiel #15
0
    def _ins2color(self, addr):
        col = _len = 0
        acc = -1

        head = get_item_head(addr)
        if can_decode(head):
            f = get_full_flags(head)
            if is_code(f):
                _len = decode_insn(self.insn, head)
                if _len:
                    if self.insn.itype in [ida_allins.NN_mov
                                           ]:  # TODO: add more instructions
                        if self.insn.Op1.type in [o_mem, o_phrase, o_displ]:
                            acc = ACC_WRITE
                            col = self.insn_colors[acc]
                        elif self.insn.Op2.type in [o_mem, o_phrase, o_displ]:
                            acc = ACC_READ
                            col = self.insn_colors[acc]
                        else:
                            acc = -1

        return (col, _len, acc)
Beispiel #16
0
def check_vtable(start, end=None):
    # We recognize a vtable by looking for an array of at least 2 pointers to code followed by a
    # NULL.
    # If no end was specified, go until the end of the segment.
    if end is None:
        end = idc.get_segm_end(start)
    # Check each address in the table. Stop once we've found something other than a pointer to
    # code.
    ended_with_zero = False
    ea = start
    while ea < end:
        method = idc.get_qword(ea)
        if method == 0:
            ended_with_zero = True
            break
        if not idc.is_code(idc.get_full_flags(method)):
            break
        ea += 8
    # Compute the length.
    length = (ea - start) / 8
    possible_vtable = ended_with_zero and length >= 2
    return possible_vtable, length
        class_parent = NameEx(BADADDR, call[2])
        class_parent_name = Demangle(class_parent, GetLongPrm(INF_LONG_DN))
        if class_parent_name:
            class_parent = class_parent_name

        fd.write('class ' + class_name + ': public ' +
                 class_parent.replace('__gMetaClass', '') + ' \n')
        class_size = call[3]

        class_vtable = call[4]
        for i in range(13):
            OpOff(class_vtable + i * 8, 0, 0)
            if i == 12:
                fptr = Qword(class_vtable + i * 8)
                if fptr != 0:
                    if idc.is_code(fptr) == False:
                        MakeUnknown(fptr, 1, idaapi.DOUNK_SIMPLE)
                        # idaapi.autoWait()
                        if fptr != Qword(class_vtable + i * 8):
                            print("BBBBBBBBBBBBBBBBBBBBBBB")
                        # fptr = Qword(class_vtable + i * 8)
                        MakeCode(fptr)
                        idaapi.autoWait()

                    if idc.get_func_attr(fptr, FUNCATTR_START) == idc.BADADDR:
                        MakeFunction(fptr)
                        idaapi.autoWait()

        class_vtable_name = 'vtbl_' + class_name_meta

        MakeNameEx(class_vtable, class_vtable_name, 0)
Beispiel #18
0
 def _is_this_elt(cls, ea):
     return idc.is_code(ida_bytes.get_full_flags(ea))
Beispiel #19
0
def is_code_ea(ea):
    if idaapi.cvar.inf.procname == "ARM":
        flags = idc.get_full_flags(ea & -2)  # flags_t
    else:
        flags = idc.get_full_flags(ea)
    return idc.is_code(flags)
Beispiel #20
0
def is_code_by_flags(ea):
    if not is_code(ea):
        return False

    flags = idc.get_full_flags(ea)
    return idc.is_code(flags)
Beispiel #21
0
def filter_for_code(name_list):
    filtered = []
    for name in name_list:
        ea = idc.get_name_ea_simple(name)
        if idc.is_code(ea):
            filtered.append(name)
Beispiel #22
0
def is_code_ptr(ea):
    return is_mapped_data(ea, 4) and idc.is_code(
        idc.get_full_flags(idc.get_qword(ea)))
Beispiel #23
0
def is_code_by_flags(ea):
  if not is_code(ea):
    return False

  flags = idc.get_full_flags(ea)
  return idc.is_code(flags)
Beispiel #24
0
 def is_code(self, ea):
     flags = idc.get_full_flags(ea)
     return idc.is_code(flags)
def reconstruct_vtable(vtable_addr, current_class_name):
    vtable_addr_local = vtable_addr
    func = Qword(vtable_addr_local)
    vtable_functions = []
    used_function_names = []

    while func != 0 and (func & 0xfffffff000000000
                         ) == 0xfffffff000000000 and '__text' in SegName(func):
        # print("  Address = " + hex(func))

        # func_addr = GetFunctionAttr(func, FUNCATTR_START)
        # MakeCode(func)

        # if add_func(func) != 0:
        #     return False, []
        if idc.is_code(func) == False:
            MakeUnknown(Qword(vtable_addr_local), 1, idaapi.DOUNK_SIMPLE)
            # idaapi.autoWait()
            # if fptr != Qword(class_vtable + i * 8):
            #     print("BBBBBBBBBBBBBBBBBBBBBBB")
            # fptr = Qword(class_vtable + i * 8)
            MakeCode(Qword(vtable_addr_local))
            idaapi.autoWait()
        # MakeCode(func)
        # idaapi.autoWait()
        MakeFunction(Qword(vtable_addr_local))
        idaapi.autoWait()
        OpOff(vtable_addr_local, 0, 0)
        idaapi.autoWait()
        # func_name = GetFunctionName(func)
        # if func_name == '':
        func_name = NameEx(BADADDR, func)
        if func_name == '':
            func_name = 'sub_' + '%016X' % func
            print("  NNMNNMNNMNNMNNM => 0x%016x" % (func))
            #func_name = 'unnamed_function'
            # print("No name :( " + hex(vtable_addr_local))
            # sys.exit(0)

        if func_name[0:3] == 'loc':
            print("  LOCLOCLOCLOCLOC => %s" % (func_name))
            if idc.get_func_attr(func,
                                 FUNCATTR_START) not in (func, idc.BADADDR):
                mainfunc = idc.get_func_attr(func, FUNCATTR_START)
                print("  SEPARATE FUNCTION => 0x%016x" % (mainfunc))
                MakeUnknown(mainfunc, 1, idaapi.DOUNK_SIMPLE)
                idaapi.autoWait()
                MakeCode(Qword(vtable_addr_local))
                idaapi.autoWait()
                MakeFunction(Qword(vtable_addr_local))
                idaapi.autoWait()
                MakeCode(mainfunc)
                if MakeFunction(mainfunc):
                    idaapi.autoWait()
                else:
                    print("  NOT RECONSTRUCT => 0x%016x" % (mainfunc))
            else:
                if MakeFunction(Qword(vtable_addr_local)):
                    idaapi.autoWait()
                else:
                    print("  NOT RECONSTRUCT => 0x%016x" %
                          (Qword(vtable_addr_local)))

            func_name = func_name.replace('loc', 'sub')
        elif func_name[0:3] == 'unk':
            print("  SUBSUBSUBSUBSUB => %s" % (func_name))
            func_name = func_name.replace('unk', 'sub')
            #     func_name = 'unnamed_function'
            #     print("No name :( " + hex(func))
            #     sys.exit(0)
            #
            # func_name = get_name(func)
            # if 'off' in func_name:
            #     func_name = func_name.replace('off', 'sub')
            # elif 'loc' in func_name:
            #     func_name = func_name.replace('loc', 'sub')
            # lif 'unk' in func_name:
            #     func_name = func_name.replace('unk', 'sub')

        func_type = GetType(func)

        if func_type == None:
            func_type = '__int64 __fastcall()'

        if func_name[0:3] == '__Z':
            func_name = Demangle(func_name, 0)
            class_name, func_name = parse_demangled_name(func_name)

            if class_name != current_class_name:
                func_name = class_name + '::' + func_name

        new_func = func_name
        i = 0
        while new_func in used_function_names:
            new_func = func_name + '_' + str(i)
            i += 1

        vtable_functions.append([new_func, func_type])
        used_function_names.append(new_func)

        # OpOff(vtable_addr_local, 0, 0)
        vtable_addr_local += 8
        func = Qword(vtable_addr_local)

    return True, vtable_functions