Merge pull request #146 from fireeye/capa-explorer-export-json-results

capa explorer: add file menu option to export capa results
This commit is contained in:
Willi Ballenthin
2020-07-15 14:28:17 -06:00
committed by GitHub

View File

@@ -1,6 +1,7 @@
# Copyright (C) 2020 FireEye, Inc. All Rights Reserved.
import os
import json
import logging
import collections
@@ -82,6 +83,7 @@ class CapaExplorerForm(idaapi.PluginForm):
self.parent = None
self.ida_hooks = None
self.doc = None
# models
self.model_data = None
@@ -254,15 +256,28 @@ class CapaExplorerForm(idaapi.PluginForm):
actions = (
("Reset view", "Reset plugin view", self.reset),
("Run analysis", "Run capa analysis on current database", self.reload),
("Export results...", "Export capa results as JSON file", self.export_json),
)
menu = self.view_menu_bar.addMenu("File")
for (name, _, handle) in actions:
action = QtWidgets.QAction(name, self.parent)
action.triggered.connect(handle)
menu.addAction(action)
def export_json(self):
""" export capa results as JSON file """
if not self.doc:
idaapi.info("No capa results to export.")
return
path = idaapi.ask_file(True, "*.json", "Choose file")
if os.path.exists(path) and 1 != idaapi.ask_yn(1, "File already exists. Overwrite?"):
return
with open(path, "wb") as export_file:
export_file.write(
json.dumps(self.doc, sort_keys=True, cls=capa.render.CapaJsonObjectEncoder).encode("utf-8")
)
def load_ida_hooks(self):
""" load IDA Pro UI hooks """
action_hooks = {
@@ -377,11 +392,11 @@ class CapaExplorerForm(idaapi.PluginForm):
logger.info("analysis completed.")
doc = capa.render.convert_capabilities_to_result_document(meta, rules, capabilities)
self.doc = capa.render.convert_capabilities_to_result_document(meta, rules, capabilities)
self.model_data.render_capa_doc(doc)
self.render_capa_doc_summary(doc)
self.render_capa_doc_mitre_summary(doc)
self.model_data.render_capa_doc(self.doc)
self.render_capa_doc_summary()
self.render_capa_doc_mitre_summary()
self.set_view_tree_default_sort_order()
@@ -391,12 +406,9 @@ class CapaExplorerForm(idaapi.PluginForm):
""" set capa tree view default sort order """
self.view_tree.sortByColumn(CapaExplorerDataModel.COLUMN_INDEX_RULE_INFORMATION, QtCore.Qt.AscendingOrder)
def render_capa_doc_summary(self, doc):
""" render capa summary results
@param doc: capa doc
"""
for (row, rule) in enumerate(rutils.capability_rules(doc)):
def render_capa_doc_summary(self):
""" render capa summary results """
for (row, rule) in enumerate(rutils.capability_rules(self.doc)):
count = len(rule["matches"])
if count == 1:
@@ -412,14 +424,11 @@ class CapaExplorerForm(idaapi.PluginForm):
# resize columns to content
self.view_summary.resizeColumnsToContents()
def render_capa_doc_mitre_summary(self, doc):
""" render capa MITRE ATT&CK results
@param doc: capa doc
"""
def render_capa_doc_mitre_summary(self):
""" render capa MITRE ATT&CK results """
tactics = collections.defaultdict(set)
for rule in rutils.capability_rules(doc):
for rule in rutils.capability_rules(self.doc):
if not rule["meta"].get("att&ck"):
continue