Example #1
0
 def add_fast_dict_from_all_vuln_func(self):
     mgr_t = FESinkFuncMgr()
     for func_name, xref_list in mgr_t.gen_sink_func_xref():
         if not func_name in self.vuln_func_fast_dict:
             tag = SINK_FUNC[func_name]['tag']
             print('func_name: ', func_name)
             print('xref_list: ', len(xref_list))
             if tag == FUNC_TAG['PRINTF']:
                 items = printf_func_analysis(func_name, xref_list)
                 self.add_fast_dict_from_items(items)
             elif tag == FUNC_TAG['STRING']:
                 items = str_func_analysis(func_name, xref_list)
                 self.add_fast_dict_from_items(items)
             elif tag == FUNC_TAG['SCANF']:
                 items = scanf_func_analysis(func_name, xref_list)
                 self.add_fast_dict_from_items(items)
             elif tag == FUNC_TAG['SYSTEM']:
                 items = system_func_analysis(func_name, xref_list)
                 self.add_fast_dict_from_items(items)
             elif tag == FUNC_TAG['MEMORY']:
                 items = mem_func_analysis(func_name, xref_list)
                 self.add_fast_dict_from_items(items)
             else:
                 FELogger.info("未支持函数%s" % func_name)
         else:
             continue
Example #2
0
    def btn_get_one_sink_func_xref(self, code=0):
        """
        查看某个危险函数调用地址
        """

        tgt_t = ida_kernwin.ask_str('', 0, '请输入要查看的危险函数名')
        if tgt_t in SINK_FUNC:
            cols = [['', 0 | ida_kernwin.Choose.CHCOL_DEC],
                    ['函数名', 10 | ida_kernwin.Choose.CHCOL_PLAIN],
                    ['函数地址', 10 | ida_kernwin.Choose.CHCOL_HEX]]
            items = []

            mgr_t = FESinkFuncMgr()
            xref_list = mgr_t.get_one_func_xref(tgt_t)

            if not xref_list:
                FELogger.warn("未找到函数%s" % tgt_t)
                return

            tmp_list = []
            for xref_addr in xref_list:
                data = AnalysisChooseData(vuln=0, name=tgt_t, ea=xref_addr)
                items.append(data)
                tmp_list.append(xref_addr)
            self.sink_func_xref_dict[tgt_t] = tmp_list

            chooser = AnalysisChooser(title='危险函数调用地址', cols=cols, item=items)
            chooser.Show()
        else:
            FELogger.warn("未支持函数")
Example #3
0
    def btn_imp_ghidra_funcs(self, code=0):
        """
        导入Ghidra函数列表
        """
        ghidra_filepath = os.path.join(os.getcwd(), 'ghidra_func_addrs.csv')
        ghidra_path = ida_kernwin.ask_str(ghidra_filepath, 0,
                                          '导入的Ghidra导出函数文件路径')

        func_addrs = list(idautils.Functions())
        make_func_addrs = []
        if ghidra_path and ghidra_path != '':
            if os.path.exists(ghidra_path):
                with open(ghidra_path, 'rb') as f:
                    next(f)
                    reader = csv.reader(f)
                    for row in reader:
                        addr = int(row[0].strip('\"'), 16)
                        if ida_funcs.add_func(addr) == True:
                            make_func_addrs.append(addr)
                        else:
                            if addr not in func_addrs:
                                FELogger.info("创建函数%s失败" % hexstr(addr))
                FELogger.info("Ghidra导出函数文件:%s,已导入" % ghidra_path)
            else:
                FELogger.erro("未找到Ghidra导出函数文件:%s" % ghidra_path)
        else:
            FELogger.warn("请输入Ghidra导出函数文件路径")

        FELogger.info("成功创建%d个新函数" % len(make_func_addrs))
Example #4
0
    def btn_del_all_vuln_bpt(self, code=0):
        """删除断点 所有危险函数漏洞地址"""
        for xref_addr_t in reduce(lambda x, y: x + y,
                                  self.vuln_func_fast_dict.values()):
            ida_dbg.del_bpt(xref_addr_t)

        FELogger.info('已删除断点:危险函数漏洞分析(全部)')
