diff --git a/capa/ida/plugin/__init__.py b/capa/ida/plugin/__init__.py index d75cfc1e..da64ece2 100644 --- a/capa/ida/plugin/__init__.py +++ b/capa/ida/plugin/__init__.py @@ -13,22 +13,22 @@ import idaapi from capa.ida.helpers import is_supported_file_type, is_supported_ida_version from capa.ida.plugin.form import CapaExplorerForm -logger = logging.getLogger("capa") +logger = logging.getLogger(__name__) class CapaExplorerPlugin(idaapi.plugin_t): # Mandatory definitions - PLUGIN_NAME = "capa explorer" + PLUGIN_NAME = "FLARE capa plugin" PLUGIN_VERSION = "1.0.0" - PLUGIN_AUTHORS = "" + PLUGIN_AUTHORS = "michael.hunhoff@mandiant.com, william.ballenthin@mandiant.com, moritz.raabe@mandiant.com" wanted_name = PLUGIN_NAME - comment = "IDA plugin for capa analysis framework" + wanted_hotkey = "ALT-F5" + comment = "IDA Pro plugin for the FLARE team's capa tool to identify capabilities in executable files." + website = "https://github.com/fireeye/capa" + help = "See https://github.com/fireeye/capa/blob/master/doc/usage.md" version = "" - website = "" - help = "" - wanted_hotkey = "" flags = 0 def __init__(self): @@ -41,13 +41,13 @@ class CapaExplorerPlugin(idaapi.plugin_t): """ logging.basicConfig(level=logging.INFO) - # check IDA version and database compat + # check IDA version and database compatibility if not is_supported_ida_version(): return idaapi.PLUGIN_SKIP if not is_supported_file_type(): return idaapi.PLUGIN_SKIP - logger.info("plugin initialized.") + logger.debug("plugin initialized") return idaapi.PLUGIN_KEEP @@ -55,7 +55,7 @@ class CapaExplorerPlugin(idaapi.plugin_t): """ called when IDA is unloading the plugin """ - logger.info("plugin closed.") + logger.debug("plugin terminated") def run(self, arg): """ diff --git a/capa/ida/plugin/form.py b/capa/ida/plugin/form.py index 26498370..fb7fe972 100644 --- a/capa/ida/plugin/form.py +++ b/capa/ida/plugin/form.py @@ -24,7 +24,10 @@ from capa.ida.plugin.hooks import CapaExplorerIdaHooks from capa.ida.plugin.model import CapaExplorerDataModel from capa.ida.plugin.proxy import CapaExplorerSortFilterProxyModel -logger = logging.getLogger("capa") +logger = logging.getLogger(__name__) + + +ICON_PATH = os.path.join(os.path.dirname(__file__), "img", "capa_icon.png") class CapaExplorerForm(idaapi.PluginForm): @@ -54,17 +57,18 @@ class CapaExplorerForm(idaapi.PluginForm): def OnCreate(self, form): """ """ self.parent = self.FormToPyQtWidget(form) + self.parent.setWindowIcon(QtGui.QIcon(ICON_PATH)) self.load_interface() self.load_capa_results() self.load_ida_hooks() self.view_tree.reset() - logger.info("form created.") + logger.debug("form created") def Show(self): """ """ - logger.info("form show.") + logger.debug("form show") return idaapi.PluginForm.Show( self, self.form_title, options=(idaapi.PluginForm.WOPN_TAB | idaapi.PluginForm.WCLS_CLOSE_LATER) ) @@ -73,7 +77,7 @@ class CapaExplorerForm(idaapi.PluginForm): """ form is closed """ self.unload_ida_hooks() self.ida_reset() - logger.info("form closed.") + logger.debug("form closed") def load_interface(self): """ load user interface """ @@ -310,19 +314,19 @@ class CapaExplorerForm(idaapi.PluginForm): return self.rule_path = rule_path - 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) + logger.debug("-" * 80) + logger.debug(" Using rules from %s.", self.rule_path) + logger.debug(" ") + logger.debug(" You can see the current default rule set here:") + logger.debug(" https://github.com/fireeye/capa-rules") + logger.debug("-" * 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) - 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 @@ -354,7 +358,7 @@ class CapaExplorerForm(idaapi.PluginForm): if capa.main.has_file_limitation(rules, capabilities, is_standalone=False): capa.ida.helpers.inform_user_ida_ui("capa encountered warnings during analysis") - logger.info("analysis completed.") + logger.debug("analysis completed.") self.doc = capa.render.convert_capabilities_to_result_document(meta, rules, capabilities) @@ -364,7 +368,7 @@ class CapaExplorerForm(idaapi.PluginForm): self.set_view_tree_default_sort_order() - logger.info("render views completed.") + logger.debug("render views completed.") def set_view_tree_default_sort_order(self): """ set capa tree view default sort order """ @@ -462,7 +466,7 @@ class CapaExplorerForm(idaapi.PluginForm): self.view_summary.setRowCount(0) self.load_capa_results() - logger.info("reload complete.") + logger.debug("%s reload completed", self.form_title) idaapi.info("%s reload completed." % self.form_title) def reset(self, checked): @@ -472,8 +476,8 @@ class CapaExplorerForm(idaapi.PluginForm): """ self.ida_reset() - logger.info("reset completed.") - idaapi.info("%s reset completed." % self.form_title) + logger.debug("%s reset completed", self.form_title) + idaapi.info("%s reset completed" % self.form_title) def slot_menu_bar_hovered(self, action): """display menu action tooltip diff --git a/capa/ida/plugin/img/capa_icon.png b/capa/ida/plugin/img/capa_icon.png new file mode 100644 index 00000000..ae38674b Binary files /dev/null and b/capa/ida/plugin/img/capa_icon.png differ diff --git a/tests/data b/tests/data index c3a35d4b..afd4177a 160000 --- a/tests/data +++ b/tests/data @@ -1 +1 @@ -Subproject commit c3a35d4b6430ed61ffef59d672a2a8b6061e23fe +Subproject commit afd4177aa9da0daefaee69f5cbc4a86fcc072a4d