Skip to content

Commit 4890bf5

Browse files
committed
ida: show addresses for file level features in rulegen
1 parent c0ce1a3 commit 4890bf5

2 files changed

Lines changed: 31 additions & 8 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
### capa Explorer Web
1616

1717
### capa Explorer IDA Pro plugin
18+
- ida: display file-scope feature addresses (`file:0x...`) in rule generator tree and safely handle file-offset navigation/filtering @vee1e #3009
1819

1920
### Development
2021
- ci: use explicit and per job permissions @mike-hunhoff #3002
@@ -165,7 +166,7 @@ Additionally a Binary Ninja bug has been fixed. Released binaries now include AR
165166

166167
### Bug Fixes
167168

168-
- binja: fix a crash during feature extraction when the MLIL is unavailable @xusheng6 #2714
169+
- binja: fix a crash during feature extraction when the MLIL is unavailable @xusheng6 #2714
169170

170171
### capa Explorer Web
171172

capa/ida/plugin/view.py

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,15 @@
1818

1919
import idc
2020
import idaapi
21+
import ida_loader
2122

2223
import capa.rules
2324
import capa.engine
2425
import capa.ida.helpers
2526
import capa.features.common
2627
import capa.features.basicblock
2728
from capa.ida.plugin.item import CapaExplorerFunctionItem
28-
from capa.features.address import AbsoluteVirtualAddress, _NoAddress
29+
from capa.features.address import FileOffsetAddress, AbsoluteVirtualAddress, _NoAddress
2930
from capa.ida.plugin.model import CapaExplorerDataModel
3031
from capa.ida.plugin.qt_compat import QtGui, QtCore, Signal, QAction, QtWidgets
3132

@@ -905,7 +906,22 @@ def slot_custom_context_menu_requested(self, pos):
905906
def slot_item_double_clicked(self, o, column):
906907
""" """
907908
if column == CapaExplorerRulegenFeatures.get_column_address_index() and o.text(column):
908-
idc.jumpto(int(o.text(column), 0x10))
909+
addr_text = o.text(column).strip()
910+
911+
if addr_text.startswith("file:"):
912+
try:
913+
file_offset = int(addr_text[len("file:") :], 16)
914+
except (ValueError, TypeError):
915+
return
916+
917+
ea = ida_loader.get_fileregion_ea(file_offset)
918+
if ea != idc.BADADDR:
919+
idc.jumpto(ea)
920+
else:
921+
try:
922+
idc.jumpto(int(addr_text, 16))
923+
except (ValueError, TypeError):
924+
return
909925
elif o.capa_type == CapaExplorerRulegenFeatures.get_node_type_leaf():
910926
self.editor.update_features([o.data(0, 0x100)])
911927

@@ -955,13 +971,18 @@ def show_item_and_parents(_o):
955971
# read ea from "Address" column
956972
o_ea = o.text(CapaExplorerRulegenFeatures.get_column_address_index())
957973

958-
if o_ea == "":
959-
# ea may be empty, hide by default
974+
if o_ea == "" or o_ea.startswith("file:"):
975+
# ea may be empty or a file offset, hide by default when filtering by VA
960976
if not o.isHidden():
961977
o.setHidden(True)
962978
continue
963979

964-
o_ea = int(o_ea, 16)
980+
try:
981+
o_ea = int(o_ea, 16)
982+
except (ValueError, TypeError):
983+
if not o.isHidden():
984+
o.setHidden(True)
985+
continue
965986

966987
if max_ea is not None and min_ea <= o_ea <= max_ea:
967988
show_item_and_parents(o)
@@ -1045,8 +1066,9 @@ def parse_features_for_tree(self, parent, features):
10451066
def format_address(e):
10461067
if isinstance(e, AbsoluteVirtualAddress):
10471068
return f"{hex(int(e))}"
1048-
else:
1049-
return ""
1069+
if isinstance(e, FileOffsetAddress):
1070+
return f"file:{hex(int(e))}"
1071+
return ""
10501072

10511073
def format_feature(feature):
10521074
""" """

0 commit comments

Comments
 (0)