Example #5
0
    def btn_add_all_vuln_bpt(self, code=0):
        """添加断点 所有危险函数漏洞地址"""
        self.add_fast_dict_from_all_vuln_func()

        for xref_addr_t in reduce(lambda x, y: x + y,
                                  self.vuln_func_fast_dict.values()):
            ida_dbg.add_bpt(xref_addr_t, 0, idc.BPT_DEFAULT)

        FELogger.info('已添加断点:危险函数漏洞分析(全部)')
Example #6
0
 def btn_del_one_vuln_bpt(self, code=0):
     """删除断点 某个危险函数漏洞地址"""
     tgt_t = ida_kernwin.ask_str('', 0, '请输入危险函数名')
     if tgt_t in SINK_FUNC:
         if tgt_t in self.vuln_func_fast_dict:
             for xref_addr_t in self.vuln_func_fast_dict[tgt_t]:
                 ida_dbg.del_bpt(xref_addr_t)
         FELogger.info("已删除断点:危险函数漏洞分析(%s)" % tgt_t)
     else:
         FELogger.warn("未支持函数")
Example #7
0
 def trace_next(self, blk, node, reg):
     """
     下一轮回溯
     """
     for ref_addr in self.get_all_ref(blk.start_ea):
         block = self.get_blk(ref_addr)
         if block:
             FELogger.info("基本块跳转\t"+hexstr(ref_addr)+"\t"+idc.generate_disasm_line(ref_addr, 0))
             node_t = self.create_tree_node(ref_addr, prev=node)
             self.dfs(node_t, reg, block)
Example #8
0
 def btn_del_tmp_func_bpt(self, code=0):
     """删除临时函数断点"""
     tgt_t = ida_kernwin.ask_str('', 0, '请输入任意函数名')
     try:
         if tgt_t in self.tmp_func_dict:
             for xref_addr_t in self.tmp_func_dict[tgt_t]:
                 ida_dbg.del_bpt(xref_addr_t)
             CUSTOM_FUNC.pop(tgt_t)
         FELogger.info("已删除断点:指定函数调用地址 %s" % tgt_t)
     except Exception:
         FELogger.warn("请输入函数名")
Example #9
0
    def add_tmp_func(self, info_only=False):
        """
        添加临时sink函数
        info_only: 在添加函数信息的同时是否添加断点
        """

        input_str = ida_kernwin.ask_text(
            0, '',
            "请输入任意函数名/函数地址,及各参数类型(none, int, str),可输入多行\n例如:\nstrcmp str str")
        try:
            rules = [x.strip() for x in input_str.strip().split('\n')]
            for rule in rules:
                tgt_t = rule.split(' ')[0].strip()
                args_rule = [x.strip() for x in rule.split(' ')[1:]]

                if not tgt_t in self.tmp_func_dict:
                    if tgt_t.startswith('0x'):
                        addr_t = int(tgt_t, 16)
                        addr_hexstr = hexstr(addr_t)
                        CUSTOM_FUNC[addr_hexstr] = {'args_rule': args_rule}
                        self.tmp_func_dict[addr_hexstr] = [addr_t]
                        if info_only == False:
                            ida_dbg.add_bpt(addr_t, 0, idc.BPT_DEFAULT)
                    else:
                        for func_addr_t in idautils.Functions():
                            func_name_t = ida_funcs.get_func_name(func_addr_t)
                            if func_name_t == tgt_t:
                                CUSTOM_FUNC[func_name_t] = {
                                    'args_rule': args_rule
                                }
                                self.tmp_func_dict[func_name_t] = []
                                for xref_addr_t in idautils.CodeRefsTo(
                                        func_addr_t, 0):
                                    self.tmp_func_dict[func_name_t].append(
                                        xref_addr_t)
                                    if info_only == False:
                                        ida_dbg.add_bpt(
                                            xref_addr_t, 0, idc.BPT_DEFAULT)
                                    else:
                                        continue
                                break
                            else:
                                continue
                else:
                    CUSTOM_FUNC[tgt_t] = {'args_rule': args_rule}
                    for xref_addr_t in self.tmp_func_dict[tgt_t]:
                        if info_only == False:
                            ida_dbg.add_bpt(xref_addr_t, 0, idc.BPT_DEFAULT)
                        else:
                            continue
                FELogger.info("已添加断点:%s" % rule)
        except Exception as e:
            FELogger.info("输入信息有误:%s" % e)
