diff options
| -rw-r--r-- | examples/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | examples/uinotification/CMakeLists.txt | 24 | ||||
| -rw-r--r-- | examples/uinotification/uinotification.cpp | 95 | ||||
| -rw-r--r-- | examples/uinotification/uinotification.h | 22 | ||||
| -rw-r--r-- | python/examples/ui_notifications.py | 77 | ||||
| -rw-r--r-- | ui/uicontext.h | 36 |
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); |
