Beispiel #1
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)
Beispiel #2
0
    def execute_rename(name):
        """
            This is a wrapper to execute the renaming synchronously
        """
        def get_name():
            return idc.get_name(name["address"])

        def make_name(force=False):
            """
                Thread safe renaming wrapper
            """
            def sync_ask_rename():
                """
                    Dialog asking renaming confirmation to the user
                """
                rename_flag = 0
                if force or idc.ask_yn(
                        rename_flag, "Replace %s by %s" %
                    (get_name(), name["data"])) == 1:
                    logger.debug("[x] renaming %s @ 0x%x as %s", get_name(),
                                 name["address"], name["data"])
                    ida_name.set_name(name["address"],
                                      name["data"].encode('ascii', 'ignore'),
                                      ida_name.SN_AUTO)

            return idaapi.execute_sync(sync_ask_rename, idaapi.MFF_FAST)

        old_name = get_name()
        if not name["data"]:
            return
        elif idaapi.has_dummy_name(idaapi.get_flags(
                name["address"])) or not old_name:
            make_name(force=True)
        elif get_name() != name["data"]:
            make_name()
Beispiel #3
0
    def run(self, arg):
        """
            loop through all functions, collect "self._data", then show view

            @param: arg : --
        """
        try:
            self._data = dict()
            count = idaapi.get_func_qty()
            for i in xrange(count):
                fn = idaapi.getn_func(i)
                fn_an = self.analyze_func(fn)

                # if fn_an['math']:
                # 	print 'fn: %#08x has math' % fn.startEA

                if idaapi.has_dummy_name(idaapi.getFlags(fn.startEA)):
                    self._handle_calls(fn, fn_an)

                self._handle_tags(fn, fn_an)

            if self.view:
                self.view.Close(idaapi.PluginForm.FORM_NO_CONTEXT)

            self.view = AutoREView(self._data)
            self.view.Show()
        except:
            idaapi.msg('AutoRE: error: %s\n' % traceback.format_exc())
Beispiel #4
0
 def send_names(self):
     """
         Used to send all the names to the server.
         Usecase: Previously analyzed IDB
     """
     for head in idautils.Names():
         if not idaapi.has_dummy_name(idaapi.get_flags(head[0])):
             self.skel_conn.push_name(head[0], head[1])
Beispiel #5
0
 def send_names(self):
     """
         Used to send all the names to the server.
         Usecase: Previously analyzed IDB
     """
     for head in idautils.Names():
         if not idaapi.has_dummy_name(idaapi.get_flags(head[0])):
             self.skel_conn.push_name(head[0], head[1])
Beispiel #6
0
 def __getlabel(cls, ea):
     try:
         f = idaapi.getFlags(ea)
         if idaapi.has_dummy_name(f) or idaapi.has_user_name(f):
             r, = xref.data_up(ea)
             return cls.__getarray(r)
     except TypeError:
         pass
     raise TypeError, "Unable to instantiate a switch_info_ex_t at target label : %x" % ea
Beispiel #7
0
    def renamed(self, *args):
        logger.debug("[IDB Hook] Something is renamed")
        ea, new_name, is_local_name = args
        min_ea = idc.get_inf_attr(idc.INF_MIN_EA)
        max_ea = idc.get_inf_attr(idc.INF_MAX_EA)
        if ea >= min_ea and ea <= max_ea:
            if is_local_name:
                logger.warning("Local names are unimplemented")
            else:
                auto = idaapi.has_auto_name(idaapi.get_flags(ea))
                dummy = idaapi.has_dummy_name(idaapi.get_flags(ea))
                if not dummy and not auto:
                    self.skel_conn.push_name(ea, new_name)
        else:
            logger.warning("ea outside program...")

        return ida_idp.IDB_Hooks.renamed(self, *args)
