예제 #1
0
    def activate(self, ctx):
        hx_view = idaapi.get_widget_vdui(ctx.widget)
        if not self.check(hx_view):
            return

        data = []
        offset = hx_view.item.e.m
        struct_type = idaapi.remove_pointer(hx_view.item.e.x.type)
        ordinal = helper.get_ordinal(struct_type)
        result = struct_xrefs.XrefStorage().get_structure_info(ordinal, offset)
        for xref_info in result:
            data.append([
                idaapi.get_short_name(xref_info.func_ea) + "+" + hex(int(xref_info.offset)),
                xref_info.type,
                xref_info.line
            ])

        field_name = helper.get_member_name(struct_type, offset)
        chooser = forms.MyChoose(
            data,
            "Cross-references to {0}::{1}".format(struct_type.dstr(), field_name),
            [["Function", 20 | idaapi.CHCOL_PLAIN],
             ["Type", 2 | idaapi.CHCOL_PLAIN],
             ["Line", 40 | idaapi.CHCOL_PLAIN]]
        )
        idx = chooser.Show(True)
        if idx == -1:
            return

        xref = result[idx]
        idaapi.open_pseudocode(xref.func_ea + xref.offset, False)
예제 #2
0
    def create(cfunc, arg):
        # Creates object suitable for scaning either from cexpr_t or ctree_item_t
        if isinstance(arg, idaapi.ctree_item_t):
            lvar = arg.get_lvar()
            if lvar:
                index = list(cfunc.get_lvars()).index(lvar)
                result = VariableObject(lvar, index)
                if arg.e:
                    result.ea = ScanObject.get_expression_address(cfunc, arg.e)
                return result
            cexpr = arg.e
        else:
            cexpr = arg

        if cexpr.op == idaapi.cot_var:
            lvar = cfunc.get_lvars()[cexpr.v.idx]
            result = VariableObject(lvar, cexpr.v.idx)
            result.ea = ScanObject.get_expression_address(cfunc, cexpr)
            return result
        elif cexpr.op == idaapi.cot_memptr:
            t = cexpr.x.type.get_pointed_object()
            result = StructPtrObject(t.dstr(), cexpr.m)
            result.name = get_member_name(t, cexpr.m)
        elif cexpr.op == idaapi.cot_memref:
            t = cexpr.x.type
            result = StructRefObject(t.dstr(), cexpr.m)
            result.name = get_member_name(t, cexpr.m)
        elif cexpr.op == idaapi.cot_obj:
            result = GlobalVariableObject(cexpr.obj_ea)
            result.name = idaapi.get_short_name(cexpr.obj_ea)
        else:
            return
        result.tinfo = cexpr.type
        result.ea = ScanObject.get_expression_address(cfunc, cexpr)
        return result
예제 #3
0
    def _name_changed(self, address, new_name, local_name):
        """
        Handler for rename event in IDA.
        """

        # we should never care about local renames (eg, loc_40804b), ignore
        if local_name or new_name.startswith("loc_"):
            return 0

        # get the function that this address falls within
        function = self.get_function(address)

        # if the address does not fall within a function (might happen?), ignore
        if not function:
            return 0

        #
        # ensure the renamed address matches the function start before
        # renaming the function in our metadata cache.
        #
        # I am not sure when this would not be the case (globals? maybe)
        # but I'd rather not find out.
        #

        if address == function.address:
            logger.debug("Name changing @ 0x%X" % address)
            logger.debug("  Old name: %s" % function.name)
            function.name = idaapi.get_short_name(address)
            logger.debug("  New name: %s" % function.name)

        # notify any listeners that a function rename occurred
        self._notify_function_renamed()

        # necessary for IDP/IDB_Hooks
        return 0
