Skip to content

Commit c6d587b

Browse files
authored
fix: matched functions table and progress bar
1 parent a1df763 commit c6d587b

5 files changed

Lines changed: 32 additions & 19 deletions

File tree

reai_toolkit/features/match_current_function/match_current_function.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ def parse_confidence(item):
135135
continue
136136

137137
function = bv.get_function_at(func_addr)
138+
line["function_address"] = func_addr
138139
log_info(f"RevEng.AI | Function: {function} at {func_addr:x}")
139140

140141
if not line["matched_function_name"] or line["matched_function_name"].startswith(("sub_", "FUN_")):
@@ -152,15 +153,14 @@ def parse_confidence(item):
152153
line["icon_text"] = "Success"
153154
matched_count += 1
154155

155-
if line not in result["data"] and line["function_address"] != "N/A":
156+
if line not in result["data"]:
156157
result["data"].append(line)
157158

158159
except Exception as e:
159160
log_error(f"RevEng.AI | Error processing function {function_by_distance.function_id}: {str(e)}")
160161
#populate_table_function(result["data"])
161162
#################
162163
if functions_by_distance.status.lower() == "completed":
163-
164164
break
165165
elif functions_by_distance.status.lower() == "error":
166166
raise Exception("Function matching failed")

reai_toolkit/features/match_current_function/match_current_function_dialog.py

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ def __init__(self, config, match_functions, bv, func):
1313
super().__init__()
1414
self.config = config
1515
self.match_functions = match_functions
16+
self.results = []
1617
self.selected_results = []
1718
self.bv = bv
1819
self.func = func
@@ -206,6 +207,8 @@ def init_ui(self):
206207
header.setSectionResizeMode(6, QHeaderView.Stretch)
207208
self.results_table.setAlternatingRowColors(True)
208209
self.results_table.verticalHeader().setVisible(False)
210+
self.results_table.setSelectionBehavior(QTableWidget.SelectRows)
211+
self.results_table.setSelectionMode(QTableWidget.SingleSelection)
209212

210213
#functions_group_layout.addLayout(search_input_layout)
211214
functions_group_layout.addWidget(filter_group)
@@ -307,15 +310,16 @@ def on_matching_finished(self, success, data):
307310

308311
def populate_results_table(self, results):
309312
self.selected_results.clear()
313+
self.results = results
310314