Beispiel #8
0
    def run(self, arg):
        if RDEBUG and RDEBUG_EGG:
            if not os.path.isfile(RDEBUG_EGG):
                idaapi.msg(
                    'AutoRE: Remote debug is enabled, but I cannot find the debug egg: %s'
                    % RDEBUG_EGG)
            else:
                import sys

                if RDEBUG_EGG not in sys.path:
                    sys.path.append(RDEBUG_EGG)

                import pydevd
                pydevd.settrace(RDEBUG_HOST,
                                port=RDEBUG_PORT,
                                stdoutToServer=True,
                                stderrToServer=True
                                )  # , stdoutToServer=True, stderrToServer=True

        try:
            self._data = dict()
            count = idaapi.get_func_qty()

            # pre-process of api wrapper functions
            known_refs_tags = self._preprocess_api_wrappers(count)

            for i in xrange(count):
                fn = idaapi.getn_func(i)
                fn_an = self.analyze_func(fn)

                # if fn_an['math']:
                # 	print 'fn: %#08x has math' % fn.startEA

                if idaapi.has_dummy_name(idaapi.getFlags(fn.startEA)):
                    self._handle_calls(fn, fn_an)

                known_refs = known_refs_tags.get(fn.startEA)
                self._handle_tags(fn, fn_an, known_refs)

            if self.view:
                self.view.Close(idaapi.PluginForm.FORM_NO_CONTEXT)
            self.view = AutoREView(self._data)
            self.view.Show()
        except:
            idaapi.msg('AutoRE: error: %s\n' % traceback.format_exc())
Beispiel #9
0
def GetNameFlags(name, ea):
    flags = 0
    # we don't know what name_value is...
    name_value, _name_value = idaapi.get_name_value(ea, name)

    # 	if(addr != ea):
    # 		if(addr == (ea | 0x100000000) or addr == (ea & 0xFFFFFFFF)):
    # 			logger.warn("(IDA bug) get_name_value returned bad address : 0x%016X (instead of 0x%016X)" % (addr, ea))
    # 		else:
    # 			logger.warn("get_name_value returned bad address : "\
    # "0x%016X (instead of 0x%016X), using idc.SN_CHECK" % (addr, ea))
    # return default value used by MakeName
    # 			return idc.SN_CHECK

    if name_value == idaapi.NT_LOCAL:
        # see name.hpp : LOCAL names can not be public nor weak, and are not listed
        flags |= idaapi.SN_LOCAL | idaapi.SN_NON_PUBLIC | idaapi.SN_NON_WEAK | idaapi.SN_NOLIST
    else:
        if idaapi.is_public_name(ea):
            flags |= idaapi.SN_PUBLIC
        else:
            flags |= idaapi.SN_NON_PUBLIC

        if idaapi.is_weak_name(ea):
            flags |= idaapi.SN_WEAK
        else:
            flags |= idaapi.SN_NON_WEAK

        if idaapi.is_in_nlist(ea) is False:
            flags |= idaapi.SN_NOLIST

    ida_flags = idc.GetFlags(ea)

    if idaapi.has_user_name(ida_flags) or idc.hasUserName(ida_flags):
        flags |= idc.SN_NON_AUTO
    elif idaapi.has_auto_name(ida_flags):
        flags |= idc.SN_AUTO
    elif idaapi.has_dummy_name(ida_flags):
        # names like "dword_XXXX"
        flags |= idc.SN_AUTO
    else:
        logger.debug("name is not user nor auto?? at 0x%016X : 0x%08X" % (ea, ida_flags))

    return flags
Beispiel #10
0
def get_symbol_name(from_ea, ea=None, allow_dummy=False):
    if ea is None:
        ea = from_ea

    global _FORCED_NAMES
    if ea in _FORCED_NAMES:
        return _FORCED_NAMES[ea]

    flags = idc.get_full_flags(ea)
    if not allow_dummy and idaapi.has_dummy_name(flags):
        return ""

    name = ""
    try:
        name = name or idc.get_name(ea, 0)  #calc_gtn_flags(from_ea, ea))
    except:
        pass

    try:
        name = name or idc.get_func_name(ea)
    except:
        pass

    return name