예제 #4
0
def parse_vtable_name(address):
    name = idaapi.get_short_name(address)
    if idaapi.is_valid_typename(name):
        if name[0:3] == 'off':
            # off_XXXXXXXX case
            return "Vtable" + name[3:], False
    else:
        # Attempt to make nice and valid name from demangled RTTI name
        try:
            name = re.sub("^const ", "", name)
            sliced_names = name.split("::")
            name, for_part = "_for_".join(sliced_names[:-1]), sliced_names[-1]
            print name, for_part
            templates = re.search("<(.*)>", name)
            if templates:
                templates = templates.group(1)
                name = re.sub("<.*>", "", name)
                templates = re.sub("[^a-zA-Z0-9_*]", "_", templates)
                templates = re.sub("\*", "PTR", templates)
                name += '_' + templates

            for_part = re.search("\{for `(.*)'\}", for_part)
            if for_part:
                for_part = for_part.group(1)
                name += '_' + for_part

            return 'Vtable_' + name, True

        except (AttributeError, IndexError):
            print "[Warning] Unable to parse virtual table name - "

        return "Vtable_{0:X}".format(address), False
예제 #5
0
    def add_item(self, function_match):
        imagebase = idaapi.get_imagebase()
        self_address = imagebase + function_match[self.self_name]
        counts = self.count_blocks(function_match)

        root = self.model.invisibleRootItem()
        columns = [
            QtGui.QStandardItem(idaapi.get_short_name(self_address)),
            QtGui.QStandardItem('%.8x' % self_address),
            QtGui.QStandardItem(function_match[self.peer_name + '_name']),
            QtGui.QStandardItem('%.8x' % function_match[self.peer_name]),
            QtGui.QStandardItem('%d' % counts['matched_block_counts']),
            QtGui.QStandardItem('%d' %
                                counts['self_unidentified_block_counts']),
            QtGui.QStandardItem('%d' %
                                counts['peer_unidentified_block_counts'])
        ]
        root.appendRow(columns)

        class Item:
            def __init__(self, **kwargs):
                self.__dict__.update(kwargs)

        item_data = Item(function_match=function_match,
                         self_name=self.self_name,
                         peer_name=self.peer_name,
                         peer_md5=self.peer_md5,
                         queue=self.queue)

        for column_item in columns:
            column_item.setData(item_data, QtCore.Qt.UserRole)
 def __init__(self, offset, address, scanned_variable=None, origin=0):
     AbstractMember.__init__(self, offset + origin, scanned_variable,
                             origin)
     self.address = address
     self.virtual_functions = []
     self.name = "vtable" + ("_{0:X}".format(self.offset)
                             if self.offset else '')
     self.vtable_name, self.have_nice_name = parse_vtable_name(
         idaapi.get_short_name(address))
     self.populate()
예제 #7
0
 def name(self):
     name = idaapi.get_short_name(self.address)
     name = name.split('(')[0]
     result = re.search(r"(\[thunk\]:)?([^`]*)(.*\{(\d+)}.*)?", name)
     name, adjuster = result.group(2), result.group(4)
     if adjuster:
         name += "_adj_" + adjuster
     name = name.translate(None, "`'").replace(' ', '_')
     name = re.sub(r'[<>]', '_t_', name)
     return name
예제 #8
0
    def renamed(self, address, new_name, local_name):
        """
        Capture all IDA rename events.
        """

        # we should never care about local renames (eg, loc_40804b), ignore
        if local_name or new_name.startswith("loc_"):
            return 0

        rendered_name = idaapi.get_short_name(address)

        # call the 'renamed' callback, that will get hooked by a listener
        self.name_changed(address, rendered_name)

        # must return 0 to keep IDA happy...
        return 0
예제 #9
0
    def apply_type(self, tinfo):
        """ Finally apply Class'es tinfo to this variable """

        if self.applicable:
            hx_view = idaapi.open_pseudocode(self.function.entry_ea, -1)
            if hx_view:
                print "[Info] Applying tinfo to variable {0} in function {1}".format(
                    self.lvar.name,
                    idaapi.get_short_name(self.function.entry_ea))
                # Finding lvar of new window that have the same name that saved one and applying tinfo_t
                lvar = filter(lambda x: x == self.lvar,
                              hx_view.cfunc.get_lvars())
                if lvar:
                    print "+++++++++++"
                    hx_view.set_lvar_type(lvar[0], tinfo)
                else:
                    print "-----------"
