Exemple #1
0
    def _apply_tag_on_callee(cls, callee_ea, rv, is_call=False):
        name = idaapi.get_ea_name(callee_ea)
        name = name.replace(idaapi.FUNC_IMPORT_PREFIX, '')

        if '@' in name:
            name = name.split('@')[0]

        if not name:
            return

        if name in IGNORE_CALL_LIST:
            if is_call:
                rv['calls'].pop()
            return

        if name in TAGS_IGNORE_LIST:
            return

        for tag, names in TAGS.items():
            for tag_api in names:
                if tag in STRICT_TAG_NAME_CHECKING:
                    match = tag_api in (name, name.lstrip('_'))
                else:
                    match = tag_api in name
                if not match or name in rv['tags'][tag]:
                    continue

                # print('%#08x: %s, tag: %s' % (dis.ea, name, tag))
                rv['tags'][tag].append(name)
                break
Exemple #2
0
    def _handle_calls(self, fn, fn_an):
        num_calls = len(fn_an['calls'])
        if num_calls != 1:
            return

        dis = fn_an['calls'][0]
        if dis.Op1.type not in (o_imm, o_far, o_near, o_mem):
            return

        ea = dis.Op1.value
        if not ea and dis.Op1.addr:
            ea = dis.Op1.addr

        if idaapi.has_dummy_name(idaapi.getFlags(ea)):
            return

        # TODO: check is there jmp, push+retn then don't rename the func
        if fn_an['strange_flow']:
            return

        possible_name = idaapi.get_ea_name(ea)
        if not possible_name or possible_name in blacklist:
            return

        normalized = self.normalize_name(possible_name)

        # if self._cfg.get('auto_rename'):
        if len(fn_an['math']) < self._MIN_MAX_MATH_OPS_TO_ALLOW_RENAME:
            idaapi.do_name_anyway(fn.startEA, normalized)
        # TODO: add an API to the view
        print 'fn: %#08x: %d calls, %d math%s possible name: %s, normalized: %s' % (
            fn.startEA, len(fn_an['calls']), len(fn_an['math']), 'has bads' if fn_an['has_bads'] else '',
            possible_name, normalized)
Exemple #3
0
    def _analysis_handle_call_insn(cls, dis, rv):
        rv['calls'].append(dis)
        if dis.Op1.type != o_mem or not dis.Op1.addr:
            return

        name = idaapi.get_ea_name(dis.Op1.addr)
        name = name.replace(idaapi.FUNC_IMPORT_PREFIX, '')

        if '@' in name:
            name = name.split('@')[0]

        if not name:
            return

        if name in IGNORE_CALL_LIST:
            rv['calls'].pop()
            return

        for tag, names in TAGS.items():
            if name in TAGS_IGNORE_LIST:
                continue

            for tag_api in names:
                if tag_api in name:
                    # print '%#08x: %s, tag: %s' % (dis.ea, name, tag)
                    rv['tags'][tag].append(name)
                    break
Exemple #4
0
    def _handle_tags(self, fn, fn_an, known_refs):
        if known_refs:
            known_refs = dict(known_refs)
            for k, names in known_refs.items():
                existing = set(fn_an['tags'][k])
                new = set(names) - existing
                if new:
                    fn_an['tags'][k] += list(new)

        tags = dict(fn_an['tags'])
        if not tags:
            return
        print 'fn: %#08x tags: %s' % (fn.startEA, tags)
        cmt = idaapi.get_func_cmt(fn, True)
        if cmt:
            cmt += '\n'
        s = str(tags.keys())
        name = idaapi.get_ea_name(fn.startEA)
        item = {'ea': fn.startEA, 'name': name, 'tags': tags}
        if not cmt or s not in cmt:
            idaapi.set_func_cmt(fn, '%sTAGS: %s' % (cmt or '', s), True)
        # self.mark_position(fn.startEA, 'TAGS: %s' % s)
        for tag in tags:
            if tag not in self._data:
                self._data[tag] = list()
            self._data[tag].append(item)