Beispiel #11
0
def get_symbol_name(from_ea, ea=None, allow_dummy=False):
    if ea is None:
        ea = from_ea

    global _FORCED_NAMES
    if ea in _FORCED_NAMES:
        return _FORCED_NAMES[ea]

    flags = idc.GetFlags(ea)
    if not allow_dummy and idaapi.has_dummy_name(flags):
        return ""

    name = ""
    try:
        name = name or idc.GetTrueNameEx(from_ea, ea)
    except:
        pass

    try:
        name = name or idc.GetFunctionName(ea)
    except:
        pass

    return name
Beispiel #12
0
def get_symbol_name(from_ea, ea=None, allow_dummy=False):
  if ea is None:
    ea = from_ea

  global _FORCED_NAMES
  if ea in _FORCED_NAMES:
    return _FORCED_NAMES[ea]

  flags = idc.get_full_flags(ea)
  if not allow_dummy and idaapi.has_dummy_name(flags):
    return ""

  name = ""
  try:
    name = name or idc.get_name(ea, 0) #calc_gtn_flags(from_ea, ea))
  except:
    pass

  try:
    name = name or idc.get_func_name(ea)
  except:
    pass

  return name
Beispiel #13
0
def get_symbol_name(from_ea, ea=None, allow_dummy=False):
  if ea is None:
    ea = from_ea

  global _FORCED_NAMES
  if ea in _FORCED_NAMES:
    return _FORCED_NAMES[ea]

  flags = idc.GetFlags(ea)
  if not allow_dummy and idaapi.has_dummy_name(flags):
    return ""

  name = ""
  try:
    name = name or idc.GetTrueNameEx(from_ea, ea)
  except:
    pass

  try:
    name = name or idc.GetFunctionName(ea)
  except:
    pass

  return name
Beispiel #14
0
    def execute_rename(name):
        """
            This is a wrapper to execute the renaming synchronously
        """
        def get_name():
            return idc.get_name(name["address"])

        def make_name(force=False):
            """
                Thread safe renaming wrapper
            """
            def sync_ask_rename():
                """
                    Dialog asking renaming confirmation to the user
                """
                rename_flag = 0
                if force or idc.ask_yn(rename_flag, "Replace %s by %s" %
                                       (get_name(), name["data"])) == 1:
                    logger.debug("[x] renaming %s @ 0x%x as %s",
                                 get_name(),
                                 name["address"],
                                 name["data"])
                    ida_name.set_name(
                        name["address"], name["data"].encode(
                            'ascii', 'ignore'),
                        ida_name.SN_AUTO)
            return idaapi.execute_sync(
                sync_ask_rename,
                idaapi.MFF_FAST)
        old_name = get_name()
        if not name["data"]:
            return
        elif idaapi.has_dummy_name(idaapi.get_flags(name["address"])) or not old_name:
            make_name(force=True)
        elif get_name() != name["data"]:
            make_name()