311315
self.results_table.setRowCount(0)
312316
self.results_table.setRowCount(len(results))
313-
317+
314318
try:
315319
self.results_table.itemChanged.disconnect()
316320
except TypeError:
317321
pass # No connections to disconnect
318-
322+
319323
if len(results) > 0:
320324
self.rename_button.setEnabled(True)
321325
self.rename_button.setStyleSheet("""
@@ -397,6 +401,8 @@ def populate_results_table(self, results):
397401
self.results_table.cellClicked.connect(self.on_checkbox_changed)
398402

399403
def on_checkbox_changed(self, item_or_row, column=None):
404+
log_info(f"RevEng.AI | on_checkbox_changed: {item_or_row}, {column}")
405+
400406
"""Handle checkbox changes to ensure only one is selected at a time"""
401407
if isinstance(item_or_row, QTableWidgetItem): # Called from itemChanged
402408
row = item_or_row.row()
@@ -405,12 +411,14 @@ def on_checkbox_changed(self, item_or_row, column=None):
405411
row = item_or_row
406412
is_checkbox = column == 0
407413

414+
log_info(f"RevEng.AI | row: {row}, is_checkbox: {is_checkbox}")
415+
log_info(f"RevEng.AI | len(self.results): {len(self.results)}")
408416
# Get the match data for this row
409-
if row < len(self.current_matches):
410-
match = self.current_matches[row]
417+
if row < len(self.results):
418+
match = self.results[row]
411419
else:
412420
return
413-
421+
log_info(f"RevEng.AI | match: {match}")
414422
if match:
415423
checkbox_item = self.results_table.item(row, 0)
416424
current_state = checkbox_item.checkState()
@@ -432,11 +440,11 @@ def on_checkbox_changed(self, item_or_row, column=None):
432440
other_checkbox.setCheckState(Qt.Unchecked)
433441

434442
# Update selected result with the current match
435-
self.selected_result = match
436-
log_info(f"RevEng.AI | Selected function match: {match.get('matched_name', 'Unknown')}")
443+
self.selected_results = [match]
444+
log_info(f"RevEng.AI | Selected function match: {match.get('matched_function_name', 'Unknown')}")
437445
else:
438446
# If unchecked, clear selection
439-
self.selected_result = {}
447+
self.selected_result = []
440448
log_info(f"RevEng.AI | Deselected function match")
441449

442450
def start_fetching_data_types(self):
@@ -446,14 +454,14 @@ def start_fetching_data_types(self):
446454
self.progress = create_cancellable_progress_dialog(self, "RevEng.AI Fetch Data Types", "Fetching data types...", self.match_functions.cancel)
447455
self.progress.show()
448456
QCoreApplication.processEvents()
449-
457+
"""
450458
if not hasattr(self, 'selected_results') or not self.selected_results:
451459
log_error("RevEng.AI | No current matches available for data type fetching")
452460
self.progress.close()
453461
QMessageBox.warning(self,"RevEng.AI Fetch Data Types","No function matches available. Please run 'Fetch Results' first.", QMessageBox.Ok)
454462
return
455-
456-
self.fetch_data_types_thread = DataThread(self.match_functions.fetch_data_types, self.bv, self.selected_results, self.match_functions.clear_cancelled)
463+
"""
464+
self.fetch_data_types_thread = DataThread(self.match_functions.fetch_data_types, self.bv, self.results, self.match_functions.clear_cancelled)
457465
self.fetch_data_types_thread.finished.connect(self.on_fetching_data_types_finished)
458466
self.fetch_data_types_thread.start()
459467

@@ -491,6 +499,7 @@ def start_renaming(self):
491499
self.progress = create_progress_dialog(self, "RevEng.AI Rename Selected Functions", "Renaming Selected Functions...")
492500
self.progress.show()
493501
QCoreApplication.processEvents()
502+
log_info(f"RevEng.AI | Selected results: {len(self.selected_results)}")
494503

495504
self.rename_thread = DataThread(
496505
self.match_functions.rename_functions,

reai_toolkit/utils/core/binary_ninja.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,12 @@ def rename_function(bv: BinaryView, addr: int, new_name: str, data_type: dict =
1010
func = bv.get_function_at(addr)
1111
if not func:
1212
log_error(f"RevEng.AI | No function found at address {hex(addr)}")
13-
return False
14-
13+
addr = addr + bv.image_base
14+
func = bv.get_function_at(addr)
15+
if not func:
16+
log_error(f"RevEng.AI | No function found at address {hex(addr)}")
17+
return False
18+
1519
if func.name == new_name:
1620
log_info(f"RevEng.AI | Function at {hex(addr)} already has name {func.name}")
1721
#return False

reai_toolkit/utils/ui/binaries_popup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from PySide6.QtCore import Qt, QCoreApplication
77
from reai_toolkit.utils.ui.progress import create_progress_dialog
88
from reai_toolkit.utils.core.threading import DataThread
9-
800
9+
1010
class BinariesPopup(QDialog):
1111
def __init__(self, match_functions, bv, status_label=None, parent=None, write_selected_binaries=None):
1212
super().__init__(parent)
@@ -33,7 +33,7 @@ def _build_search_section(self, parent_layout):
3333
search_input_layout = QHBoxLayout()
3434
self.search_input = QLineEdit()
3535
self.search_input.setPlaceholderText("Enter search term...")
36-
self.search_input.returnPressed.connect(self._search_binaries)
36+
#self.search_input.returnPressed.connect(self._search_binaries)
3737

3838
description_label = QLabel(
3939
"Search (e.g. sha_256_hash:{}, tag:{}, binary_name:{}, function_name:{}, model_name:{})"

reai_toolkit/utils/ui/collections_popup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from PySide6.QtCore import Qt, QCoreApplication
77
from reai_toolkit.utils.ui.progress import create_progress_dialog
88
from reai_toolkit.utils.core.threading import DataThread
9-
800
9+
1010
class CollectionsPopup(QDialog):
1111
def __init__(self, match_functions, bv, status_label=None, parent=None, write_selected_collections=None):
1212
super().__init__(parent)
@@ -33,7 +33,7 @@ def _build_search_section(self, parent_layout):
3333
search_input_layout = QHBoxLayout()
3434
self.search_input = QLineEdit()
3535
self.search_input.setPlaceholderText("Enter search term...")
36-
self.search_input.returnPressed.connect(self._search_collections)
36+
#self.search_input.returnPressed.connect(self._search_collections)
3737

3838
description_label = QLabel(
3939
"Search (e.g. sha_256_hash:{}, tag:{}, collection_name:{}, function_name:{}, model_name:{})"

0 commit comments

Comments
 (0)