summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/CMakeLists.txt1
-rw-r--r--examples/uinotification/CMakeLists.txt24
-rw-r--r--examples/uinotification/uinotification.cpp95
-rw-r--r--examples/uinotification/uinotification.h22
-rw-r--r--python/examples/ui_notifications.py77
-rw-r--r--ui/uicontext.h36
6 files changed, 255 insertions, 0 deletions
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 10ff05da..764ba0c4 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -4,4 +4,5 @@ add_subdirectory(cmdline_disasm)
add_subdirectory(llil_parser)
add_subdirectory(mlil_parser)
add_subdirectory(print_syscalls)
+add_subdirectory(uinotification)
add_subdirectory(x86_extension)
diff --git a/examples/uinotification/CMakeLists.txt b/examples/uinotification/CMakeLists.txt
new file mode 100644
index 00000000..6af09269
--- /dev/null
+++ b/examples/uinotification/CMakeLists.txt
@@ -0,0 +1,24 @@
+cmake_minimum_required(VERSION 3.13 FATAL_ERROR)
+
+project(uinotification)
+
+file(GLOB SOURCES
+ *.cpp
+ *.h)
+
+add_library(uinotification SHARED ${SOURCES})
+target_link_libraries(uinotification binaryninjaapi binaryninjaui)
+
+set_target_properties(uinotification PROPERTIES
+ CXX_STANDARD 17
+ CXX_VISIBILITY_PRESET hidden
+ CXX_STANDARD_REQUIRED ON
+ VISIBILITY_INLINES_HIDDEN ON
+ POSITION_INDEPENDENT_CODE ON
+ LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../../bin)
+
+if(BN_INTERNAL_BUILD)
+ ui_plugin_rpath(uinotification)
+endif()
+
+bn_install_plugin(${PROJECT_NAME})
diff --git a/examples/uinotification/uinotification.cpp b/examples/uinotification/uinotification.cpp
new file mode 100644
index 00000000..f9d1da39
--- /dev/null
+++ b/examples/uinotification/uinotification.cpp
@@ -0,0 +1,95 @@
+#include "uinotification.h"
+#include "filecontext.h"
+#include "viewframe.h"
+#include <QMessageBox>
+
+using namespace BinaryNinja;
+
+NotificationListener* NotificationListener::m_instance = nullptr;
+
+void NotificationListener::init()
+{
+ m_instance = new NotificationListener;
+ UIContext::registerNotification(m_instance);
+}
+
+
+void NotificationListener::OnContextOpen(UIContext* context)
+{
+ LogInfo("OnContextOpen");
+}
+
+
+void NotificationListener::OnContextClose(UIContext* context)
+{
+ LogInfo("OnContextClose");
+}
+
+
+bool NotificationListener::OnBeforeOpenDatabase(UIContext* context, FileMetadataRef metadata)
+{
+ LogInfo("OnBeforeOpenDatabase");
+ return QMessageBox::question(context->mainWindow(), "OnBeforeOpenDatabase", "OnBeforeOpenDatabase") == QMessageBox::StandardButton::Yes;
+}
+
+
+bool NotificationListener::OnAfterOpenDatabase(UIContext* context, FileMetadataRef metadata, BinaryViewRef data)
+{
+ LogInfo("OnAfterOpenDatabase");
+ return QMessageBox::question(context->mainWindow(), "OnAfterOpenDatabase", "OnAfterOpenDatabase") == QMessageBox::StandardButton::Yes;
+}
+
+
+bool NotificationListener::OnBeforeOpenFile(UIContext* context, FileContext* file)
+{
+ LogInfo("OnBeforeOpenFile");
+ return QMessageBox::question(context->mainWindow(), "OnBeforeOpenFile", "OnBeforeOpenFile") == QMessageBox::StandardButton::Yes;
+}
+
+
+void NotificationListener::OnAfterOpenFile(UIContext* context, FileContext* file, ViewFrame* frame)
+{
+ LogInfo("OnAfterOpenFile");
+}
+
+
+bool NotificationListener::OnBeforeSaveFile(UIContext* context, FileContext* file, ViewFrame* frame)
+{
+ LogInfo("OnBeforeSaveFile");
+ return QMessageBox::question(context->mainWindow(), "OnBeforeSaveFile", "OnBeforeSaveFile") == QMessageBox::StandardButton::Yes;
+}
+
+
+void NotificationListener::OnAfterSaveFile(UIContext* context, FileContext* file, ViewFrame* frame)
+{
+ LogInfo("OnAfterSaveFile");
+}
+
+
+bool NotificationListener::OnBeforeCloseFile(UIContext* context, FileContext* file, ViewFrame* frame)
+{
+ LogInfo("OnBeforeCloseFile");
+ return QMessageBox::question(context->mainWindow(), "OnBeforeCloseFile", "OnBeforeCloseFile") == QMessageBox::StandardButton::Yes;
+}
+
+
+void NotificationListener::OnAfterCloseFile(UIContext* context, FileContext* file, ViewFrame* frame)
+{
+ LogInfo("OnAfterCloseFile");
+}
+
+
+void NotificationListener::OnViewChange(UIContext* context, ViewFrame* frame, const QString& type)
+{
+ LogInfo("OnViewChange");
+}
+
+
+extern "C"
+{
+ BINARYNINJAPLUGIN bool UIPluginInit()
+ {
+ NotificationListener::init();
+ return true;
+ }
+}
diff --git a/examples/uinotification/uinotification.h b/examples/uinotification/uinotification.h
new file mode 100644
index 00000000..a26b3de3
--- /dev/null
+++ b/examples/uinotification/uinotification.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#include "uicontext.h"
+
+class NotificationListener: UIContextNotification
+{
+ static NotificationListener* m_instance;
+public:
+ virtual void OnContextOpen(UIContext* context) override;
+ virtual void OnContextClose(UIContext* context) override;
+ virtual bool OnBeforeOpenDatabase(UIContext* context, FileMetadataRef metadata) override;
+ virtual bool OnAfterOpenDatabase(UIContext* context, FileMetadataRef metadata, BinaryViewRef data) override;
+ virtual bool OnBeforeOpenFile(UIContext* context, FileContext* file) override;
+ virtual void OnAfterOpenFile(UIContext* context, FileContext* file, ViewFrame* frame) override;
+ virtual bool OnBeforeSaveFile(UIContext* context, FileContext* file, ViewFrame* frame) override;
+ virtual void OnAfterSaveFile(UIContext* context, FileContext* file, ViewFrame* frame) override;
+ virtual bool OnBeforeCloseFile(UIContext* context, FileContext* file, ViewFrame* frame) override;
+ virtual void OnAfterCloseFile(UIContext* context, FileContext* file, ViewFrame* frame) override;
+ virtual void OnViewChange(UIContext* context, ViewFrame* frame, const QString& type) override;
+
+ static void init();
+}; \ No newline at end of file
diff --git a/python/examples/ui_notifications.py b/python/examples/ui_notifications.py
new file mode 100644
index 00000000..8074a1c5
--- /dev/null
+++ b/python/examples/ui_notifications.py
@@ -0,0 +1,77 @@
+# Copyright (c) 2015-2020 Vector 35 Inc
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+# IN THE SOFTWARE.
+
+from binaryninjaui import *
+
+class UINotification(UIContextNotification):
+ def __init__(self):
+ UIContextNotification.__init__(self)
+ UIContext.registerNotification(self)
+ print("py UIContext.registerNotification")
+
+ def __del__(self):
+ UIContext.unregisterNotification(self)
+ print("py UIContext.unregisterNotification")
+
+ def OnContextOpen(self, context):
+ print("py OnContextOpen")
+
+ def OnContextClose(self, context):
+ print("py OnContextClose")
+
+ def OnBeforeOpenDatabase(self, context, metadata):
+ print(f"py OnBeforeOpenDatabase {metadata.filename}")
+ return True
+
+ def OnAfterOpenDatabase(self, context, metadata, data):
+ print(f"py OnAfterOpenDatabase {metadata.filename} {data.name}")
+ return True
+
+ def OnBeforeOpenFile(self, context, file):
+ print(f"py OnBeforeOpenFile {file.getFilename()}")
+ return True
+
+ def OnAfterOpenFile(self, context, file, frame):
+ print(f"py OnAfterOpenFile {file.getFilename()} {frame.getShortFileName()}")
+
+ def OnBeforeSaveFile(self, context, file, frame):
+ print(f"py OnBeforeSaveFile {file.getFilename()} {frame.getShortFileName()}")
+ return True
+
+ def OnAfterSaveFile(self, context, file, frame):
+ print(f"py OnAfterSaveFile {file.getFilename()} {frame.getShortFileName()}")
+
+ def OnBeforeCloseFile(self, context, file, frame):
+ print(f"py OnBeforeCloseFile {file.getFilename()} {frame.getShortFileName()}")
+ return True
+
+ def OnAfterCloseFile(self, context, file, frame):
+ print(f"py OnAfterCloseFile {file.getFilename()} {frame.getShortFileName()}")
+
+ def OnViewChange(self, context, frame, type):
+ if frame:
+ print(f"py OnViewChange {frame.getShortFileName()} / {type}")
+ else:
+ print("py OnViewChange")
+
+
+# Register as a global so it doesn't get destructed
+notif = UINotification()
+
diff --git a/ui/uicontext.h b/ui/uicontext.h
index e2a6e0a5..bc88a71b 100644
--- a/ui/uicontext.h
+++ b/ui/uicontext.h
@@ -17,6 +17,24 @@ class ViewFrame;
class UIActionHandler;
class FileContext;
+class BINARYNINJAUIAPI UIContextNotification
+{
+public:
+ virtual void OnContextOpen(UIContext* context) { (void)context; }
+ virtual void OnContextClose(UIContext* context) { (void)context; }
+
+ virtual bool OnBeforeOpenDatabase(UIContext* context, FileMetadataRef metadata) { (void)context; (void)metadata; return true; }
+ virtual bool OnAfterOpenDatabase(UIContext* context, FileMetadataRef metadata, BinaryViewRef data) { (void)context; (void)metadata; (void)data; return true; }
+ virtual bool OnBeforeOpenFile(UIContext* context, FileContext* file) { (void)context; (void)file; return true; }
+ virtual void OnAfterOpenFile(UIContext* context, FileContext* file, ViewFrame* frame) { (void)context; (void)file; (void)frame; }
+ virtual bool OnBeforeSaveFile(UIContext* context, FileContext* file, ViewFrame* frame) { (void)context; (void)file; (void)frame; return true; }
+ virtual void OnAfterSaveFile(UIContext* context, FileContext* file, ViewFrame* frame) { (void)context; (void)file; (void)frame; }
+ virtual bool OnBeforeCloseFile(UIContext* context, FileContext* file, ViewFrame* frame) { (void)context; (void)file; (void)frame; return true; }
+ virtual void OnAfterCloseFile(UIContext* context, FileContext* file, ViewFrame* frame) { (void)context; (void)file; (void)frame; }
+
+ virtual void OnViewChange(UIContext* context, ViewFrame* frame, const QString& type) { (void)context; (void)frame; (void)type; }
+};
+
class BINARYNINJAUIAPI UIContextHandler
{
public:
@@ -31,6 +49,7 @@ class BINARYNINJAUIAPI UIContext
static UIContextHandler* m_handler;
static std::set<UIContext*> m_contexts;
UIActionHandler m_globalActions;
+ static std::vector<UIContextNotification*> m_notifications;
static QPointer<PreviewWidget> m_currentPreview;
@@ -51,6 +70,23 @@ public:
UIActionHandler* globalActions() { return &m_globalActions; }
virtual UIActionHandler* contentActionHandler() = 0;
+ static void registerNotification(UIContextNotification* notification);
+ static void unregisterNotification(UIContextNotification* notification);
+
+ void NotifyOnContextOpen();
+ void NotifyOnContextClose();
+
+ bool NotifyOnBeforeOpenDatabase(FileMetadataRef metadata);
+ bool NotifyOnAfterOpenDatabase(FileMetadataRef metadata, BinaryViewRef data);
+ bool NotifyOnBeforeOpenFile(FileContext* file);
+ void NotifyOnAfterOpenFile(FileContext* file, ViewFrame* frame);
+ bool NotifyOnBeforeSaveFile(FileContext* file, ViewFrame* frame);
+ void NotifyOnAfterSaveFile(FileContext* file, ViewFrame* frame);
+ bool NotifyOnBeforeCloseFile(FileContext* file, ViewFrame* frame);
+ void NotifyOnAfterCloseFile(FileContext* file, ViewFrame* frame);
+
+ void NotifyOnViewChange(ViewFrame* frame, const QString& type);
+
static void setHandler(UIContextHandler* handler);
static QSize getScaledWindowSize(int x, int y);