Beispiel #15
0
        def activate(self, ctx):
            if self.menu_title == MenuAskEntryId:
                self.outer_self.mixto.entry_id = idaapi.ask_str(
                    "", 1000, "Mixto Entry Id")

            else:
                if self.outer_self.mixto.entry_id is None:
                    self.outer_self.mixto.entry_id = idaapi.ask_str(
                        "", 1000, "Mixto Entry Id")

            if self.menu_title == MenuAllFunc:
                all_func = ""
                # Get count of all functions in the binary
                count = idaapi.get_func_qty()

                for i in range(count):
                    fn = idaapi.getn_func(i)

                    # Function should not have dummy name such as sub_*
                    # and should not start with underscore (possible library functions)
                    if not idaapi.has_dummy_name(get_flags_at(
                            start_ea_of(fn))) and not idaapi.get_func_name(
                                start_ea_of(fn)).startswith("_"):
                        all_func += "{} @ 0x{:x}\n".format(
                            idaapi.get_func_name(start_ea_of(fn)),
                            start_ea_of(fn))
                self.outer_self.mixto.AddCommit(all_func,
                                                self.outer_self.mixto.entry_id,
                                                "(IDA) All Functions")

            elif self.menu_title == MenuImports:
                global AllImports
                AllImports = ""
                # Get count of all import modules in the binary
                count = idaapi.get_import_module_qty()

                for i in range(count):
                    module_name = idaapi.get_import_module_name(i)

                    AllImports += "{}:\n".format(module_name)
                    idaapi.enum_import_names(i, imports_cb)
                self.outer_self.mixto.AddCommit(AllImports,
                                                self.outer_self.mixto.entry_id,
                                                "(IDA) All Imports")

            elif self.menu_title == MenuDecFunc:
                addr_current = idc.get_screen_ea()
                addr_func = idaapi.get_func(addr_current)

                if not addr_func:
                    idaapi.msg("Place cursor inside a function!")
                    return False
                else:
                    err = None
                    out = str(idaapi.decompile(addr_func))
                    # print(out)
                    self.outer_self.mixto.AddCommit(
                        str(out),
                        self.outer_self.mixto.entry_id,
                        "(IDA) Function Decompilation {}".format(
                            idc.GetFunctionName(addr_func.startEA)),
                    )

            elif self.menu_title == MenuExports:
                all_exports = ""
                for entry in idautils.Entries():
                    _, ord, ea, name = entry
                    if not name:
                        all_exports += "0x{:x}: ord#{}\n".format(ea, ord)
                    else:
                        all_exports += "0x{:x}: {} ord#{}\n".format(
                            ea, name, ord)
                self.outer_self.mixto.AddCommit(all_exports,
                                                self.outer_self.mixto.entry_id,
                                                "(IDA) All Exports")

            elif self.menu_title == MenuAllComments:
                addr_current = idc.get_screen_ea()
                addr_func = idaapi.get_func(addr_current)

                uniq_comments = {}
                comments = []
                for ea in range(addr_func.startEA, addr_func.endEA):
                    comment = idaapi.get_cmt(ea, 0)
                    if comment is not None:
                        # hacky way to make sure only uniq comments are added
                        if uniq_comments.get(comment) == 1:
                            pass
                        else:
                            print(uniq_comments)
                            comments.append("{offset} {value}".format(
                                offset=hex(ea), value=comment))
                            print("here")
                            uniq_comments[comment] = 1
                if len(comments) > 0:
                    out = "\n".join(comments)
                    self.outer_self.mixto.AddCommit(
                        str(out),
                        self.outer_self.mixto.entry_id,
                        "(IDA) Function Comments {}".format(
                            idc.GetFunctionName(addr_func.startEA)),
                    )

                else:
                    raise TypeError("No comments found")

            return True
Beispiel #16
0
        def activate(self, ctx):
            if self.menu_title == MenuAskEntryId:
                self.outer_self.mixto.entry_id = idaapi.ask_str(
                    "", 1000, "Mixto Entry Id")

            else:
                if self.outer_self.mixto.entry_id is None:
                    self.outer_self.mixto.entry_id = idaapi.ask_str(
                        "", 1000, "Mixto Entry Id")

            if self.menu_title == MenuAllFunc:
                all_func = ""
                # Get count of all functions in the binary
                count = idaapi.get_func_qty()

                for i in range(count):
                    fn = idaapi.getn_func(i)

                    # Function should not have dummy name such as sub_*
                    # and should not start with underscore (possible library functions)
                    if not idaapi.has_dummy_name(get_flags_at(
                            start_ea_of(fn))) and not idaapi.get_func_name(
                                start_ea_of(fn)).startswith("_"):
                        all_func += "{} @ 0x{:x}\n".format(
                            idaapi.get_func_name(start_ea_of(fn)),
                            start_ea_of(fn))
                self.outer_self.mixto.AddCommit(all_func,
                                                self.outer_self.mixto.entry_id,
                                                "(IDA) All Functions")

            elif self.menu_title == MenuImports:
                global AllImports
                AllImports = ""
                # Get count of all import modules in the binary
                count = idaapi.get_import_module_qty()

                for i in range(count):
                    module_name = idaapi.get_import_module_name(i)

                    AllImports += "{}:\n".format(module_name)
                    idaapi.enum_import_names(i, imports_cb)
                self.outer_self.mixto.AddCommit(AllImports,
                                                self.outer_self.mixto.entry_id,
                                                "(IDA) All Imports")

            elif self.menu_title == MenuDecFunc:
                addr_current = idc.get_screen_ea()
                addr_func = idaapi.get_func(addr_current)

                if not addr_func:
                    idaapi.msg("Place cursor inside a function!")
                    return False
                else:
                    err = None
                    out = ida_hexrays.decompile_func(addr_func, err)
                    # print(out)
                    self.outer_self.mixto.AddCommit(
                        str(out),
                        self.outer_self.mixto.entry_id,
                        "(IDA) Function Decompilation",
                    )

            elif self.menu_title == MenuExports:
                all_exports = ""
                for entry in idautils.Entries():
                    _, ord, ea, name = entry
                    if not name:
                        all_exports += "0x{:x}: ord#{}\n".format(ea, ord)
                    else:
                        all_exports += "0x{:x}: {} ord#{}\n".format(
                            ea, name, ord)
                self.outer_self.mixto.AddCommit(all_exports,
                                                self.outer_self.mixto.entry_id,
                                                "(IDA) All Exports")

            elif self.menu_title == MenuAllComments:
                raise NotImplementedError("Comments not yet implemented TODO")

            return True