Example #10
0
    def jump_in_hex(self):
        ea = self.ea
        if not ea or not ida_bytes.is_loaded(ea):
            FELogger.warn("地址错误")
            return

        widget = self.find_hex_view()
        if not widget:
            FELogger.warn("无法找到十六进制窗口")
            return

        self.jumpto_in_view(widget, ea)
Example #11
0
    def jump_in_new_window(self):
        ea = self.ea
        if not ea or not ida_bytes.is_loaded(ea):
            FELogger.warn("地址错误")
            return

        window_name = "D-0x%x" % ea
        widget = ida_kernwin.open_disasm_window(window_name)
        if widget:
            self.jumpto_in_view(widget, ea)
        else:
            FELogger.warn("创建新窗口失败")
Example #12
0
    def jump_in_disassembly(self):
        ea = self.ea
        if not ea or not ida_bytes.is_loaded(ea):
            FELogger.warn("地址错误")
            return

        widget = self.find_disass_view()
        if not widget:
            FELogger.warn("无法找到反汇编窗口")
            return

        self.jumpto_in_view(widget, ea)
Example #13
0
 def get_all_bpt_list(self):
     """
     获取所有断点的地址列表
     """
     bpt_list = []
     bpt_num = ida_dbg.get_bpt_qty()
     bpt_t = ida_dbg.bpt_t()
     for i in range(bpt_num):
         if ida_dbg.getn_bpt(i, bpt_t) == True:
             bpt_list.append(bpt_t.ea)
         else:
             FELogger.info("获取断点失败 %d" % i)
     return bpt_list
Example #14
0
    def activate(self, ctx):
        if self.get_xdbg_hook_status():
            FELogger.info('关闭调试事件记录')
            self.dbg_hook.unhook()
        else:
            FELogger.info('启用调试事件记录')

            if ida_kernwin.ask_yn(0, '是否单步调试?') == 1:
                self.dbg_hook.step_dbg = True
            else:
                self.dbg_hook.step_dbg = False
            self.dbg_hook.hook()

        self.set_xdbg_hook_status()
Example #15
0
def system_func_analysis(func_name, xref_list):
    """
    system系列函数漏洞分析    
    """

    vuln_flag = 0
    addr1 = 0
    str1 = ''

    func_name_t = func_name
    xref_list_t = xref_list
    items = []
    vuln_rule = SINK_FUNC[func_name_t]['vuln_rule']
    vuln_reg = vuln_rule[0]['vuln_regs'][0]

    FELogger.info('检测%s漏洞' % vuln_rule[0]['vuln_type'])
    for xref_addr_t in xref_list_t:
        FELogger.info("从%s回溯来源地址%s" % (hexstr(xref_addr_t), vuln_reg))
        tracer = FEArgsTracer(xref_addr_t, vuln_reg)
        source_addr = tracer.run()
        print('source_addr: ', source_addr)
        # 判断是否找到目标地址
        if source_addr == []:
            FELogger.info("目标地址未找到%s" % hexstr(xref_addr_t))
            vuln_flag = 1
        else:
            for cmd_addr in source_addr:
                addr1 = cmd_addr
                # 判断字符串是否来自内存
                if idc.get_operand_type(cmd_addr, 1) == ida_ua.o_mem:
                    cmd_str = FEStrMgr.get_mem_string(cmd_addr)
                    # 判断是否找到字符串
                    if cmd_str == []:
                        FELogger.info("硬编码命令未找到%s" % hexstr(xref_addr_t))
                        vuln_flag = 1
                    else:
                        vuln_flag = 0
                        str1 = cmd_str[0]
                else:
                    FELogger.info("命令来自外部%s" % hexstr(xref_addr_t))
                    vuln_flag = 1

        data = AnalysisChooseData(vuln=vuln_flag,
                                  name=func_name_t,
                                  ea=xref_addr_t,
                                  addr1=addr1,
                                  str1=str1)
        items.append(data)
    return items