Exemple #5
0
def get_name_or_address(ea):
    name = idaapi.get_ea_name(ea, idaapi.GN_VISIBLE)
    if name:
        name = repr(name)
    else:
        name = "0x{:08X}".format(ea)

    return name
Exemple #6
0
def _get_best_name(ea):
    try:
        return sark.Function(ea).demangled
    except exceptions.SarkNoFunction:
        name = idaapi.get_ea_name(ea)
        if name:
            return name
        return '0x{:X}'.format(ea)
Exemple #7
0
    def parse(self):
        itype_addr = common.read_mem(self.addr) & 0xFFFFFFFFFFFFFFFF
        self.itype = self.type_parser.parse_type(type_addr=itype_addr)

        rtype_addr = common.read_mem(self.addr +
                                     common.ADDR_SZ) & 0xFFFFFFFFFFFFFFFF
        self.rtype = self.type_parser.parse_type(type_addr=rtype_addr)

        self.hash = common.read_mem(self.addr + 2 * common.ADDR_SZ,
                                    forced_addr_sz=4) & 0xFFFFFFFF

        # methods start addr(if has method)
        curr_addr = self.addr + 3 * common.ADDR_SZ
        while True:
            if len(idaapi.get_ea_name(curr_addr)) > 0:
                # stop at next itab_elem addr
                # next itab elem is labeled a head name by ida pro
                break

            meth_addr = common.read_mem(curr_addr)
            if idaapi.get_func(meth_addr):
                meth_name = idaapi.get_ea_name(meth_addr)
                self.methods.append(meth_name)
                self.meth_num += 1

            curr_addr += common.ADDR_SZ

        idc.MakeComm(self.addr, "interface: %s" % self.itype.name)
        idc.MakeComm(self.addr + common.ADDR_SZ, "rtype: %s" % self.rtype.name)
        idc.MakeComm(self.addr + 2 * common.ADDR_SZ, "rtype hash")
        idaapi.autoWait()

        itab_elem_name = "go_itab__%s_%s" % (self.rtype.name_obj.name_str,
                                             self.itype.name)
        idc.MakeNameEx(self.addr, itab_elem_name, flags=idaapi.SN_FORCE)
        common._debug("Go itab %s(@ 0x%x) parsed." %
                      (itab_elem_name, self.addr))
        idaapi.autoWait()
Exemple #8
0
    def _rename_ea_requested(self, addr, name_idx):
        old_name = name_idx.data()

        if idaapi.IDA_SDK_VERSION >= 700:
            new_name = idaapi.ask_str(str(old_name), 0, 'New name:')
        else:
            new_name = idaapi.askstr(0, str(old_name), 'New name:')

        if new_name is None:
            return

        self._rename(addr, new_name)
        renamed_name = idaapi.get_ea_name(addr)
        name_idx.model().setData(name_idx, renamed_name)
Exemple #9
0
    def _preprocess_api_wrappers(self, fnqty):
        rv = defaultdict(dict)

        for i in xrange(fnqty):
            fn = idaapi.getn_func(i)
            items = list(FuncItems(self.start_ea_of(fn)))
            if len(items) not in (1, 2):
                continue

            dis0 = decode_insn(items[0])
            if dis0 is None:
                continue
            addr = self._check_is_jmp_wrapper(dis0)

            if not addr and len(items) > 1:
                dis1 = decode_insn(items[1])
                if dis1 is not None:
                    addr = self._check_is_push_retn_wrapper(dis0, dis1)

            if not addr:
                continue

            name = idaapi.get_ea_name(addr)
            name = name.replace(idaapi.FUNC_IMPORT_PREFIX, '')
            if not name:
                continue

            imp_stripped_name = name.lstrip('_')

            for tag, names in TAGS.items():
                for tag_api in names:
                    if tag in STRICT_TAG_NAME_CHECKING:
                        match = tag_api in (name, imp_stripped_name)
                    else:
                        match = tag_api in name
                    if not match:
                        continue

                    refs = list(CodeRefsTo(self.start_ea_of(fn), 1))

                    for ref in refs:
                        ref_fn = idaapi.get_func(ref)
                        if not ref_fn:
                            # idaapi.msg('AutoRE: there is no func for ref: %08x for api: %s' % (ref, name))
                            continue
                        if tag not in rv[self.start_ea_of(ref_fn)]:
                            rv[self.start_ea_of(ref_fn)][tag] = list()
                        if name not in rv[self.start_ea_of(ref_fn)][tag]:
                            rv[self.start_ea_of(ref_fn)][tag].append(name)
        return dict(rv)