예제 #10
0
    def scan_function(self, ea, offset, arg_index):
        # Function for recursive search structure's members

        if (ea, arg_index, self.origin + offset) in scanned_functions:
            return
        try:
            scanned_functions.add((ea, arg_index, self.origin + offset))
            new_function = idaapi.decompile(ea)
            if new_function:
                print "[Info] Scanning function {name} at 0x{ea:08X}, origin: 0x{origin:04X}".format(
                    name=idaapi.get_short_name(ea), ea=ea, origin=self.origin + offset
                )
                scanner = DeepSearchVisitor(new_function, self.origin + offset, arg_index)
                scanner.apply_to(new_function.body, None)
                self.candidates.extend(scanner.candidates)
        except idaapi.DecompilationFailure:
            print "[ERROR] Ida failed to decompile function"
예제 #11
0
    def create(cfunc, cexpr):
        if cexpr.op == idaapi.cot_call:
            e = cexpr
        elif cexpr.op == idaapi.cot_cast and cexpr.x.op == idaapi.cot_call:
            e = cexpr.x
        else:
            return

        func_name = idaapi.get_short_name(e.x.obj_ea)
        if "malloc" in func_name or "operator new" in func_name:
            carg = e.a[0]
            if carg.op == idaapi.cot_num:
                size = carg.numval()
            else:
                size = 0
            result = MemoryAllocationObject(func_name, size)
            result.ea = ScanObject.get_expression_address(cfunc, e)
            return result
예제 #12
0
    def _manipulate(self, cexpr, obj):
        if self.crippled:
            logger.debug("Skipping crippled function at {}".format(
                helper.to_hex(self._cfunc.entry_ea)))
            return

        if obj.id == api.SO_GLOBAL_OBJECT:
            old_name = idaapi.get_short_name(cexpr.obj_ea)
            if settings.PROPAGATE_THROUGH_ALL_NAMES or _is_default_name(
                    old_name):
                new_name = self.__rename_with_prefix(
                    lambda x: idaapi.set_name(cexpr.obj_ea, x),
                    self.__propagated_name)
                logger.debug("Renamed global variable from {} to {}".format(
                    old_name, new_name))
        elif obj.id == api.SO_LOCAL_VARIABLE:
            lvar = self._cfunc.get_lvars()[cexpr.v.idx]
            old_name = lvar.name
            if settings.PROPAGATE_THROUGH_ALL_NAMES or _is_default_name(
                    old_name):
                new_name = self.__rename_with_prefix(
                    lambda x: self.__hx_view.rename_lvar(lvar, x, True),
                    self.__propagated_name)
                logger.debug("Renamed local variable from {} to {}".format(
                    old_name, new_name))
        elif obj.id in (api.SO_STRUCT_POINTER, api.SO_STRUCT_REFERENCE):
            struct_tinfo = cexpr.x.type
            offset = cexpr.m
            struct_tinfo.remove_ptr_or_array()
            old_name = helper.get_member_name(struct_tinfo, offset)
            if settings.PROPAGATE_THROUGH_ALL_NAMES or _is_default_name(
                    old_name):
                new_name = self.__rename_with_prefix(
                    lambda x: helper.change_member_name(
                        struct_tinfo.dstr(), offset, x),
                    self.__propagated_name)
                logger.debug("Renamed struct member from {} to {}".format(
                    old_name, new_name))
예제 #13
0
 def function_name(self):
     return idaapi.get_short_name(self.func_ea)
 def name(self):
     name = idaapi.get_short_name(self.address)
     name = name.split('(')[0]
     name = name.replace("`", '').replace(" ", '_').replace("'", '')
     return name
예제 #15
0
 def get_function_name_at(self, address):
     return idaapi.get_short_name(address)
예제 #16
0
 def _refresh_name(self):
     """
     Refresh the function name against the open database.
     """
     self.name = idaapi.get_short_name(self.address)