Example #16
0
    def btn_import_all_bpt_addr(self, code=0):
        """
        导入离线断点
        """
        cur_workpath = os.getcwd()
        csv_filepath = os.path.join(
            cur_workpath, '%s_bpt.csv' % ida_nalt.get_root_filename())

        if os.path.exists(csv_filepath):
            with open(csv_filepath, 'r') as f:
                next(f)
                reader = csv.reader(f)
                for row in reader:
                    ida_dbg.add_bpt(int(row[0], 16), 0, idc.BPT_DEFAULT)
            FELogger.info("导入断点完成:%s" % csv_filepath)
        else:
            FELogger.warn("文件不存在:%s" % csv_filepath)
Example #17
0
    def btn_export_all_bpt_addr(self, code=0):
        """
        导出离线断点
        """
        cur_workpath = os.getcwd()
        csv_filepath = os.path.join(
            cur_workpath, '%s_bpt.csv' % ida_nalt.get_root_filename())

        bpt_list = self.get_all_bpt_list()
        bpt_list = [[format(bpt, '#010x')[2:]] for bpt in bpt_list]

        header = ['breakpoints']
        with open(csv_filepath, 'w', newline='') as f:
            ff = csv.writer(f)
            ff.writerow(header)
            ff.writerows(bpt_list)

        FELogger.info("导出断点完成:%s" % csv_filepath)
Example #18
0
    def get_after_run_info(self, args_rule):
        """
        获取某函数执行后的返回值
        # TODO 添加参数的变化
        """

        runtime_info = {}
        args = self.get_xdbg_reg_var()

        rv = ida_idd.regval_t()
        ida_dbg.get_reg_val('PC', rv)
        FELogger.console('PC: %s' % hexstr(rv.ival))

        arg_v = args[arm_regset.ret].ival
        #str_t = FEStrMgr.get_string_from_mem(arg_v)
        #runtime_info[arm_regset.ret] = [hexstr(arg_v), repr(str_t)]
        #FELogger.console('ret: %s => %s' % (hexstr(arg_v), repr(str_t)))
        FELogger.console('%s: %s' % (arm_regset.ret, hexstr(arg_v)))
        return runtime_info
Example #19
0
 def btn_dfs_test_2(self, code=0):
     tgt_t = ida_kernwin.ask_str('', 0, '请输入函数名')
     reg_t = ida_kernwin.ask_str('', 0, '请输入回溯寄存器')
     if (tgt_t and tgt_t != '') and (reg_t and reg_t != ''):
         for func_addr_t in idautils.Functions():
             func_name_t = ida_funcs.get_func_name(func_addr_t)
             if func_name_t == tgt_t:
                 for xref_addr_t in idautils.CodeRefsTo(func_addr_t, 0):
                     if ida_funcs.get_func(xref_addr_t):
                         FELogger.info("从地址%s回溯寄存器%s" %
                                       (hexstr(xref_addr_t), reg_t))
                         tracer = FEArgsTracer(xref_addr_t,
                                               reg_t,
                                               max_node=256)
                         source_addr = tracer.run()
                         print('source_addr: ', source_addr)
                 break
         else:
             FELogger.warn("请输入函数名和寄存器")
Example #20
0
 def dfs(self, node, reg, blk):
     """深度优先搜索
     node: 当前节点
     reg: 回溯寄存器
     blk: 当前基本块
     """
     blk_t = blk
     if self.get_node_nums() < self.max_node:    # 避免路径爆炸
         if self.push_cache_node(node['addr'], reg): # 避免重复,加快速度
             cur_t, reg_t = self.trace_block(blk_t, node, reg)
             if reg_t:
                 # 如果返回一个新的寄存器,开启下一轮回溯
                 self.trace_next(blk_t, node, reg_t)
             else:
                 self.cache['addr'].add(cur_t)
         else:
             FELogger.info("该块已经回溯,取消操作")
     else:
         FELogger.info("超出最大回溯块数量")
Example #21
0
    def add_or_del_all_xref_bpt(self, is_add):
        if is_add == True:
            action = idc.add_bpt
            act_info = '添加'
        else:
            action = idc.del_bpt
            act_info = '删除'

        if self.sink_func_xref_dict == {}:
            mgr_t = FESinkFuncMgr()
            for func_name, xref_list in mgr_t.gen_sink_func_xref():
                tmp_list = []
                for xref_addr_t in xref_list:
                    tmp_list.append(xref_addr_t)
                    action(xref_addr_t)
                self.sink_func_xref_dict[func_name] = tmp_list
        else:
            for xref_addr_t in reduce(lambda x, y: x + y,
                                      self.sink_func_xref_dict.values()):
                action(xref_addr_t)
        FELogger.info('已%s断点:危险函数调用地址(全部)' % act_info)