Exemple #10
0
 def _handle_tags(self, fn, fn_an):
     tags = dict(fn_an['tags'])
     if not tags:
         return
     print 'fn: %#08x tags: %s' % (fn.startEA, tags)
     cmt = idaapi.get_func_cmt(fn, True)
     if cmt:
         cmt += '\n'
     s = str(tags.keys())
     name = idaapi.get_ea_name(fn.startEA)
     item = {'ea': fn.startEA, 'name': name, 'tags': tags}
     if not cmt or s not in cmt:
         idaapi.set_func_cmt(fn, '%sTAGS: %s' % (cmt or '', s), True)
     # self.mark_position(fn.startEA, 'TAGS: %s' % s)
     for tag in tags:
         if tag not in self._data:
             self._data[tag] = list()
         self._data[tag].append(item)
Exemple #11
0
def get_offset_name(ea):
    # Try and get the function name
    try:
        func = get_func(ea)
        name = idaapi.get_ea_name(func.start_ea)
        name = demangle(name, 0x60)  # MNG_NOTYPE | MNG_NORETTYPE
        if name:
            offset = ea - func.start_ea
            if offset:
                return '{}+{:X}'.format(name, offset)
            return name
    except exceptions.SarkNoFunction:
        pass

    # If that failed, use the segment name instead.
    segment = idaapi.getseg(ea)
    name = idaapi.get_segm_name(segment)
    offset_format = '{{:0{}X}}'.format(get_native_size() * 2)
    ea_text = offset_format.format(ea)
    if name:
        return '{}:{}'.format(name, ea_text)

    # Nothing found, simply return the address
    return ea_text
def define_vtables():
    segments = util.enum_all_segments()
    vtables_total = 0

    for segm in segments:
        addr = segm.start_ea
        while addr < segm.end_ea:
            funcs_counted = VirtualTable.check(addr)
            if funcs_counted:
                print 'Found possible vtable: %#x (%s) with %d functions' % (
                    addr,
                    repr(
                        idaapi.demangle_name(
                            idaapi.get_ea_name(addr),
                            idc.get_inf_attr(
                                idc.INF_SHORT_DN))), funcs_counted)
                v = VirtualTable(addr)

                v.finalize()
                addr += funcs_counted * const.PTR_SIZE
                vtables_total += 1
            addr += const.PTR_SIZE

    print '[!] Imported %d virtual tables in total!' % vtables_total
