From e18eb5f463aae4106a2e93e2c8e3d2bdef92dad4 Mon Sep 17 00:00:00 2001 From: Michael Hunhoff Date: Mon, 31 Aug 2020 15:15:19 -0600 Subject: [PATCH] addressing PR comments --- capa/ida/helpers/__init__.py | 2 - capa/ida/plugin/__init__.py | 4 +- .../ida/plugin/capa_plugin_ida.py | 0 capa/ida/plugin/form.py | 61 +++++++++---------- doc/usage.md | 2 +- 5 files changed, 32 insertions(+), 37 deletions(-) rename capa_plugin_ida.py => capa/ida/plugin/capa_plugin_ida.py (100%) diff --git a/capa/ida/helpers/__init__.py b/capa/ida/helpers/__init__.py index a4e612e0..04c681ea 100644 --- a/capa/ida/helpers/__init__.py +++ b/capa/ida/helpers/__init__.py @@ -46,7 +46,6 @@ def is_supported_ida_version(): logger.warning( "Your IDA Pro version is: %s. Supported versions are: %s." % (version, ", ".join(SUPPORTED_IDA_VERSIONS)) ) - # capa.ida.helpers.inform_user_ida_ui(warning_msg) return False return True @@ -62,7 +61,6 @@ def is_supported_file_type(): ) logger.error(" If you don't know the input file type, you can try using the `file` utility to guess it.") logger.error("-" * 80) - # inform_user_ida_ui("capa does not support the format of this file") return False return True diff --git a/capa/ida/plugin/__init__.py b/capa/ida/plugin/__init__.py index 3dd76abc..d75cfc1e 100644 --- a/capa/ida/plugin/__init__.py +++ b/capa/ida/plugin/__init__.py @@ -20,7 +20,7 @@ class CapaExplorerPlugin(idaapi.plugin_t): # Mandatory definitions PLUGIN_NAME = "capa explorer" - PLUGIN_VERSION = "0.0.1" + PLUGIN_VERSION = "1.0.0" PLUGIN_AUTHORS = "" wanted_name = PLUGIN_NAME @@ -61,6 +61,6 @@ class CapaExplorerPlugin(idaapi.plugin_t): """ called when IDA is running the plugin as a script """ - self.form = CapaExplorerForm(self.PLUGIN_NAME, logger) + self.form = CapaExplorerForm(self.PLUGIN_NAME) self.form.Show() return True diff --git a/capa_plugin_ida.py b/capa/ida/plugin/capa_plugin_ida.py similarity index 100% rename from capa_plugin_ida.py rename to capa/ida/plugin/capa_plugin_ida.py diff --git a/capa/ida/plugin/form.py b/capa/ida/plugin/form.py index ff66a16f..26498370 100644 --- a/capa/ida/plugin/form.py +++ b/capa/ida/plugin/form.py @@ -8,32 +8,31 @@ import os import json +import logging import collections -from PyQt5 import QtGui, QtCore, QtWidgets - import idaapi +from PyQt5 import QtGui, QtCore, QtWidgets import capa.main import capa.rules import capa.ida.helpers import capa.render.utils as rutils import capa.features.extractors.ida - from capa.ida.plugin.view import CapaExplorerQtreeView +from capa.ida.plugin.hooks import CapaExplorerIdaHooks from capa.ida.plugin.model import CapaExplorerDataModel from capa.ida.plugin.proxy import CapaExplorerSortFilterProxyModel -from capa.ida.plugin.hooks import CapaExplorerIdaHooks + +logger = logging.getLogger("capa") class CapaExplorerForm(idaapi.PluginForm): - def __init__(self, name, logger): + def __init__(self, name): """ """ super(CapaExplorerForm, self).__init__() self.form_title = name - self.logger = logger - self.rule_path = "" self.parent = None @@ -61,11 +60,11 @@ class CapaExplorerForm(idaapi.PluginForm): self.view_tree.reset() - self.logger.info("form created.") + logger.info("form created.") def Show(self): """ """ - self.logger.info("form show.") + logger.info("form show.") return idaapi.PluginForm.Show( self, self.form_title, options=(idaapi.PluginForm.WOPN_TAB | idaapi.PluginForm.WCLS_CLOSE_LATER) ) @@ -74,7 +73,7 @@ class CapaExplorerForm(idaapi.PluginForm): """ form is closed """ self.unload_ida_hooks() self.ida_reset() - self.logger.info("form closed.") + logger.info("form closed.") def load_interface(self): """ load user interface """ @@ -307,23 +306,23 @@ class CapaExplorerForm(idaapi.PluginForm): rule_path = self.ask_user_directory() if not rule_path: capa.ida.helpers.inform_user_ida_ui("You must select a rules directory to use for analysis.") - self.logger.warning("no rules directory selected. nothing to do.") + logger.warning("no rules directory selected. nothing to do.") return self.rule_path = rule_path - self.logger.info("-" * 80) - self.logger.info(" Using rules from %s." % self.rule_path) - self.logger.info(" ") - self.logger.info(" You can see the current default rule set here:") - self.logger.info(" https://github.com/fireeye/capa-rules") - self.logger.info("-" * 80) + logger.info("-" * 80) + logger.info(" Using rules from %s." % self.rule_path) + logger.info(" ") + logger.info(" You can see the current default rule set here:") + logger.info(" https://github.com/fireeye/capa-rules") + logger.info("-" * 80) try: rules = capa.main.get_rules(self.rule_path) rules = capa.rules.RuleSet(rules) except (IOError, capa.rules.InvalidRule, capa.rules.InvalidRuleSet) as e: capa.ida.helpers.inform_user_ida_ui("Failed to load rules from %s" % self.rule_path) - self.logger.error("failed to load rules from %s (%s)" % (self.rule_path, e)) + logger.error("failed to load rules from %s (%s)" % (self.rule_path, e)) self.rule_path = "" return @@ -338,26 +337,24 @@ class CapaExplorerForm(idaapi.PluginForm): # warn user binary file is loaded but still allow capa to process it # TODO: check specific architecture of binary files based on how user configured IDA processors if idaapi.get_file_type_name() == "Binary file": - self.logger.warning("-" * 80) - self.logger.warning(" Input file appears to be a binary file.") - self.logger.warning(" ") - self.logger.warning( + logger.warning("-" * 80) + logger.warning(" Input file appears to be a binary file.") + logger.warning(" ") + logger.warning( " capa currently only supports analyzing binary files containing x86/AMD64 shellcode with IDA." ) - self.logger.warning( + logger.warning( " This means the results may be misleading or incomplete if the binary file loaded in IDA is not x86/AMD64." ) - self.logger.warning( - " If you don't know the input file type, you can try using the `file` utility to guess it." - ) - self.logger.warning("-" * 80) + logger.warning(" If you don't know the input file type, you can try using the `file` utility to guess it.") + logger.warning("-" * 80) capa.ida.helpers.inform_user_ida_ui("capa encountered warnings during analysis") if capa.main.has_file_limitation(rules, capabilities, is_standalone=False): capa.ida.helpers.inform_user_ida_ui("capa encountered warnings during analysis") - self.logger.info("analysis completed.") + logger.info("analysis completed.") self.doc = capa.render.convert_capabilities_to_result_document(meta, rules, capabilities) @@ -367,7 +364,7 @@ class CapaExplorerForm(idaapi.PluginForm): self.set_view_tree_default_sort_order() - self.logger.info("render views completed.") + logger.info("render views completed.") def set_view_tree_default_sort_order(self): """ set capa tree view default sort order """ @@ -465,7 +462,7 @@ class CapaExplorerForm(idaapi.PluginForm): self.view_summary.setRowCount(0) self.load_capa_results() - self.logger.info("reload complete.") + logger.info("reload complete.") idaapi.info("%s reload completed." % self.form_title) def reset(self, checked): @@ -475,7 +472,7 @@ class CapaExplorerForm(idaapi.PluginForm): """ self.ida_reset() - self.logger.info("reset completed.") + logger.info("reset completed.") idaapi.info("%s reset completed." % self.form_title) def slot_menu_bar_hovered(self, action): @@ -521,7 +518,7 @@ class CapaExplorerForm(idaapi.PluginForm): """ allow user to change rules directory """ rule_path = self.ask_user_directory() if not rule_path: - self.logger.warning("no rules directory selected. nothing to do.") + logger.warning("no rules directory selected. nothing to do.") return self.rule_path = rule_path if 1 == idaapi.ask_yn(1, "Run analysis now?"): diff --git a/doc/usage.md b/doc/usage.md index c08d651a..750721f1 100644 --- a/doc/usage.md +++ b/doc/usage.md @@ -32,7 +32,7 @@ We like to use capa to help find the most interesting parts of a program, such a ![capa explorer](img/capa_explorer.png) The plugin currently supports IDA Pro 7.1 through 7.5 with either Python 2 or Python 3. To use the plugin, install capa -by following method 2 or 3 from the [installation guide](doc/installation.md) and copy [capa_plugin_ida.py](capa_plugin_ida.py) +by following method 2 or 3 from the [installation guide](installation.md) and copy [capa_plugin_ida.py](../capa/ida/plugin/capa_plugin_ida.py) to the plugins directory of your IDA Pro installation. Following these steps you can run capa explorer in IDA Pro by navigating to `Edit > Plugins > capa explorer`. The plugin will prompt you to select a rules directory to use for analysis. You can use the [default rule set](https://github.com/fireeye/capa-rules/) or point the plugin to your own directory of rules.