Skip to content

Commit 22db22d

Browse files
committed
feat: detach analysis option
1 parent 2259fc5 commit 22db22d

11 files changed

Lines changed: 88 additions & 6 deletions

File tree

reai_toolkit/features/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from reai_toolkit.features.match_current_function import MatchCurrentFunctionFeature
77
from reai_toolkit.features.view_function_in_portal import ViewFunctionInPortalFeature
88
from reai_toolkit.features.ai_decompiler import AIDecompilerFeature
9+
from reai_toolkit.features.detach import DetachAnalysisFeature
910
__all__ = [
1011
'ConfigurationFeature',
1112
'UploadFeature',
@@ -15,4 +16,5 @@
1516
'MatchCurrentFunctionFeature',
1617
'ViewFunctionInPortalFeature',
1718
'AIDecompilerFeature'
19+
'DetachAnalysisFeature'
1820
]

reai_toolkit/features/ai_decompiler/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,4 @@ def on_dock_closed(self, visible):
6666
self.ai_decompiler.stop_address_tracking()
6767

6868
def is_valid(self, bv: BinaryView, func):
69-
return self.config.is_configured == True
69+
return self.config.is_configured == True and self.config.analysis_id is not None

reai_toolkit/features/auto_unstrip/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,7 @@ def show_auto_unstrip_dialog(self, bv: BinaryView):
2222
log_info("RevEng.AI | Opening AutoUnstrip dialog")
2323
dialog = AutoUnstripDialog(self.config, self.auto_unstrip, bv)
2424
dialog.exec_()
25+
26+
def is_valid(self, bv: BinaryView):
27+
return self.config.is_configured == True and self.config.analysis_id is not None
2528

reai_toolkit/features/choose_source/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,6 @@ def show_choose_source_dialog(self, bv: BinaryView):
2323
dialog = ChooseSourceDialog(self.config, self.choose_source, bv)
2424
dialog.exec_()
2525

26+
def is_valid(self, bv: BinaryView):
27+
return self.config.is_configured == True and self.config.analysis_id is None
28+

reai_toolkit/features/configuration/config.py

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,4 +190,22 @@ def get_analysis_id(self, bv: BinaryView):
190190
if self.sha256 in all_analyses:
191191
return all_analyses[self.sha256]["analysis_id"]
192192
else:
193-
return 0
193+
return 0
194+
195+
196+
def reset_analysis_data(self, bv: BinaryView):
197+
try:
198+
self.analysis_id = None
199+
self.binary_id = None
200+
self.model_id = None
201+
self.sha256 = get_sha256(bv.file.filename)
202+
all_analyses = self.get_all_analyses()
203+
if self.sha256 in all_analyses:
204+
del all_analyses[self.sha256]
205+
settings = Settings()
206+
settings.set_json("revengai.all_analyses", json.dumps(all_analyses))
207+
log_info(f"RevEng.AI | Reset analysis data for SHA256: {self.sha256[:8]}...")
208+
return True, ""
209+
except Exception as e:
210+
log_error(f"RevEng.AI | Failed to reset analysis data: {str(e)}")
211+
return False, str(e)
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
from reai_toolkit.utils import BaseAuthFeature
2+
from binaryninja import PluginCommand, log_info, BinaryView
3+
from PySide6.QtWidgets import QMessageBox
4+
5+
class DetachAnalysisFeature(BaseAuthFeature):
6+
def __init__(self, config=None):
7+
super().__init__(config)
8+
log_info("RevEng.AI | DetachAnalysis Feature initialized")
9+
10+
def register(self):
11+
PluginCommand.register(
12+
"RevEng.AI\\Analysis\\\u200b\u200bDetach Analysis",
13+
"Detach from the current RevEng.AI analysis",
14+
self.verify_detach,
15+
self.is_valid
16+
)
17+
log_info("RevEng.AI | DetachAnalysis Feature registered")
18+
19+
def verify_detach(self, bv: BinaryView):
20+
log_info("RevEng.AI | Requesting detach confirmation")
21+
22+
reply = QMessageBox.question(
23+
None,
24+
"RevEng.AI - Detach Analysis",
25+
"Are you sure you want to detach from the current RevEng.AI analysis?\n\n"
26+
"This will disconnect this binary from its analysis on the RevEng.AI platform. "
27+
"You can reconnect later by choosing a source again.",
28+
QMessageBox.Yes | QMessageBox.No,
29+
QMessageBox.No
30+
)
31+
32+
if reply == QMessageBox.Yes:
33+
log_info("RevEng.AI | User confirmed detach")
34+
self.config.reset_analysis_data(bv)
35+
36+
QMessageBox.information(
37+
None,
38+
"RevEng.AI - Analysis Detached",
39+
"Successfully detached from the RevEng.AI analysis.\n\n"
40+
"You can process a new binary or choose a different source.",
41+
QMessageBox.Ok
42+
)
43+
else:
44+
log_info("RevEng.AI | User cancelled detach")
45+
46+
def is_valid(self, bv: BinaryView):
47+
return self.config.is_configured == True and self.config.analysis_id is not None

reai_toolkit/features/match_current_function/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,4 @@ def show_match_current_function_dialog(self, bv: BinaryView, func):
2424
dialog.exec_()
2525

2626
def is_valid(self, bv: BinaryView, func):
27-
return self.config.is_configured == True
27+
return self.config.is_configured == True and self.config.analysis_id is not None

reai_toolkit/features/match_functions/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,6 @@ def show_match_functions_dialog(self, bv: BinaryView):
2222
log_info("RevEng.AI | Opening MatchFunctions dialog")
2323
dialog = MatchFunctionsDialog(self.config, self.match_functions, bv)
2424
dialog.exec_()
25+
26+
def is_valid(self, bv: BinaryView):
27+
return self.config.is_configured == True and self.config.analysis_id is not None

reai_toolkit/features/upload/__init__.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,7 @@ def register(self):
2121
def show_upload_dialog(self, bv: BinaryView):
2222
log_info("RevEng.AI | Opening process dialog")
2323
dialog = UploadDialog(self.config, self.uploader, bv)
24-
dialog.exec()
24+
dialog.exec()
25+
26+
def is_valid(self, bv: BinaryView):
27+
return self.config.is_configured == True and self.config.analysis_id is None

reai_toolkit/features/view_function_in_portal/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,4 @@ def show_match_current_function_dialog(self, bv: BinaryView, func):
2525
dialog.exec_()
2626

2727
def is_valid(self, bv: BinaryView, func):
28-
return self.config.is_configured == True
28+
return self.config.is_configured == True and self.config.analysis_id is not None

0 commit comments

Comments
 (0)