Exemple #13
0
    def check_member_assignment(self, expression, index):
        """
        We are now in cexpr_t == idaapi.cot_var. This function checks if expression is part of member assignment
        statement. Returns None if not.

        :param expression: idaapi.cexpr_t
        :param index: int
        :return: Structures.AbstractField
        """
        parents_type = map(lambda x: idaapi.get_ctype_name(x.cexpr.op),
                           list(self.parents)[:0:-1])
        parents = map(lambda x: x.cexpr, list(self.parents)[:0:-1])

        for parent in parents:
            if parent.ea != idaapi.BADADDR:
                self.expression_address = parent.ea
                break
        else:
            self.expression_address = idaapi.BADADDR

        offset = 0

        if parents_type[0:2] == ['asg', 'expr']:
            if parents[0].y == expression:
                # Assignment like (v1 = v2) where v2 is scanned variable
                if parents[0].x.op == idaapi.cot_var:
                    self.add_variable(parents[0].x.v.idx)
                    return
            else:
                # if expression is (var = something), we have to explore whether continue to scan this variable or not
                if parents[0].y.op != idaapi.cot_num:
                    if parents[0].y.op == idaapi.cot_call:
                        # Check if expression: var = function((TYPE) var, ...) or var = function(var, ...)
                        args = parents[0].y.a
                        if args and ((args[0].op == idaapi.cot_cast
                                      and args[0].x.op == idaapi.cot_var
                                      and args[0].x.v.idx == index) or
                                     (args[0].op == idaapi.cot_var
                                      and args[0].v.idx == index)):
                            return
                    try:
                        self.protected_variables.remove(index)
                    except KeyError:
                        print "[Info] Remove variable {0} from scan list, address: 0x{1:08X}".format(
                            index, self.expression_address)
                        self.variables.pop(index)
                    return

        # Assignment like v1 = (TYPE) v2 where TYPE is one the supported types
        elif parents_type[0:3] == ['cast', 'asg', 'expr']:
            if parents[1].x.op == idaapi.cot_var:
                if filter(lambda x: x.equals_to(parents[0].type),
                          Const.LEGAL_TYPES):
                    self.add_variable(parents[1].x.v.idx)
                    return

        # Universal call with no cast conversion and offsets: call(..., this, ...)
        if parents_type[0] == 'call':
            arg_index, _ = Helper.get_func_argument_info(
                parents[0], expression)
            if SCAN_ALL_ARGUMENTS or not arg_index:
                self.scan_function(parents[0].x.obj_ea, 0, arg_index)
            return

        # --------------------------------------------------------------------------------------------
        # When variable is DWORD, int, __int64 etc
        # --------------------------------------------------------------------------------------------
        elif self.variables[index].equals_to(Const.X_WORD_TINFO):

            if parents_type[0:2] == ['add', 'cast']:
                if parents[0].theother(expression).op != idaapi.cot_num:
                    return
                offset = parents[0].theother(expression).numval()

                if parents_type[2] == 'ptr':
                    if parents_type[3] == 'asg':
                        if parents[3].x == parents[2]:
                            # *(TYPE *)(var + x) = ???
                            return self.get_member(
                                offset,
                                index,
                                object=parents[3].y,
                                default=parents[1].type.get_pointed_object())
                        if parents[3].x.op == idaapi.cot_var:
                            # other_var = *(TYPE *)(var + x)
                            return self.create_member(offset, index,
                                                      parents[3].x.type)
                    return self.create_member(
                        offset, index, parents[1].type.get_pointed_object())

                elif parents_type[2] == 'call':
                    # call(..., (TYPE)(var + x), ...)
                    if parents[0].theother(expression).op != idaapi.cot_num:
                        return
                    offset = parents[0].theother(expression).numval()
                    return self.get_member(offset,
                                           index,
                                           call=parents[2],
                                           arg=parents[1])

                elif parents_type[2] == 'asg':
                    # other_var = (LEGAL TYPE) (var + offset)
                    if parents[2].y == parents[1] and parents[
                            2].x.op == idaapi.cot_var:
                        if filter(lambda x: x.equals_to(parents[1].type),
                                  Const.LEGAL_TYPES):
                            self.scan_function(self.function.entry_ea, offset,
                                               parents[2].x.v.idx)
                            return

                cast_type = parents[1].type
                if cast_type.is_ptr():
                    return self.create_member(offset, index,
                                              cast_type.get_pointed_object())

            elif parents_type[0:2] == ['cast', 'ptr']:

                if parents_type[2] == 'asg' and parents[2].x == parents[1]:
                    # *(TYPE *)var = ???
                    return self.get_member(
                        0,
                        index,
                        object=parents[2].y,
                        default=parents[0].type.get_pointed_object())
                return self.create_member(0, index,
                                          parents[0].type.get_pointed_object())

            elif parents_type[0:2] == ['cast', 'call']:
                # call(..., (TYPE)(var + x), ...)
                return self.get_member(0,
                                       index,
                                       call=parents[1],
                                       arg=parents[0])

            elif parents_type[0] == 'add':
                # call(..., var + x, ...)
                if parents[0].theother(expression).op != idaapi.cot_num:
                    return
                offset = parents[0].theother(expression).numval()

                if parents_type[1] == 'call':
                    return self.get_member(offset,
                                           index,
                                           call=parents[1],
                                           arg=parents[0])

                elif parents_type[1] == 'asg':
                    if parents[1].y == parents[0] and parents[
                            1].x.op == idaapi.cot_var:
                        self.scan_function(self.function.entry_ea, offset,
                                           parents[1].x.v.idx)
                        return

            elif parents_type[0] == 'asg':
                # var = (int)&Some_object
                if parents[0].y.op == idaapi.cot_cast and parents[
                        0].y.x.op == idaapi.cot_ref:
                    return self.create_member(
                        0, index, parents[0].y.x.type.get_pointed_object())

        # --------------------------------------------------------------------------------------------
        # When variable is void *, PVOID, DWORD *, QWORD * etc
        # --------------------------------------------------------------------------------------------
        else:
            # print "[DEBUG] D* Parents:", parents_type
            offset = 0

            if parents_type[0] == 'idx':
                if parents[0].y.op != idaapi.cot_num:
                    # There's no way to handle with dynamic offset
                    return None
                offset = parents[0].y.numval(
                ) * self.variables[index].get_ptrarr_objsize()
                if parents_type[1] == 'asg' and parents[1].x == parents[0]:
                    # var[idx] = ???
                    return self.get_member(
                        offset,
                        index,
                        object=parents[1].y,
                        default=self.variables[index].get_pointed_object())
                elif parents_type[1] == 'cast':
                    # (TYPE) var[idx]
                    return self.create_member(offset, index, parents[1].type)
                return self.create_member(offset, index, Const.X_WORD_TINFO)
            elif parents_type[0:2] == ['ptr', 'asg']:
                # *var = ???
                return self.get_member(
                    0,
                    index,
                    object=parents[1].y,
                    default=self.variables[index].get_pointed_object())
            else:
                if parents_type[0:2] == ['cast', 'ptr']:

                    if parents_type[2] == 'call':
                        # call(..., *(TYPE *) var, ...)
                        return self.get_member(0,
                                               index,
                                               call=parents[2],
                                               arg=parents[1])
                    elif parents_type[2] == 'asg' and parents[2].x == parents[
                            1]:
                        # *(TYPE *) var = ???
                        return self.get_member(
                            0,
                            index,
                            object=parents[2].y,
                            default=parents[0].type.get_pointed_object())

                elif parents_type[0:2] == ['cast', 'add']:
                    if parents[1].theother(parents[0]).op != idaapi.cot_num:
                        return None
                    offset = parents[1].theother(parents[0]).numval()
                    offset *= parents[0].type.get_ptrarr_objsize(
                    ) if parents[0].type.is_ptr() else 1

                    if parents_type[2] == 'ptr':
                        if parents_type[3] == 'asg' and parents[
                                3].x == parents[2]:
                            # *((TYPE *)var + x) = ???
                            return self.get_member(
                                offset,
                                index,
                                object=parents[3].y,
                                default=parents[0].type.get_pointed_object())
                        return self.create_member(
                            offset, index,
                            parents[0].type.get_pointed_object())
                    elif parents_type[2] == 'call':
                        # call(..., (TYPE)var + offset, ...)
                        return self.get_member(offset,
                                               index,
                                               call=parents[2],
                                               arg=parents[1])
                    elif parents_type[2] == 'cast' and parents[2].type.is_ptr(
                    ):
                        if parents_type[3] == 'call':
                            # call(..., (TYPE *) ((TYPE *)var + x), ...)
                            # Where argument type is not the same as cast type. Ida has a bug here choosing sometimes
                            # wrong pointer type
                            idx, tinfo = Helper.get_func_argument_info(
                                parents[3], parents[2])
                            return self.create_member(
                                offset, index, tinfo.get_pointed_object())

                        # (TYPE *) ((TYPE *)var + x)
                        return self.create_member(
                            offset, index,
                            parents[2].type.get_pointed_object())

                elif parents_type[0:2] == ['add', 'cast']:
                    if parents[0].theother(expression).op != idaapi.cot_num:
                        return None
                    offset = parents[0].theother(expression).numval(
                    ) * self.variables[index].get_ptrarr_objsize()

                    if parents_type[2] == 'call':
                        # call(..., (TYPE)(var + x), ...)
                        return self.get_member(offset,
                                               index,
                                               call=parents[2],
                                               arg=parents[1])
                    elif parents_type[2] == 'asg':
                        if parents[2].y == parents[1] and parents[
                                2].x.op == idaapi.cot_var:
                            if filter(lambda x: x.equals_to(parents[1].type),
                                      Const.LEGAL_TYPES):
                                self.scan_function(self.function.entry_ea,
                                                   offset, parents[2].x.v.idx)
                                return
                    else:
                        return self.create_member(
                            offset, index,
                            parents[1].type.get_pointed_object())

                elif parents_type[0] == 'add':

                    # call(..., var + offset, ...)
                    if parents[0].theother(expression).op != idaapi.cot_num:
                        return None
                    offset = parents[0].theother(expression).numval(
                    ) * self.variables[index].get_ptrarr_objsize()

                    if parents_type[1] == 'call':
                        return self.get_member(offset,
                                               index,
                                               call=parents[1],
                                               arg=parents[0])

                    if parents_type[1] == 'asg':
                        # other_var = var + offset
                        if parents[1].y == parents[0] and parents[
                                1].x.op == idaapi.cot_var:
                            self.scan_function(self.function.entry_ea, offset,
                                               parents[1].x.v.idx)
                            return

                elif parents_type[0:2] == ['cast', 'call']:
                    # call(..., (TYPE) var, ...)
                    return self.get_member(0,
                                           index,
                                           call=parents[1],
                                           arg=parents[0])

                elif parents_type[0] == 'ptr':
                    if parents_type[1] == 'cast':
                        # (TYPE) *var
                        return self.create_member(0, index, parents[0].type)
                    # *var
                    return self.create_member(
                        0, index, self.variables[index].get_pointed_object())

                elif parents_type[0] == 'asg':
                    return

        if 'return' not in parents_type[0:2] and parents_type[0] not in (
                'if', 'band', 'eq', 'ne', 'cast'):
            print "[DEBUG] Unhandled type", self.variables[index].dstr(), \
                "Index:", index, \
                "Offset:", offset, \
                "Function:", idaapi.get_ea_name(self.function.entry_ea), \
                "Address: 0x{0:08X}".format(expression.ea), \
                "Parents:", parents_type
Exemple #14
0
 def name(self):
     """Function's Name"""
     return idaapi.get_ea_name(self.start_ea)
Exemple #15
0
 def name(self):
     """Name of the line (the label shown in IDA)."""
     return idaapi.get_ea_name(self.ea)
Exemple #16
0
 def add_record(self, ea, score):
     pfn = idaapi.get_func(ea)
     self.record[pfn.start_ea] = {
         'name': idaapi.get_ea_name(pfn.start_ea),
         'score': score
     }
 def get_func_name(ea):
     name = idaapi.get_func_name(ea)
     if not name:
         name = idaapi.get_ea_name(ea)
     return idaapi.COLSTR(name, idaapi.SCOLOR_SYMBOL)
Exemple #18
0
 def on_get_text(self, value, attrs):
     name = idaapi.get_ea_name(value)
     demangle = getattr(idaapi, 'demangle_name2', idaapi.demangle_name)
     name = demangle(name, 0) or name
     return name or "0x{:08X}".format(value)