ida: show addresses for file level features in rulegen (#3009)

* ida: show addresses for file level features in rulegen

* ida(ai): remove redundant `int` conversion

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>

---------

Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Co-authored-by: Moritz <mr-tz@users.noreply.github.com>
This commit is contained in:
lakshit verma
2026-06-05 15:02:46 +05:30
committed by GitHub
parent c592100495
commit adffa80e8f
2 changed files with 31 additions and 8 deletions
+2 -1
View File
@@ -124,6 +124,7 @@
### capa Explorer Web
### capa Explorer IDA Pro plugin
- ida: display file-scope feature addresses (`file:0x...`) in rule generator tree and safely handle file-offset navigation/filtering @vee1e #3009
### Development
- tests: update binja version to 5.3 @mr-tz #3011
@@ -277,7 +278,7 @@ Additionally a Binary Ninja bug has been fixed. Released binaries now include AR
### Bug Fixes
- binja: fix a crash during feature extraction when the MLIL is unavailable @xusheng6 #2714
- binja: fix a crash during feature extraction when the MLIL is unavailable @xusheng6 #2714
### capa Explorer Web
+29 -7
View File
@@ -18,12 +18,13 @@ from collections import Counter
import idc
import idaapi
import ida_loader
import capa.ida.helpers
import capa.features.common
import capa.features.basicblock
from capa.ida.plugin.item import CapaExplorerFunctionItem
from capa.features.address import AbsoluteVirtualAddress, _NoAddress
from capa.features.address import FileOffsetAddress, AbsoluteVirtualAddress, _NoAddress
from capa.ida.plugin.model import CapaExplorerDataModel
from capa.ida.plugin.qt_compat import QtGui, QtCore, Signal, QAction, QtWidgets
@@ -895,7 +896,22 @@ class CapaExplorerRulegenFeatures(QtWidgets.QTreeWidget):
def slot_item_double_clicked(self, o, column):
""" """
if column == CapaExplorerRulegenFeatures.get_column_address_index() and o.text(column):
idc.jumpto(int(o.text(column), 0x10))
addr_text = o.text(column).strip()
if addr_text.startswith("file:"):
try:
file_offset = int(addr_text[len("file:") :], 16)
except (ValueError, TypeError):
return
ea = ida_loader.get_fileregion_ea(file_offset)
if ea != idc.BADADDR:
idc.jumpto(ea)
else:
try:
idc.jumpto(int(addr_text, 16))
except (ValueError, TypeError):
return
elif o.capa_type == CapaExplorerRulegenFeatures.get_node_type_leaf():
self.editor.update_features([o.data(0, 0x100)])
@@ -945,13 +961,18 @@ class CapaExplorerRulegenFeatures(QtWidgets.QTreeWidget):
# read ea from "Address" column
o_ea = o.text(CapaExplorerRulegenFeatures.get_column_address_index())
if o_ea == "":
# ea may be empty, hide by default
if o_ea == "" or o_ea.startswith("file:"):
# ea may be empty or a file offset, hide by default when filtering by VA
if not o.isHidden():
o.setHidden(True)
continue
o_ea = int(o_ea, 16)
try:
o_ea = int(o_ea, 16)
except (ValueError, TypeError):
if not o.isHidden():
o.setHidden(True)
continue
if max_ea is not None and min_ea <= o_ea <= max_ea:
show_item_and_parents(o)
@@ -1035,8 +1056,9 @@ class CapaExplorerRulegenFeatures(QtWidgets.QTreeWidget):
def format_address(e):
if isinstance(e, AbsoluteVirtualAddress):
return f"{hex(int(e))}"
else:
return ""
if isinstance(e, FileOffsetAddress):
return f"file:{hex(e)}"
return ""
def format_feature(feature):
""" """