From 0e0f35b7e8e0ec63df50b9801b09f4d286bc0945 Mon Sep 17 00:00:00 2001 From: Zion Leonahenahe Basque Date: Mon, 4 Nov 2024 15:27:53 -0700 Subject: [PATCH] Feature: detect the launching of a decompiler (#132) --- .../change_watcher_plugin/bs_change_watcher/__init__.py | 2 ++ libbs/__init__.py | 2 +- libbs/api/decompiler_interface.py | 9 +++++++++ libbs/decompilers/ida/interface.py | 1 + 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/examples/change_watcher_plugin/bs_change_watcher/__init__.py b/examples/change_watcher_plugin/bs_change_watcher/__init__.py index 10b3b57..04a6729 100644 --- a/examples/change_watcher_plugin/bs_change_watcher/__init__.py +++ b/examples/change_watcher_plugin/bs_change_watcher/__init__.py @@ -17,9 +17,11 @@ def create_plugin(*args, **kwargs): FunctionHeader, StackVariable, Enum, Struct, GlobalVariable, Comment, Context ) + decompiler_started_event_callbacks = [lambda *x, **y: print(f"[BSChangeWatcher] Started with plugin version {__version__}")] deci = DecompilerInterface.discover( plugin_name="ArtifactChangeWatcher", init_plugin=True, + decompiler_started_callbacks=decompiler_started_event_callbacks, gui_init_args=args, gui_init_kwargs=kwargs ) diff --git a/libbs/__init__.py b/libbs/__init__.py index e53870b..fed438d 100644 --- a/libbs/__init__.py +++ b/libbs/__init__.py @@ -1,4 +1,4 @@ -__version__ = "2.2.1" +__version__ = "2.3.0" import logging diff --git a/libbs/api/decompiler_interface.py b/libbs/api/decompiler_interface.py index 18fbc73..26d2678 100644 --- a/libbs/api/decompiler_interface.py +++ b/libbs/api/decompiler_interface.py @@ -62,6 +62,7 @@ def __init__( # [artifact_class] = list(callback_func) artifact_change_callbacks: Optional[Dict[Type[Artifact], List[Callable]]] = None, undo_event_callbacks: Optional[List[Callable]] = None, + decompiler_started_callbacks: Optional[List[Callable]] = None, thread_artifact_callbacks: bool = True, ): self.name = name @@ -89,6 +90,7 @@ def __init__( # callback functions, keyed by Artifact class self.artifact_change_callbacks = artifact_change_callbacks or defaultdict(list) self.undo_event_callbacks = undo_event_callbacks or [] + self.decompiler_started_callbacks = decompiler_started_callbacks or [] self._thread_artifact_callbacks = thread_artifact_callbacks # artifact dict aliases: @@ -633,6 +635,13 @@ def _set_function_header(self, fheader: FunctionHeader, **kwargs) -> bool: # lift it ONCE inside this function. Each one will return the lifted form, for easier overriding. # + def decompiler_started_event(self, **kwargs): + for callback_func in self.decompiler_started_callbacks: + if self._thread_artifact_callbacks: + threading.Thread(target=callback_func, kwargs=kwargs, daemon=True).start() + else: + callback_func(**kwargs) + def gui_undo_event(self, **kwargs): for callback_func in self.undo_event_callbacks: if self._thread_artifact_callbacks: diff --git a/libbs/decompilers/ida/interface.py b/libbs/decompilers/ida/interface.py index 1f70b3a..16a716d 100755 --- a/libbs/decompilers/ida/interface.py +++ b/libbs/decompilers/ida/interface.py @@ -62,6 +62,7 @@ def _init_gui_hooks(self): hook.hook() def _init_gui_plugin(self, *args, **kwargs): + self.decompiler_started_event() plugin_cls_name = self._plugin_name + "_cls" IDAPluginCls = compat.generate_generic_ida_plugic_cls(cls_name=plugin_cls_name) return IDAPluginCls(*args, name=self._plugin_name, interface=self, **kwargs)