Beispiel #17
0
def name(ea=None, *args, **kwds):
    """name(ea), name(ea, string)
    First syntax returns the name at the given address.
    Second syntax changes the name at the given address.
    """
    if len(args) > 1:
        raise TypeError, "{:s}() takes exactly {!r} arguments ({:d} given)".format(
            'name', (1, 2),
            len(args) + 1 + len(kwds))
    if kwds and tuple(kwds.keys()) != ('string', ):
        raise TypeError, "{:s}() got an unexpected keyword argument '{:s}'".format(
            'name',
            filter(lambda n: n != 'string', kwds.keys())[0])

    ea = ui.current.address() if ea is None else ea
    if len(args) == 1 or kwds.has_key('string'):
        string = kwds.get('string', args[0])
        assert idaapi.SN_NOCHECK == 0, '%s.name : idaapi.SN_NOCHECK != 0' % __name__
        SN_NOLIST = idaapi.SN_NOLIST
        SN_LOCAL = idaapi.SN_LOCAL
        SN_NON_PUBLIC = idaapi.SN_NON_PUBLIC

        if idaapi.has_any_name(idaapi.getFlags(ea)):
            pass

        flags = idaapi.SN_NON_AUTO
        flags |= 0 if idaapi.is_in_nlist(ea) else idaapi.SN_NOLIST
        flags |= idaapi.SN_WEAK if idaapi.is_weak_name(
            ea) else idaapi.SN_NON_WEAK
        flags |= idaapi.SN_PUBLIC if idaapi.is_public_name(
            ea) else idaapi.SN_NON_PUBLIC

        try:
            function.top(ea)
            flags |= idaapi.SN_LOCAL
        except Exception:
            flags &= ~idaapi.SN_LOCAL

        try:
            # check if we're a label of some kind
            f = idaapi.getFlags(ea)
            if idaapi.has_dummy_name(f) or idaapi.has_user_name(f):
                # that is referenced by an array with a correctly sized pointer inside it
                (r, sidata), = ((r, type.array(r)) for r in xref.data_up(ea))
                if config.bits() == sidata.itemsize * 8 and ea in sidata:
                    # which we check to see if it's a switch_info_t
                    si, = (idaapi.get_switch_info_ex(r)
                           for r in xref.data_up(r))
                    if si is not None:
                        # because it's name has it's local flag cleared
                        flags ^= idaapi.SN_LOCAL
        except:
            pass

        res, ok = name(ea), idaapi.set_name(ea, string or "", flags)
        tag(ea, 'name', string)
        assert ok, '%s.name : unable to call idaapi.set_name(%x, %r, %x)' % (
            __name__, ea, string, flags)
        return res

    try:
        return tag(ea, 'name')
    except KeyError:
        pass
    return None