Example #22
0
    def fix_len_args_run_info(self, args_rule, args):
        """
        获取定长参数函数的寄存器信息
        """

        run_info = {}

        for idx in range(len(args_rule)):
            str_reg = 'R%s' % idx
            arg_t = args_rule[idx]
            if arg_t == 'none':  # 跳过无关的参数
                continue
            elif arg_t == 'int':
                run_info[str_reg] = [hexstr(args[str_reg].ival), None]
                FELogger.console('%s: %s' %
                                 (str_reg, hexstr(args[str_reg].ival)))
            elif arg_t == 'str':
                arg_v = args[str_reg].ival
                if arg_v != 0:
                    str_t = FEStrMgr.get_string_from_mem(arg_v)
                else:
                    str_t = ''
                run_info[str_reg] = [hexstr(arg_v), repr(str_t)]
                FELogger.console('%s: %s => %s' %
                                 (str_reg, hexstr(arg_v), repr(str_t)))
            else:
                run_info[str_reg] = [hexstr(args[str_reg].ival), None]
                FELogger.console('%s: %s' %
                                 (str_reg, hexstr(args[str_reg].ival)))

        return run_info
Example #23
0
    def add_or_del_one_xref_bpt(self, is_add):
        if is_add == True:
            action = idc.add_bpt
            act_info = '添加'
        else:
            action = idc.del_bpt
            act_info = '删除'

        tgt_t = ida_kernwin.ask_str('', 0, '请输入危险函数名')
        if tgt_t in SINK_FUNC:
            if not tgt_t in self.sink_func_xref_dict:
                mgr_t = FESinkFuncMgr()
                xref_list = mgr_t.get_one_func_xref(tgt_t)

                if not xref_list:
                    FELogger.warn("未找到函数%s" % tgt_t)
                    return

                tmp_list = []
                for xref_addr in xref_list:
                    tmp_list.append(xref_addr)
                    action(xref_addr)
                self.sink_func_xref_dict[tgt_t] = tmp_list
            else:
                for xref_addr_t in self.sink_func_xref_dict[tgt_t]:
                    action(xref_addr_t)
            FELogger.info("已%s断点:危险函数调用地址(%s)" % (act_info, tgt_t))
        else:
            FELogger.warn("未支持函数")
Example #24
0
    def get_before_run_info(self, args_rule):
        """
        获取某函数执行前的寄存器信息
        """

        runtime_info = {}
        args = self.get_xdbg_reg_var()

        rv = ida_idd.regval_t()
        ida_dbg.get_reg_val('PC', rv)
        FELogger.console('PC: %s' % hexstr(rv.ival))

        # 判断是否包含变长参数
        if args_rule[-1] == '...':
            runtime_info = self.var_len_args_run_info(args_rule, args)
        elif args_rule[-1] == 'va_list':
            # TODO 支持va_list参数解析,暂时同“...”
            runtime_info = self.var_len_args_run_info(args_rule, args)
        else:
            runtime_info = self.fix_len_args_run_info(args_rule, args)

        return runtime_info
