From 5dacd070bdc421e3b6c0066f123034b2a7323593 Mon Sep 17 00:00:00 2001 From: Lav <32195948+Lavender-exe@users.noreply.github.com> Date: Sat, 16 May 2026 23:28:01 +0200 Subject: [PATCH] [Binary Ninja] Fixed compatibility issue with version 5.x --- ext_bn/retsync/plugin.json | 2 +- ext_bn/retsync/retsync/rswidget.py | 50 +++++++++++++++++---------- ext_bn/retsync/sync.py | 54 ++++++++++-------------------- 3 files changed, 51 insertions(+), 55 deletions(-) diff --git a/ext_bn/retsync/plugin.json b/ext_bn/retsync/plugin.json index d8a23e2..95ca525 100644 --- a/ext_bn/retsync/plugin.json +++ b/ext_bn/retsync/plugin.json @@ -18,7 +18,7 @@ }, "dependencies": { }, - "version": "0.1.1", + "version": "0.1.2", "author": "Alexandre Gazet", "minimumbinaryninjaversion": 2 } diff --git a/ext_bn/retsync/retsync/rswidget.py b/ext_bn/retsync/retsync/rswidget.py index 6f9bf63..4197be5 100644 --- a/ext_bn/retsync/retsync/rswidget.py +++ b/ext_bn/retsync/retsync/rswidget.py @@ -28,16 +28,18 @@ from PySide6 import QtCore from PySide6.QtCore import Qt from PySide6.QtWidgets import QApplication, QHBoxLayout, QVBoxLayout, QLabel, QWidget - from PySide6.QtGui import QKeySequence + from PySide6.QtGui import QKeySequence, QImage else: from PySide2 import QtCore from PySide2.QtCore import Qt from PySide2.QtWidgets import QApplication, QHBoxLayout, QVBoxLayout, QLabel, QWidget - from PySide2.QtGui import QKeySequence + from PySide2.QtGui import QKeySequence, QImage from binaryninjaui import UIAction, UIActionHandler -from binaryninjaui import DockContextHandler - +from binaryninjaui import ( + Sidebar, SidebarWidget, SidebarWidgetType, + SidebarWidgetLocation, SidebarContextSensitivity, +) from .rsconfig import rs_log @@ -48,12 +50,12 @@ class SyncStatus(object): RUNNING = "connected" -# based on hellodockwidget.py -# from https://github.com/Vector35/binaryninja-api/ -class SyncDockWidget(QWidget, DockContextHandler): - def __init__(self, parent, name, data): - QWidget.__init__(self, parent) - DockContextHandler.__init__(self, self, name) +class SyncSidebarWidget(SidebarWidget): + _instance = None + + def __init__(self, name, frame, data): + SidebarWidget.__init__(self, name) + SyncSidebarWidget._instance = self self.actionHandler = UIActionHandler() self.actionHandler.setupActionHandler(self) @@ -83,11 +85,8 @@ def __init__(self, parent, name, data): layout.addStretch() self.setLayout(layout) - def shouldBeVisible(self, view_frame): - if view_frame is None: - return False - else: - return True + def notifyViewChanged(self, view_frame): + pass def contextMenuEvent(self, event): self.m_contextMenuManager.show(self.m_menu, self.actionHandler) @@ -119,6 +118,21 @@ def reset_status(self): self.client_pgm.setText('n/a') self.client_dbg.setText('n/a') - @staticmethod - def create_widget(name, parent, data=None): - return SyncDockWidget(parent, name, data) + +class SyncSidebarWidgetType(SidebarWidgetType): + def __init__(self): + icon = QImage(56, 56, QImage.Format_RGB32) + icon.fill(0) + SidebarWidgetType.__init__(self, icon, "ret-sync") + + def createWidget(self, frame, data): + return SyncSidebarWidget("ret-sync", frame, data) + + def defaultLocation(self): + return SidebarWidgetLocation.RightContent + + def contextSensitivity(self): + return SidebarContextSensitivity.SelfManagedSidebarContext + + +Sidebar.addSidebarWidgetType(SyncSidebarWidgetType()) diff --git a/ext_bn/retsync/sync.py b/ext_bn/retsync/sync.py index a99be59..5c939fa 100644 --- a/ext_bn/retsync/sync.py +++ b/ext_bn/retsync/sync.py @@ -23,17 +23,7 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. """ -import binaryninjaui -if 'qt_major_version' in binaryninjaui.__dict__ and binaryninjaui.qt_major_version == 6: - from PySide6 import QtCore - from PySide6.QtCore import Qt -else: - from PySide2 import QtCore - from PySide2.QtCore import Qt - -from binaryninjaui import DockHandler from binaryninjaui import UIAction, UIActionHandler, UIContext, UIContextNotification -from binaryninjaui import ViewFrame from binaryninja.plugin import BackgroundTaskThread, PluginCommand @@ -52,7 +42,7 @@ from .retsync import rsconfig as rsconfig from .retsync.rsconfig import rs_encode, rs_decode, rs_log, rs_debug, load_configuration -from .retsync.rswidget import SyncDockWidget +from .retsync.rswidget import SyncSidebarWidget class SyncHandler(object): @@ -434,19 +424,6 @@ def as_list(self): return self.opened.values() def list_dyn(self): - self.opened = {} - dock = DockHandler.getActiveDockHandler() - view_frame = dock.getViewFrame() - - if view_frame: - frames = view_frame.parent() - for i in range(frames.count()): - widget = frames.widget(i) - vf = ViewFrame.viewFrameForWidget(widget) - if vf: - file_name = vf.getFileContext().getFilename - self.add(file_name) - return self.opened @@ -462,7 +439,6 @@ def __init__(self): self.pgm_mgr = ProgramManager() # binary ninja objects - self.widget = None self.view_frame = None self.view = None self.binary_view = None @@ -478,11 +454,12 @@ def __init__(self): self.sync_mode_auto = True self.cb_trace_enabled = False + @property + def widget(self): + return SyncSidebarWidget._instance + def init_widget(self): - dock_handler = DockHandler.getActiveDockHandler() - parent = dock_handler.parent() - self.widget = SyncDockWidget.create_widget("ret-sync plugin", parent) - dock_handler.addDockWidget(self.widget, Qt.BottomDockWidgetArea, Qt.Horizontal, True, False) + pass # widget created by BN sidebar system via SyncSidebarWidgetType def OnAfterOpenFile(self, context, file, frame): self.pgm_mgr.add(file.getRawData().file.original_filename) @@ -525,7 +502,8 @@ def OnViewChange(self, context, frame, type): def bootstrap(self, dialect): self.pgm_mgr.reset_bases() - self.widget.set_connected(dialect) + if self.widget: + self.widget.set_connected(dialect) if dialect in rsconfig.DBG_DIALECTS: self.dbg_dialect = rsconfig.DBG_DIALECTS[dialect] @@ -535,14 +513,16 @@ def reset_client(self): self.sync_enabled = False self.cb_trace_enabled = False self.current_pgm = None - self.widget.reset_client() + if self.widget: + self.widget.reset_client() def broadcast(self, msg): self.client.send(rs_encode(msg)) rs_log(msg) def set_program(self, pgm): - self.widget.set_program(pgm) + if self.widget: + self.widget.set_program(pgm) if not self.pgm_mgr.exists(pgm): return self.sync_enabled = True @@ -590,9 +570,10 @@ def pgm_target(self, pgm=None): rs_log('error while switching tabs') def trigger_action(self, action: str): - handler = UIActionHandler().actionHandlerFromWidget( - DockHandler.getActiveDockHandler().parent()) - handler.executeAction(action) + ctx = UIContext.activeContext() + if ctx: + handler = UIActionHandler().actionHandlerFromWidget(ctx.mainWindow()) + handler.executeAction(action) # check if address is within a valid segment def is_safe(self, offset): @@ -786,6 +767,7 @@ def cmd_syncoff(self, ctx=None): if self.client_listener: self.client_listener.cancel() self.client_listener = None - self.widget.reset_status() + if self.widget: + self.widget.reset_status() else: rs_log('not listening')