diff --git a/CHANGELOG.md b/CHANGELOG.md index e987a8de..322f111f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,6 +54,7 @@ Deprecation notice: as described in [#937](https://github.com/mandiant/capa/issu ### capa explorer IDA Pro plugin - improve file format extraction #918 @mike-hunhoff - remove decorators added by IDA to ELF imports #919 @mike-hunhoff +- bug fixes for Address abstraction #1091 @mike-hunhoff ### Development diff --git a/capa/features/extractors/ida/function.py b/capa/features/extractors/ida/function.py index 372ffc4d..f4f3a541 100644 --- a/capa/features/extractors/ida/function.py +++ b/capa/features/extractors/ida/function.py @@ -34,7 +34,7 @@ def extract_function_loop(fh: FunctionHandle): edges.append((bb.start_ea, succ.start_ea)) if loops.has_loop(edges): - yield Characteristic("loop"), f.start_ea + yield Characteristic("loop"), fh.address def extract_recursive_call(fh: FunctionHandle): diff --git a/capa/ida/plugin/item.py b/capa/ida/plugin/item.py index a6817eb9..7fdc34be 100644 --- a/capa/ida/plugin/item.py +++ b/capa/ida/plugin/item.py @@ -315,7 +315,7 @@ class CapaExplorerFeatureItem(CapaExplorerDataItem): ea = int(location) super(CapaExplorerFeatureItem, self).__init__(parent, [display, ea_to_hex(ea), details]) else: - super(CapaExplorerFeatureItem, self).__init__(parent, [display, "global", details]) + super(CapaExplorerFeatureItem, self).__init__(parent, [display, "", details]) class CapaExplorerInstructionViewItem(CapaExplorerFeatureItem): diff --git a/capa/ida/plugin/model.py b/capa/ida/plugin/model.py index 4aea1f44..79b27fee 100644 --- a/capa/ida/plugin/model.py +++ b/capa/ida/plugin/model.py @@ -446,8 +446,10 @@ class CapaExplorerDataModel(QtCore.QAbstractItemModel): for rule in rutils.capability_rules(doc): for location_, _ in rule.matches: location = location_.to_capa() - # within IDA, assume that all addresses are virtual addresses. - assert isinstance(location, AbsoluteVirtualAddress) + + if not isinstance(location, AbsoluteVirtualAddress): + # only handle matches with a VA + continue ea = int(location) ea = capa.ida.helpers.get_func_start_ea(ea) @@ -600,8 +602,14 @@ class CapaExplorerDataModel(QtCore.QAbstractItemModel): elif isinstance(feature, frzf.MatchFeature): # display content of rule for all rule matches - matched_rule_name = feature.match - return CapaExplorerRuleMatchItem(parent, display, source=doc.rules[matched_rule_name].source) + matched_rule_source = "" + + # check if match is a matched rule + matched_rule = doc.rules.get(feature.match, None) + if matched_rule is not None: + matched_rule_source = matched_rule.source + + return CapaExplorerRuleMatchItem(parent, display, source=matched_rule_source) elif isinstance(feature, (frzf.RegexFeature, frzf.SubstringFeature)): for capture, addrs in sorted(match.captures.items()): diff --git a/capa/ida/plugin/view.py b/capa/ida/plugin/view.py index 2f1cc41f..ef656736 100644 --- a/capa/ida/plugin/view.py +++ b/capa/ida/plugin/view.py @@ -18,7 +18,7 @@ import capa.ida.helpers import capa.features.common import capa.features.basicblock from capa.ida.plugin.item import CapaExplorerFunctionItem -from capa.features.address import NO_ADDRESS +from capa.features.address import Address, _NoAddress from capa.ida.plugin.model import CapaExplorerDataModel MAX_SECTION_SIZE = 750 @@ -789,7 +789,7 @@ class CapaExplorerRulegenFeatures(QtWidgets.QTreeWidget): self.parent_items = {} self.editor = editor - self.setHeaderLabels(["Feature", "Virtual Address"]) + self.setHeaderLabels(["Feature", "Address"]) self.setStyleSheet("QTreeView::item {padding-right: 15 px;padding-bottom: 2 px;}") # configure view columns to auto-resize @@ -1012,9 +1012,8 @@ class CapaExplorerRulegenFeatures(QtWidgets.QTreeWidget): self.parent_items = {} def format_address(e): - if e == NO_ADDRESS: - return "" - return "%X" % e if e else "" + assert isinstance(e, Address) + return "%X" % e if not isinstance(e, _NoAddress) else "" def format_feature(feature): """ """ @@ -1056,7 +1055,7 @@ class CapaExplorerRulegenFeatures(QtWidgets.QTreeWidget): addr = addrs.pop() else: # some features may not have an address e.g. "format" - addr = "" + addr = _NoAddress() for (i, v) in enumerate((format_feature(feature), format_address(addr))): self.parent_items[feature].setText(i, v) self.parent_items[feature].setData(0, 0x100, feature)