Example #25
0
    def btn_add_one_vuln_bpt(self, code=0):
        """添加断点 某个危险函数漏洞地址"""
        tgt_t = ida_kernwin.ask_str('', 0, '请输入危险函数名')
        if tgt_t in SINK_FUNC:
            if not tgt_t in self.vuln_func_fast_dict:
                mgr_t = FESinkFuncMgr()
                xref_list = mgr_t.get_one_func_xref(tgt_t)
                tag = SINK_FUNC[tgt_t]['tag']

                if not xref_list:
                    FELogger.warn("未找到函数%s" % tgt_t)
                    return

                if tag == FUNC_TAG['PRINTF']:
                    items = printf_func_analysis(tgt_t, xref_list)
                    self.add_fast_dict_from_items(items)
                elif tag == FUNC_TAG['STRING']:
                    items = str_func_analysis(tgt_t, xref_list)
                    self.add_fast_dict_from_items(items)
                elif tag == FUNC_TAG['SCANF']:
                    items = scanf_func_analysis(tgt_t, xref_list)
                    self.add_fast_dict_from_items(items)
                elif tag == FUNC_TAG['SYSTEM']:
                    items = system_func_analysis(tgt_t, xref_list)
                    self.add_fast_dict_from_items(items)
                elif tag == FUNC_TAG['MEMORY']:
                    items = mem_func_analysis(tgt_t, xref_list)
                    self.add_fast_dict_from_items(items)
                else:
                    FELogger.info("未支持函数%s" % tgt_t)

            if tgt_t in self.vuln_func_fast_dict:
                for xref_addr_t in self.vuln_func_fast_dict[tgt_t]:
                    ida_dbg.add_bpt(xref_addr_t, 0, idc.BPT_DEFAULT)

            FELogger.info('已添加断点:危险函数漏洞分析(%s)' % tgt_t)
        else:
            FELogger.warn("未支持函数")
Example #26
0
    def btn_dfs_test_1(self, code=0):
        addr_t = ida_kernwin.ask_str('', 0, '请输入回溯起点地址')
        reg_t = ida_kernwin.ask_str('', 0, '请输入回溯寄存器')
        if (addr_t and addr_t != '') and (reg_t and reg_t != ''):
            try:
                addr_t = int(addr_t, 16)
            except Exception:
                FELogger.warn("无效地址")
                return

            FELogger.info("从地址%s回溯寄存器%s" % (hexstr(addr_t), reg_t))
            tracer = FEArgsTracer(addr_t, reg_t)
            source_addr = tracer.run()
            print('source_addr: ', source_addr)
        else:
            FELogger.warn("请输入起点地址和寄存器")
Example #27
0
        def do_export():
            st = ida_auto.set_ida_state(idc.IDA_STATUS_WORK)
            xml = XmlExporter(1)

            try:
                try:
                    xml.export_xml()
                    FELogger.info("已导出IDA数据到XML")
                except Cancelled:
                    ida_kernwin.hide_wait_box()
                    FELogger.warn("已取消XML导出")
                except Exception as e:
                    ida_kernwin.hide_wait_box()
                    FELogger.warn("导出XML失败 %s" % e)
            finally:
                xml.cleanup()
                ida_auto.set_ida_state(st)
Example #28
0
    def check_src_reg(xref_addr_t, src_reg, siz_addr_t=0):
        vuln_flag = 0
        addr1 = 0
        str1 = ''

        if siz_addr_t == 0:
            str_siz_addr = ''
        else:
            str_siz_addr = hexstr(siz_addr_t)

        FELogger.info("从%s回溯来源地址%s" % (hexstr(xref_addr_t), src_reg))
        src_tracer = FEArgsTracer(xref_addr_t, src_reg)
        src_source_addr = src_tracer.run()
        print('src_source_addr: ', src_source_addr)
        # 判断是否找到字符串来源地址
        if src_source_addr == []:
            FELogger.info("未找到目标地址%s" % hexstr(xref_addr_t))
            vuln_flag = 1
        else:
            for src_addr in src_source_addr:
                addr1 = src_addr
                src_str = FEStrMgr.get_mem_string(src_addr)
                # 判断是否找到字符串
                if src_str == []:
                    FELogger.info('来源字符串未找到%s' % hexstr(xref_addr_t))
                    vuln_flag = 1
                else:
                    # 判断来源地址是否为内存
                    str1 = src_str[0]
                    if idc.get_operand_type(src_addr, 1) != ida_ua.o_mem:
                        vuln_flag = 1
                    else:
                        vuln_flag = 0

        data = AnalysisChooseData(vuln=vuln_flag,
                                  name=func_name_t,
                                  ea=xref_addr_t,
                                  addr1=addr1,
                                  str1=str1,
                                  other1=str_siz_addr)
        items.append(data)
Example #29
0
def PLUGIN_ENTRY():
    try:
        return Firmeye()
    except Exception as e:
        FELogger.erro(e.__str__())
Example #30
0
 def banner(self):
     FELogger.console(PLUGIN_HELP)
     FELogger.console(BANNER_MSG)