summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRusty Wagner <rusty@vector35.com>2019-03-19 15:41:08 -0400
committerRusty Wagner <rusty@vector35.com>2019-03-20 13:00:17 -0400
commit411acbaa4a1d217e731d3df0b189445117be3b26 (patch)
tree49b5c5290058ffb98dd23ec9a7c1a49921254d15
parentca1bc587c22928bbd7198813064c9615c3c12771 (diff)
Add in progress UI API headers
-rw-r--r--ui/action.h367
-rw-r--r--ui/addressindicator.h24
-rw-r--r--ui/assembledialog.h33
-rw-r--r--ui/commandpalette.h110
-rw-r--r--ui/commands.h27
-rw-r--r--ui/commentdialog.h18
-rw-r--r--ui/compiledialog.h49
-rw-r--r--ui/compileoptions.h46
-rw-r--r--ui/createstructdialog.h30
-rw-r--r--ui/createtypedialog.h28
-rw-r--r--ui/dialogtextedit.h18
-rw-r--r--ui/disassemblyview.h179
-rw-r--r--ui/dockhandler.h112
-rw-r--r--ui/featuremap.h106
-rw-r--r--ui/filecontext.h77
-rw-r--r--ui/filter.h54
-rw-r--r--ui/flowgraphwidget.h285
-rw-r--r--ui/fontsettings.h32
-rw-r--r--ui/forminputdialog.h28
-rw-r--r--ui/functionlist.h135
-rw-r--r--ui/functionsview.h41
-rw-r--r--ui/hexeditor.h217
-rw-r--r--ui/instructionedit.h29
-rw-r--r--ui/linearview.h235
-rw-r--r--ui/logview.h165
-rw-r--r--ui/menus.h25
-rw-r--r--ui/minigraph.h39
-rw-r--r--ui/platformdialog.h30
-rw-r--r--ui/preview.h35
-rw-r--r--ui/progressindicator.h111
-rw-r--r--ui/qfileaccessor.h22
-rw-r--r--ui/render.h94
-rw-r--r--ui/reportcollectionwidget.h32
-rw-r--r--ui/reportwidget.h33
-rw-r--r--ui/scriptingconsole.h115
-rw-r--r--ui/statusbarwidget.h23
-rw-r--r--ui/stringsview.h149
-rw-r--r--ui/textdialog.h28
-rw-r--r--ui/theme.h119
-rw-r--r--ui/transformparam.h18
-rw-r--r--ui/typeview.h253
-rw-r--r--ui/uicontext.h76
-rw-r--r--ui/uitypes.h56
-rw-r--r--ui/viewframe.h262
-rw-r--r--ui/viewtype.h40
-rw-r--r--ui/xreflist.h87
46 files changed, 4092 insertions, 0 deletions
diff --git a/ui/action.h b/ui/action.h
new file mode 100644
index 00000000..b3050717
--- /dev/null
+++ b/ui/action.h
@@ -0,0 +1,367 @@
+#pragma once
+
+#include <QtWidgets/QMenu>
+#include <QtWidgets/QMenuBar>
+#include <QtGui/QIcon>
+#include <QtWidgets/QShortcut>
+#include <QtCore/QPointer>
+#include <functional>
+#include <map>
+#include <set>
+#include <vector>
+#include "uitypes.h"
+
+#define MENU_ORDER_FIRST 0
+#define MENU_ORDER_EARLY 64
+#define MENU_ORDER_NORMAL 128
+#define MENU_ORDER_LATE 192
+#define MENU_ORDER_LAST 255
+
+class View;
+class UIContext;
+
+struct BINARYNINJAUIAPI HighlightTokenState
+{
+ bool valid;
+ bool secondaryHighlight;
+ BNInstructionTextTokenType type;
+ BinaryNinja::InstructionTextToken token;
+ ArchitectureRef arch;
+ bool addrValid, localVarValid, isDest;
+ uint64_t addr;
+ BinaryNinja::Variable localVar;
+
+ HighlightTokenState();
+};
+
+struct BINARYNINJAUIAPI UIActionContext
+{
+ UIContext* context;
+ View* view;
+ QWidget* widget;
+ HighlightTokenState token;
+
+ BinaryViewRef binaryView;
+ uint64_t address, length;
+ size_t instrIndex;
+ FunctionRef function;
+ LowLevelILFunctionRef lowLevelILFunction;
+ MediumLevelILFunctionRef mediumLevelILFunction;
+
+ UIActionContext();
+ UIActionContext(const BinaryNinja::PluginCommandContext& pluginContext);
+ operator BinaryNinja::PluginCommandContext() const;
+};
+
+struct BINARYNINJAUIAPI UIAction
+{
+ std::function<void (const UIActionContext& context)> activate;
+ std::function<bool (const UIActionContext& context)> isValid;
+
+ UIAction();
+ UIAction(const std::function<void (const UIActionContext& context)>& activate);
+ UIAction(const std::function<void()>& activate);
+ UIAction(const std::function<void (const UIActionContext& context)>& activate,
+ const std::function<bool (const UIActionContext& context)>& isValid);
+ UIAction(const std::function<void()>& activate,
+ const std::function<bool (const UIActionContext& context)>& isValid);
+ UIAction(const std::function<void (const UIActionContext& context)>& activate,
+ const std::function<bool()>& isValid);
+ UIAction(const std::function<void()>& activate,
+ const std::function<bool()>& isValid);
+ UIAction(const UIAction& other);
+
+ static void registerAction(const QString& name, const QKeySequence& defaultKeyBinding = QKeySequence());
+ static void registerAction(const QString& name, const QList<QKeySequence>& defaultKeyBinding);
+
+ static void registerTransformActions();
+ static void registerPluginCommandActions();
+ static void registerPluginCommandActions(const QString& prefix);
+ static void registerHighlightColorActions(const QString& prefix);
+
+ static void setActionDisplayName(const QString& registeredName, const QString& displayName);
+ static void setActionDisplayName(const QString& registeredName, const std::function<QString()>& displayNameFunc);
+ static void setActionDisplayName(const QString& registeredName, const std::function<QString(const UIActionContext&)>& displayNameFunc);
+
+ static bool isActionRegistered(const QString& name);
+ static std::set<QString> getAllRegisteredActions();
+ static QList<QKeySequence> getDefaultKeyBinding(const QString& name);
+ static QList<QKeySequence> getKeyBinding(const QString& name);
+ static QString getActionDisplayName(const QString& name, const UIActionContext& context);
+
+ static int rawControl();
+ static int rawMeta();
+
+ static void setUserKeyBinding(const QString& name, const QList<QKeySequence>& keyBinding);
+ static void resetKeyBindingToDefault(const QString& name);
+ static void readKeyBindingsFile();
+ static void writeKeyBindingsFile();
+};
+
+struct BINARYNINJAUIAPI UITransformAction
+{
+ std::function<void (const UIActionContext& context, TransformRef xform)> activate;
+ std::function<bool (const UIActionContext& context, TransformRef xform)> isValid;
+
+ UITransformAction();
+ UITransformAction(const std::function<void (const UIActionContext& context, TransformRef xform)>& activate);
+ UITransformAction(const std::function<void(TransformRef xform)>& activate);
+ UITransformAction(const std::function<void (const UIActionContext& context, TransformRef xform)>& activate,
+ const std::function<bool (const UIActionContext& context, TransformRef xform)>& isValid);
+ UITransformAction(const std::function<void(TransformRef xform)>& activate,
+ const std::function<bool (const UIActionContext& context, TransformRef xform)>& isValid);
+ UITransformAction(const std::function<void (const UIActionContext& context, TransformRef xform)>& activate,
+ const std::function<bool(TransformRef xform)>& isValid);
+ UITransformAction(const std::function<void(TransformRef xform)>& activate,
+ const std::function<bool(TransformRef xform)>& isValid);
+ UITransformAction(const UITransformAction& other);
+};
+
+struct BINARYNINJAUIAPI UIHighlightColorAction
+{
+ std::function<void (const UIActionContext& context, BNHighlightColor color)> activate;
+ std::function<bool (const UIActionContext& context)> isValid;
+
+ UIHighlightColorAction();
+ UIHighlightColorAction(const std::function<void (const UIActionContext& context, BNHighlightColor color)>& activate);
+ UIHighlightColorAction(const std::function<void(BNHighlightColor color)>& activate);
+ UIHighlightColorAction(const std::function<void (const UIActionContext& context, BNHighlightColor color)>& activate,
+ const std::function<bool (const UIActionContext& context)>& isValid);
+ UIHighlightColorAction(const std::function<void(BNHighlightColor color)>& activate,
+ const std::function<bool (const UIActionContext& context)>& isValid);
+ UIHighlightColorAction(const std::function<void (const UIActionContext& context, BNHighlightColor color)>& activate,
+ const std::function<bool()>& isValid);
+ UIHighlightColorAction(const std::function<void(BNHighlightColor color)>& activate,
+ const std::function<bool()>& isValid);
+ UIHighlightColorAction(const UIHighlightColorAction& other);
+};
+
+enum ActionPriority
+{
+ LowActionPriority,
+ NormalActionPriority,
+ HighActionPriority
+};
+
+class BINARYNINJAUIAPI UIActionHandler
+{
+ std::map<QString, UIAction> m_actions;
+ std::map<QString, ActionPriority> m_priority;
+ std::map<QString, std::function<QString(const UIActionContext&)>> m_actionDisplayNames;
+ std::map<QString, std::function<bool(const UIActionContext&)>> m_checked;
+ QWidget* m_handlerWidget;
+ std::map<QString, std::vector<QShortcut*>> m_handlerWidgetShortcuts;
+ UIActionHandler* m_parent;
+ std::set<UIActionHandler*> m_children;
+ bool m_isGlobal, m_inheritParentBindings;
+ std::function<UIActionContext()> m_actionContextOverride;
+
+ static std::map<QString, std::set<UIActionHandler*>> m_actionBindings;
+ static std::set<QString> m_globalMenuActions;
+
+ void bindActionShortcutToWidget(const QString& name);
+ void unbindActionShortcut(const QString& name);
+ void addActionToChildren(const QString& name);
+ void removeActionFromChildren(const QString& name);
+
+public:
+ UIActionHandler(bool isGlobal = false);
+ virtual ~UIActionHandler();
+ void setupActionHandler(QWidget* obj, bool inheritParentBindings = true);
+
+ static UIActionHandler* actionHandlerFromWidget(QWidget* widget);
+ static UIActionHandler* globalActions();
+
+ void bindAction(const QString& name, const UIAction& action);
+ void bindAction(const QString& name, const UIAction& action, ActionPriority priority);
+ void unbindAction(const QString& name);
+
+ void executeAction(const QString& name);
+ void executeAction(const QString& name, const UIActionContext& context);
+ bool isBoundAction(const QString& name);
+ bool isValidAction(const QString& name);
+ bool isValidAction(const QString& name, const UIActionContext& context);
+ ActionPriority getPriority(const QString& name);
+
+ void bindCopyAsActions(const UITransformAction& action);
+ void bindPasteFromActions(const UITransformAction& action);
+ void bindTransformActions(const UITransformAction& encode, const UITransformAction& decode);
+ void unbindCopyAsActions();
+ void unbindPasteFromActions();
+ void unbindTransformActions();
+
+ void bindPluginCommandActions();
+ void bindPluginCommandActions(const QString& prefix,
+ const std::function<UIActionContext(const UIActionContext&, const BinaryNinja::PluginCommand&)>& context,
+ const std::function<bool(const UIActionContext&, const BinaryNinja::PluginCommand&)>& isValid);
+ void unbindPluginCommandActions();
+ void unbindPluginCommandActions(const QString& prefix);
+
+ void bindHighlightColorActions(const QString& prefix, const UIHighlightColorAction& action);
+ void unbindHighlightColorActions(const QString& prefix);
+
+ void setActionDisplayName(const QString& registeredName, const QString& displayName);
+ void setActionDisplayName(const QString& registeredName, const std::function<QString()>& displayNameFunc);
+ void setActionDisplayName(const QString& registeredName, const std::function<QString(const UIActionContext&)>& displayNameFunc);
+ QString getActionDisplayName(const QString& name);
+ QString getActionDisplayName(const QString& name, const UIActionContext& context);
+
+ void setChecked(const QString& name, bool checked);
+ void setChecked(const QString& name, const std::function<bool()>& checked);
+ void setChecked(const QString& name, const std::function<bool(const UIActionContext&)>& checked);
+ bool isChecked(const QString& name);
+ bool isChecked(const QString& name, const UIActionContext& context);
+ bool isCheckable(const QString& name);
+
+ std::set<QString> getAllValidActions();
+ std::set<QString> getAllValidActions(const UIActionContext& context);
+
+ UIActionContext defaultActionContext();
+ virtual UIActionContext actionContext();
+ void setActionContext(const std::function<UIActionContext()>& contextFunc);
+
+ QWidget* widget() { return m_handlerWidget; }
+
+ static void updateActionBindings(const QString& name);
+ static void addGlobalMenuAction(const QString& name);
+ static void removeGlobalMenuAction(const QString& name);
+
+ static void reparentWidget(QWidget* widget);
+};
+
+enum MenuItemVisibility
+{
+ DefaultMenuItemVisibility,
+ ShowMenuItemOnlyWhenActive,
+ AlwaysShowMenuItem,
+ NeverShowMenuItem
+};
+
+class MenuInstance;
+
+class BINARYNINJAUIAPI Menu
+{
+ std::map<QString, QString> m_actions;
+ std::map<QString, QString> m_groups;
+ std::map<QString, uint8_t> m_order, m_groupOrder;
+ std::map<QString, MenuItemVisibility> m_visibility;
+ std::map<QString, QAction::MenuRole> m_roles;
+ std::map<QString, QIcon> m_icons;
+ uint64_t m_version;
+ bool m_global;
+
+ Menu(bool global);
+ void setParentOrdering(const QString& path, const QString& group, uint8_t order);
+
+public:
+ Menu();
+ Menu(const Menu& menu);
+
+ void addAction(const QString& action, const QString& group, uint8_t order = MENU_ORDER_NORMAL);
+ void addAction(const QString& submenu, const QString& action, const QString& group, uint8_t order = MENU_ORDER_NORMAL);
+ void removeAction(const QString& action);
+ void removeAction(const QString& submenu, const QString& action);
+
+ void addCopyAsActions(const QString& group, uint8_t order = MENU_ORDER_NORMAL);
+ void addPasteFromActions(const QString& group, uint8_t order = MENU_ORDER_NORMAL);
+ void addTransformActions(const QString& group, uint8_t order = MENU_ORDER_NORMAL);
+ void removeCopyAsActions();
+ void removePasteFromActions();
+ void removeTransformActions();
+
+ void addPluginCommandActions(const QString& group);
+ void addPluginCommandActions(const QString& prefix, const QString& group, uint8_t order = MENU_ORDER_NORMAL);
+ void addPluginCommandSubmenuActions(const QString& submenu, const QString& group);
+ void addPluginCommandSubmenuActions(const QString& submenu, const QString& prefix, const QString& group,
+ uint8_t order = MENU_ORDER_NORMAL);
+ void removePluginCommandActions();
+ void removePluginCommandSubmenuActions(const QString& submenu);
+
+ void addHighlightColorActions(const QString& submenu, const QString& group, uint8_t order = MENU_ORDER_NORMAL);
+ void removeHighlightColorActions(const QString& submenu);
+
+ void setOrdering(const QString& path, const QString& group, uint8_t order = MENU_ORDER_NORMAL);
+ void setGroupOrdering(const QString& group, uint8_t order);
+
+ void setVisibility(const QString& path, MenuItemVisibility visibility);
+ void setRole(const QString& path, QAction::MenuRole role);
+
+ void setIcon(const QString& path, const QIcon& icon);
+
+ MenuInstance* create(QWidget* owner, UIActionHandler* handler, bool showInactiveActions = false);
+ MenuInstance* create(QWidget* owner, UIActionHandler* handler, const UIActionContext& context,
+ bool showInactiveActions = false);
+
+ uint64_t getVersion();
+ const std::map<QString, QString>& getActions();
+ QString getGroupForAction(const QString& name);
+ uint8_t getOrderForAction(const QString& name);
+ uint8_t getOrderForGroup(const QString& name);
+ MenuItemVisibility getVisibility(const QString& name);
+ QAction::MenuRole getRole(const QString& name);
+ QIcon getIcon(const QString& name);
+
+ static Menu* mainMenu(const QString& name);
+ static void setMainMenuOrder(const QString& name, uint8_t order);
+ static std::vector<QString> getMainMenus();
+};
+
+class BINARYNINJAUIAPI MenuInstance
+{
+ Menu* m_menu;
+ QMenu* m_instance;
+ UIActionHandler* m_handler;
+ UIActionContext m_context;
+ uint64_t m_version;
+ std::map<QString, QPointer<QAction>> m_actions;
+
+ struct Group;
+
+ struct Item
+ {
+ QString name, action;
+ uint8_t order;
+ QAction::MenuRole role;
+ QIcon icon;
+ bool checkable;
+ std::vector<Group> submenu;
+ };
+
+ struct Group
+ {
+ QString name;
+ std::vector<Item> items;
+ uint8_t order;
+ };
+
+ static std::map<QString, std::set<MenuInstance*>> m_actionBindings;
+
+ std::vector<Group> layoutMenu(const std::map<QString, QString>& actions, const QString& prefix,
+ bool showInactiveActions);
+ void addGroupsToMenu(QMenu* menu, const std::vector<Group>& groups);
+
+public:
+ MenuInstance(Menu* menu, QMenu* instance);
+ virtual ~MenuInstance();
+ void update(UIActionHandler* handler, bool showInactiveActions = false);
+ void update(UIActionHandler* handler, const UIActionContext& context, bool showInactiveActions = false);
+
+ Menu* source() const { return m_menu; }
+ QMenu* instance() const { return m_instance; }
+
+ static void updateActionBindings(const QString& name);
+};
+
+class BINARYNINJAUIAPI MainMenuInstance
+{
+ QMenuBar* m_instance;
+ std::map<QString, MenuInstance*> m_menus;
+
+public:
+ MainMenuInstance(QMenuBar* instance);
+ ~MainMenuInstance();
+ void update(UIActionHandler* handler);
+ void update(UIActionHandler* handler, const UIActionContext& context);
+};
+
+Q_DECLARE_METATYPE(UIActionHandler*)
diff --git a/ui/addressindicator.h b/ui/addressindicator.h
new file mode 100644
index 00000000..3ad40638
--- /dev/null
+++ b/ui/addressindicator.h
@@ -0,0 +1,24 @@
+#pragma once
+
+#include <QtWidgets/QLabel>
+#include "viewframe.h"
+#include "menus.h"
+#include "uicontext.h"
+
+class BINARYNINJAUIAPI AddressIndicator: public QLabel
+{
+ Q_OBJECT
+
+ uint64_t m_begin, m_end;
+ ContextMenuManager m_contextMenu;
+
+public:
+ AddressIndicator(QWidget* parent);
+
+ void setOffsets(uint64_t begin, uint64_t end);
+
+protected:
+ virtual void mousePressEvent(QMouseEvent* event);
+ virtual void enterEvent(QEvent* event);
+ virtual void leaveEvent(QEvent* event);
+};
diff --git a/ui/assembledialog.h b/ui/assembledialog.h
new file mode 100644
index 00000000..8d1f1c45
--- /dev/null
+++ b/ui/assembledialog.h
@@ -0,0 +1,33 @@
+#pragma once
+
+#include <QtWidgets/QDialog>
+#include <QtWidgets/QComboBox>
+#include "binaryninjaapi.h"
+#include "dialogtextedit.h"
+#include "uicontext.h"
+
+class BINARYNINJAUIAPI AssembleDialog: public QDialog
+{
+ Q_OBJECT
+
+ BinaryViewRef m_view;
+ uint64_t m_addr;
+ QComboBox* m_archSelection;
+ DialogTextEdit* m_code;
+ BinaryNinja::DataBuffer m_bytes;
+ bool m_setDefault;
+
+public:
+ AssembleDialog(QWidget* parent, BinaryViewRef data, uint64_t addr, ArchitectureRef prefArch = NULL, const QString& code = "");
+
+ ArchitectureRef getArchitecture();
+ const BinaryNinja::DataBuffer& getBytes() const { return m_bytes; }
+
+private Q_SLOTS:
+ void saveOnFinish(int result);
+ void assemble();
+
+protected:
+ virtual void accept() override;
+
+};
diff --git a/ui/commandpalette.h b/ui/commandpalette.h
new file mode 100644
index 00000000..f009764d
--- /dev/null
+++ b/ui/commandpalette.h
@@ -0,0 +1,110 @@
+#pragma once
+
+#include <QtWidgets/QListView>
+#include <QtCore/QAbstractItemModel>
+#include <QtWidgets/QLineEdit>
+#include <QtWidgets/QFrame>
+#include <QtCore/QPointer>
+#include <vector>
+#include "action.h"
+
+struct BINARYNINJAUIAPI CommandListItem
+{
+ QString name;
+ QString shortcut;
+ QString action;
+};
+
+class CommandPalette;
+class CommandListFilter;
+
+class BINARYNINJAUIAPI CommandListModel: public QAbstractItemModel
+{
+ Q_OBJECT
+
+ std::vector<CommandListItem> m_items;
+ std::vector<CommandListItem> m_allItems;
+
+ bool isFilterMatch(const QString& name, const QString& filter);
+ int getFilterMatchScore(const QString& name, const QString& filter);
+
+public:
+ CommandListModel(QWidget* parent, const std::vector<CommandListItem>& items);
+
+ virtual QModelIndex index(int row, int col, const QModelIndex& parent) const override;
+ virtual QModelIndex parent(const QModelIndex& i) const override;
+ virtual bool hasChildren(const QModelIndex& parent) const override;
+ virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override;
+ virtual int columnCount(const QModelIndex& parent) const override;
+ virtual QVariant data(const QModelIndex& i, int role) const override;
+
+ QString getActionForItem(int row);
+ void setFilterText(const QString& text);
+};
+
+class BINARYNINJAUIAPI CommandList: public QListView
+{
+ Q_OBJECT
+
+ CommandPalette* m_palette;
+ CommandListModel* m_model;
+ CommandListFilter* m_filter;
+
+public:
+ CommandList(CommandPalette* parent, const std::vector<CommandListItem>& items);
+ void setFilter(CommandListFilter* filter) { m_filter = filter; }
+ void setFilterText(const QString& text);
+
+ QString getActionForItem(int row);
+
+ QModelIndex index(int row, int col, const QModelIndex& parent = QModelIndex()) const;
+
+protected:
+ virtual void keyPressEvent(QKeyEvent* event) override;
+ virtual void focusOutEvent(QFocusEvent* event) override;
+};
+
+class BINARYNINJAUIAPI CommandListFilter: public QLineEdit
+{
+ Q_OBJECT
+
+ CommandPalette* m_palette;
+ CommandList* m_list;
+
+public:
+ CommandListFilter(CommandPalette* parent, CommandList* list);
+
+protected:
+ virtual void keyPressEvent(QKeyEvent* event) override;
+ virtual void focusOutEvent(QFocusEvent* event) override;
+};
+
+class BINARYNINJAUIAPI CommandPalette: public QFrame
+{
+ Q_OBJECT
+
+ UIActionHandler* m_handler;
+ UIActionContext m_context;
+ QPointer<QWidget> m_previousWidget;
+
+ CommandListFilter* m_filter;
+ CommandList* m_list;
+
+ bool m_executing;
+
+ std::vector<CommandListItem> getCommandList();
+ void init();
+
+public:
+ CommandPalette(QWidget* parent, UIActionHandler* handler);
+ CommandPalette(QWidget* parent, UIActionHandler* handler, const UIActionContext& context);
+
+ void focusInput();
+ void activateFirstItem();
+ void selectFirstItem();
+ void close();
+
+private Q_SLOTS:
+ void itemClicked(const QModelIndex& idx);
+ void filterChanged(const QString& text);
+};
diff --git a/ui/commands.h b/ui/commands.h
new file mode 100644
index 00000000..0bc7d8f2
--- /dev/null
+++ b/ui/commands.h
@@ -0,0 +1,27 @@
+#pragma once
+
+#include <QtWidgets/QWidget>
+#include "binaryninjaapi.h"
+#include "render.h"
+#include "uicontext.h"
+
+bool BINARYNINJAUIAPI undefineNameForAddress(BinaryViewRef data, uint64_t addr);
+bool BINARYNINJAUIAPI undefineNameForLocalVariable(BinaryViewRef data,
+ FunctionRef func, const BinaryNinja::Variable& var);
+bool BINARYNINJAUIAPI inputNameForAddress(QWidget* parent, BinaryViewRef data, uint64_t addr);
+bool BINARYNINJAUIAPI inputNameForLocalVariable(QWidget* parent, BinaryViewRef data,
+ FunctionRef function, const BinaryNinja::Variable& var);
+bool BINARYNINJAUIAPI inputNameForType(QWidget* parent, std::string& name, const QString& title = "Set Name",
+ const QString& msg = "Enter name:");
+
+bool BINARYNINJAUIAPI askForNewType(QWidget* parent, BinaryViewRef data, FunctionRef func, const std::string& title,
+ TypeRef& type, BinaryNinja::QualifiedName& name);
+bool BINARYNINJAUIAPI inputNewType(QWidget* parent, BinaryViewRef data, FunctionRef currentFunction,
+ uint64_t currentAddr, HighlightTokenState& highlight);
+
+bool BINARYNINJAUIAPI overwriteCode(BinaryViewRef data, ArchitectureRef arch,
+ uint64_t addr, const BinaryNinja::DataBuffer& buffer);
+
+StructureRef BINARYNINJAUIAPI getInnerMostStructureContaining(
+ StructureRef structure, size_t& memberIndex, const std::vector<std::string>& nameList,
+ size_t nameIndex);
diff --git a/ui/commentdialog.h b/ui/commentdialog.h
new file mode 100644
index 00000000..803fcd3b
--- /dev/null
+++ b/ui/commentdialog.h
@@ -0,0 +1,18 @@
+#pragma once
+
+#include <QtWidgets/QDialog>
+#include <QtWidgets/QComboBox>
+#include "binaryninjaapi.h"
+#include "dialogtextedit.h"
+#include "uicontext.h"
+
+class BINARYNINJAUIAPI CommentDialog: public QDialog
+{
+ Q_OBJECT
+
+ DialogTextEdit* m_comment;
+
+public:
+ CommentDialog(QWidget* parent, const QString& comment = "");
+ QString getComment();
+};
diff --git a/ui/compiledialog.h b/ui/compiledialog.h
new file mode 100644
index 00000000..c5d2123a
--- /dev/null
+++ b/ui/compiledialog.h
@@ -0,0 +1,49 @@
+#pragma once
+
+#include <QtWidgets/QDialog>
+#include <QtWidgets/QComboBox>
+#include <QtWidgets/QLabel>
+#include <set>
+#include "binaryninjaapi.h"
+#include "dialogtextedit.h"
+#include "uicontext.h"
+
+enum CompileMode
+{
+ CompileStandalone,
+ CompilePatch
+};
+
+class BINARYNINJAUIAPI CompileDialog: public QDialog
+{
+ Q_OBJECT
+
+ BinaryViewRef m_view;
+ uint64_t m_addr;
+ QComboBox* m_arch;
+ QComboBox* m_os;
+ DialogTextEdit* m_code;
+ QLabel* m_optionsText;
+ bool m_saveOSSetting;
+ std::map<std::string, std::string> m_options;
+ std::set<std::string> m_unsavedOptions;
+ BinaryNinja::DataBuffer m_bytes;
+ bool m_setDefault;
+
+ void appendOptionString(std::string& out, const std::string& text);
+ void updateOptionsText();
+
+public:
+ CompileDialog(QWidget* parent, BinaryViewRef data, uint64_t addr, CompileMode mode, const QString& code = "");
+
+ ArchitectureRef getArchitecture();
+ const BinaryNinja::DataBuffer& getBytes() const { return m_bytes; }
+
+private Q_SLOTS:
+ void saveOnFinish(int result);
+ void compile();
+ void options();
+
+protected:
+ virtual void accept() override;
+};
diff --git a/ui/compileoptions.h b/ui/compileoptions.h
new file mode 100644
index 00000000..53a7e687
--- /dev/null
+++ b/ui/compileoptions.h
@@ -0,0 +1,46 @@
+#pragma once
+
+#include <QtWidgets/QDialog>
+#include <QtWidgets/QCheckBox>
+#include <QtWidgets/QRadioButton>
+#include <QtWidgets/QLineEdit>
+#include "binaryninjaapi.h"
+#include "uicontext.h"
+
+class BINARYNINJAUIAPI CompileOptions: public QDialog
+{
+ Q_OBJECT
+
+ QCheckBox* m_safeStack;
+ QLineEdit* m_blacklist;
+ QLineEdit* m_base;
+ QLineEdit* m_maxLength;
+ QCheckBox* m_pad;
+ QCheckBox* m_polymorph;
+
+ QRadioButton* m_exit;
+ QRadioButton* m_allowReturn;
+ QRadioButton* m_concat;
+
+ QLineEdit* m_stackReg;
+ QLineEdit* m_frameReg;
+ QLineEdit* m_baseReg;
+ QLineEdit* m_returnReg;
+ QLineEdit* m_returnHighReg;
+ QCheckBox* m_encodePointers;
+ QCheckBox* m_stackGrowsUp;
+ QCheckBox* m_antiDisasm;
+ QLineEdit* m_antiDisasmFreq;
+ QLineEdit* m_seed;
+
+ QString optionValue(const std::map<std::string, std::string>& options, const std::string& name);
+ void updateOptions(const std::map<std::string, std::string>& options);
+
+public:
+ CompileOptions(QWidget* parent, const std::map<std::string, std::string>& initialOptions);
+
+ std::map<std::string, std::string> getSettings();
+
+private Q_SLOTS:
+ void reset();
+};
diff --git a/ui/createstructdialog.h b/ui/createstructdialog.h
new file mode 100644
index 00000000..df117411
--- /dev/null
+++ b/ui/createstructdialog.h
@@ -0,0 +1,30 @@
+#pragma once
+
+#include <QtWidgets/QDialog>
+#include <QtWidgets/QLineEdit>
+#include "binaryninjaapi.h"
+#include "uicontext.h"
+
+class BINARYNINJAUIAPI CreateStructDialog: public QDialog
+{
+ Q_OBJECT
+
+ QLineEdit* m_name;
+ QLineEdit* m_size;
+
+ BinaryNinja::QualifiedName m_resultName;
+ uint64_t m_resultSize;
+
+public:
+ CreateStructDialog(QWidget* parent);
+
+ BinaryNinja::QualifiedName getName() { return m_resultName; }
+ uint64_t getSize() { return m_resultSize; }
+
+private Q_SLOTS:
+ void createStruct();
+
+protected:
+ virtual void showEvent(QShowEvent* e) override;
+
+};
diff --git a/ui/createtypedialog.h b/ui/createtypedialog.h
new file mode 100644
index 00000000..1d0effe3
--- /dev/null
+++ b/ui/createtypedialog.h
@@ -0,0 +1,28 @@
+#pragma once
+
+#include <QtWidgets/QDialog>
+#include <QtWidgets/QLineEdit>
+#include "binaryninjaapi.h"
+#include "dialogtextedit.h"
+#include "uicontext.h"
+
+class BINARYNINJAUIAPI CreateTypeDialog: public QDialog
+{
+ Q_OBJECT
+
+ DialogTextEdit* m_code;
+
+ BinaryViewRef m_data;
+ std::map<BinaryNinja::QualifiedName, TypeRef> m_results;
+
+public:
+ CreateTypeDialog(QWidget* parent, BinaryViewRef data, const QString& definition);
+ std::map<BinaryNinja::QualifiedName, TypeRef> getResults() { return m_results; }
+
+private Q_SLOTS:
+ void createType();
+
+protected:
+ virtual void showEvent(QShowEvent* e) override;
+
+};
diff --git a/ui/dialogtextedit.h b/ui/dialogtextedit.h
new file mode 100644
index 00000000..cc719aae
--- /dev/null
+++ b/ui/dialogtextedit.h
@@ -0,0 +1,18 @@
+#pragma once
+
+#include <QtWidgets/QTextEdit>
+#include "uicontext.h"
+
+class BINARYNINJAUIAPI DialogTextEdit: public QTextEdit
+{
+ Q_OBJECT
+
+public:
+ DialogTextEdit(QWidget* parent);
+
+protected:
+ virtual void keyPressEvent(QKeyEvent* event) override;
+
+Q_SIGNALS:
+ void contentAccepted();
+};
diff --git a/ui/disassemblyview.h b/ui/disassemblyview.h
new file mode 100644
index 00000000..477081fb
--- /dev/null
+++ b/ui/disassemblyview.h
@@ -0,0 +1,179 @@
+#pragma once
+
+#include <QtWidgets/QAbstractScrollArea>
+#include <QtCore/QPointer>
+#include <QtWidgets/QSplitter>
+#include <QtWidgets/QLabel>
+#include <mutex>
+#include "binaryninjaapi.h"
+#include "viewframe.h"
+#include "instructionedit.h"
+#include "render.h"
+#include "progressindicator.h"
+#include "commentdialog.h"
+#include "menus.h"
+#include "statusbarwidget.h"
+#include "flowgraphwidget.h"
+
+#define FUNCTION_UPDATE_CHECK_INTERVAL 100
+
+class BINARYNINJAUIAPI DisassemblyHistoryEntry: public FlowGraphHistoryEntry
+{
+ BNFunctionGraphType m_graphType;
+
+public:
+ BNFunctionGraphType getGraphType() const { return m_graphType; }
+ void setGraphType(BNFunctionGraphType type) { m_graphType = type; }
+};
+
+class DisassemblyContainer;
+
+class BINARYNINJAUIAPI DisassemblyView: public FlowGraphWidget
+{
+ Q_OBJECT
+
+friend class DisassemblyFunctionHeader;
+
+public:
+ explicit DisassemblyView(DisassemblyContainer* parent, BinaryViewRef data, FunctionRef func = nullptr,
+ bool navToAddr = false, uint64_t addr = 0);
+
+ virtual bool navigate(uint64_t pos) override;
+ virtual bool navigateToFunction(FunctionRef func, uint64_t pos) override;
+
+ virtual HistoryEntry* getHistoryEntry() override;
+ virtual void navigateToHistoryEntry(HistoryEntry* entry) override;
+
+ virtual StatusBarWidget* getStatusBarWidget() override;
+
+ void setGraphType(BNFunctionGraphType type);
+ void setOption(BNDisassemblyOption option, bool state = true);
+ void toggleOption(BNDisassemblyOption option);
+
+ DisassemblySettingsRef getSettings();
+
+ virtual void onFunctionSelected(FunctionRef func) override;
+ virtual void onHighlightChanged(const HighlightTokenState& highlight) override;
+
+ static void registerActions();
+
+private:
+ class DisassemblyViewOptionsWidget: public QLabel
+ {
+ public:
+ DisassemblyViewOptionsWidget(DisassemblyView* parent);
+
+ protected:
+ virtual void mousePressEvent(QMouseEvent* event);
+ virtual void enterEvent(QEvent* event);
+ virtual void leaveEvent(QEvent* event);
+
+ private:
+ DisassemblyView* m_view;
+ Menu m_menu;
+ ContextMenuManager m_contextMenuManager;
+ };
+
+ class DisassemblyViewStatusBarWidget: public StatusBarWidget
+ {
+ public:
+ DisassemblyViewStatusBarWidget(DisassemblyView* parent);
+ virtual void updateStatus() override;
+
+ private:
+ DisassemblyView* m_view;
+ DisassemblyViewOptionsWidget* m_options;
+ };
+
+ void bindActions();
+
+ BNFunctionGraphType m_graphType;
+ std::set<BNDisassemblyOption> m_options;
+ DisassemblyContainer* m_container;
+
+private Q_SLOTS:
+ void viewInHexEditor();
+ void viewInLinearDisassembly();
+};
+
+
+class BINARYNINJAUIAPI DisassemblyFunctionHeader: public QWidget
+{
+ Q_OBJECT
+
+ DisassemblyContainer* m_container;
+
+ BinaryViewRef m_data;
+ FunctionRef m_func;
+
+ QProgressIndicator* m_updateIndicator;
+ QTimer* m_updateTimer;
+
+ RenderContext m_render;
+ std::vector<BinaryNinja::DisassemblyTextLine> m_lines;
+ size_t m_width;
+ HighlightTokenState m_highlight;
+
+ void adjustSize(int width, int height);
+
+private Q_SLOTS:
+ void updateTimerEvent();
+
+protected:
+ virtual void paintEvent(QPaintEvent* event) override;
+ virtual void resizeEvent(QResizeEvent* event) override;
+
+ virtual void mousePressEvent(QMouseEvent* event) override;
+ virtual void mouseDoubleClickEvent(QMouseEvent* event) override;
+
+public:
+ DisassemblyFunctionHeader(DisassemblyContainer* parent, BinaryViewRef data);
+
+ void updateFonts();
+ void setCurrentFunction(FunctionRef func);
+ void setHighlightToken(const HighlightTokenState& state);
+
+ virtual QSize sizeHint() const override;
+};
+
+class BINARYNINJAUIAPI DisassemblyContainer: public QWidget, public ViewContainer
+{
+ Q_OBJECT
+
+ ViewFrame* m_viewFrame;
+ DisassemblyView* m_view;
+ DisassemblyFunctionHeader* m_funcHeader;
+ QWidget* m_analysisWarning;
+ QLabel* m_analysisWarningText;
+
+public:
+ explicit DisassemblyContainer(QWidget* parent, BinaryViewRef data, ViewFrame* view, FunctionRef func = nullptr,
+ bool navToAddr = false, uint64_t addr = 0);
+ virtual View* getView() override { return m_view; }
+ ViewFrame* getViewFrame() { return m_viewFrame; }
+
+ DisassemblyView* getDisassembly() const { return m_view; }
+ DisassemblyFunctionHeader* getFunctionHeader() const { return m_funcHeader; }
+
+ void updateFonts();
+ void refreshHeader(FunctionRef func);
+ void setCurrentFunction(FunctionRef func);
+ void setHeaderHighlightToken(const HighlightTokenState& state);
+
+protected:
+ virtual void focusInEvent(QFocusEvent* event) override;
+
+private Q_SLOTS:
+ void linkActivatedEvent(const QString& link);
+};
+
+class DisassemblyViewType: public ViewType
+{
+ static DisassemblyViewType* m_instance;
+
+public:
+ DisassemblyViewType();
+ virtual int getPriority(BinaryViewRef data, const QString& filename);
+ virtual QWidget* create(BinaryViewRef data, ViewFrame* viewFrame);
+ static void init();
+};
diff --git a/ui/dockhandler.h b/ui/dockhandler.h
new file mode 100644
index 00000000..08392532
--- /dev/null
+++ b/ui/dockhandler.h
@@ -0,0 +1,112 @@
+#pragma once
+
+#include <QtCore/QObject>
+#include <QtCore/QSettings>
+#include <QtWidgets/QDockWidget>
+#include <map>
+
+#include "binaryninjaapi.h"
+#include "action.h"
+#include "uitypes.h"
+
+class ContextMenuManager;
+class DockHandler;
+class Menu;
+class View;
+class ViewFrame;
+
+struct BINARYNINJAUIAPI DockProperties
+{
+ DockProperties() { };
+ DockProperties(QDockWidget* dw, bool vis, Qt::DockWidgetArea dar, Qt::Orientation dor, bool dvis, bool vs) :
+ dockWidget(dw), visibleState(vis), defaultArea(dar), defaultOrientation(dor), defaultVisibility(dvis),
+ viewSensitive(vs), neverBeenVisible(true), sizeStash(0, 0), actionOnShow(nullptr) { }
+ DockProperties(const DockProperties &dp) :
+ dockWidget(dp.dockWidget), visibleState(dp.visibleState), defaultArea(dp.defaultArea),
+ defaultOrientation(dp.defaultOrientation), defaultVisibility(dp.defaultVisibility),
+ viewSensitive(dp.viewSensitive), neverBeenVisible(dp.neverBeenVisible), sizeStash(dp.sizeStash), actionOnShow(dp.actionOnShow) { }
+
+ QDockWidget* dockWidget;
+ bool visibleState;
+ Qt::DockWidgetArea defaultArea;
+ Qt::Orientation defaultOrientation;
+ bool defaultVisibility;
+ bool viewSensitive;
+ bool neverBeenVisible;
+ QSize sizeStash;
+ std::function<void()> actionOnShow;
+};
+
+struct DockSizePrefs
+{
+ DockSizePrefs() { }
+ QList<QDockWidget*> docks;
+ QList<int> hDockSizes;
+ QList<int> vDockSizes;
+ bool nonUniformVisibility = false;
+};
+
+class BINARYNINJAUIAPI DockContextHandler
+{
+protected:
+ QString m_name;
+ UIActionHandler m_actionHandler;
+ ContextMenuManager* m_contextMenuManager = nullptr;
+ Menu* m_menu = nullptr;
+ QWidget* m_parentWindow;
+
+public:
+ DockContextHandler(QWidget* widget, const QString& name);
+ virtual ~DockContextHandler();
+
+ QWidget* getParentWindow() { return m_parentWindow; }
+
+ virtual void focusInput() { };
+ virtual bool isAvailable(ViewFrame* /*frame*/) { return true; };
+ virtual void notifyViewChanged(ViewFrame* /*frame*/) { };
+ virtual bool shouldBeVisible(ViewFrame* /*frame*/) { return true; };
+ virtual void updateFonts() { };
+};
+
+class BINARYNINJAUIAPI DockHandler: public QObject
+{
+ Q_OBJECT
+
+ int m_windowIndex = 0;
+ ViewFrame* m_viewFrame = nullptr;
+ View* m_view = nullptr;
+ BinaryViewRef m_data;
+ std::map<QString, DockProperties> m_docks;
+ bool m_resizeDocksRequest = false;
+ bool m_shouldResizeDocks = false;
+ std::map<Qt::DockWidgetArea, bool> m_enableHiddenGroupSave;
+
+public:
+ explicit DockHandler(QObject* parent, int windowIndex);
+
+ void close();
+ void notifyRestoredFromState();
+ void reset(bool initial = false);
+ void reset(const QString& name);
+ void resizeDocksOnShow(bool resizeDocks) { m_resizeDocksRequest = resizeDocks; }
+ bool addDockWidget(const QString& name, QWidget* primaryWidget, Qt::DockWidgetArea area = Qt::BottomDockWidgetArea, Qt::Orientation orientation = Qt::Horizontal, bool defaultVisibility = false);
+ QDockWidget* getDockWidget(const QString& name);
+ ViewFrame* getViewFrame() { return m_viewFrame; }
+ bool isVisible(const QString& name);
+ void setVisible(const QString& name, bool visible);
+
+ void saveState(QSettings& settings, const QString& windowStateName);
+ void restoreState(QSettings& settings, const QString& windowStateName);
+ void saveDockSizes(bool nullFrame = false);
+ void restoreDockSizes();
+
+ bool shouldResizeDocks();
+ void updateFonts();
+ void addActionOnShow(const QString& name, const std::function<void()>& action);
+
+ static DockHandler* getActiveDockHandler();
+
+public Q_SLOTS:
+ void viewChanged(ViewFrame* frame);
+ void topLevelChanged(bool topLevel);
+};
diff --git a/ui/featuremap.h b/ui/featuremap.h
new file mode 100644
index 00000000..bc2a13cd
--- /dev/null
+++ b/ui/featuremap.h
@@ -0,0 +1,106 @@
+#pragma once
+
+#include <QtWidgets/QAction>
+#include <QtGui/QColor>
+#include <QtGui/QImage>
+#include <QtWidgets/QMenu>
+#include <QtGui/QPainter>
+#include <QtCore/QRect>
+#include <QtCore/QTimer>
+#include <QtCore/QVector>
+#include <QtWidgets/QWidget>
+#include <mutex>
+#include <tuple>
+#include <vector>
+
+#include "binaryninjaapi.h"
+#include "dockhandler.h"
+#include "uitypes.h"
+
+class ContextMenuManager;
+class Menu;
+class View;
+class ViewFrame;
+
+class BINARYNINJAUIAPI FeatureMap: public QWidget, public BinaryNinja::BinaryDataNotification, public DockContextHandler
+{
+ Q_OBJECT
+
+ QImage* m_image = nullptr;
+ QImage* m_staticImage = nullptr;
+ std::vector<std::pair<uint64_t, uint64_t>> m_regions;
+
+ ViewFrame* m_frame = nullptr;
+ BinaryViewRef m_data;
+
+ bool m_updatesPending = false;
+ QTimer* m_updateTimer = nullptr;
+ size_t m_bvWidth = 0;
+ size_t m_bvHeight = 0;
+ uint64_t m_bvLength = 0;
+
+ int m_defaultWidth = 100;
+
+ int m_curLocX = 0;
+ int m_curLocY = 0;
+ uint64_t m_curAddr = 0;
+ bool m_navigationInProgress = false;
+
+ QVector<QColor> m_colors;
+ QVector<QRgb> m_colorTable;
+
+ class BackgroundRefresh: public BinaryNinja::RefCountObject
+ {
+ std::mutex m_mutex;
+ bool m_valid;
+ FeatureMap* m_featureMap;
+
+ public:
+ BackgroundRefresh(FeatureMap* featureMap);
+ void start();
+ void abort();
+ };
+
+ BinaryNinja::Ref<BackgroundRefresh> m_backgroundRefresh;
+
+public:
+ FeatureMap(ViewFrame* frame, BinaryViewRef data);
+ virtual ~FeatureMap();
+
+ View* getBinaryDataNavigableView(bool preferGraphView = false);
+ void backgroundRefresh();
+ std::pair<uint64_t, bool> getOffsetForAddress(uint64_t addr);
+ void setCurrentLocation(uint64_t address);
+ void updateTheme();
+
+ void renderDataVariable(const BinaryNinja::DataVariable& var, bool ignoreString = false);
+
+ virtual void OnAnalysisFunctionAdded(BinaryNinja::BinaryView* data, BinaryNinja::Function* func) override;
+ virtual void OnAnalysisFunctionRemoved(BinaryNinja::BinaryView* data, BinaryNinja::Function* func) override;
+ virtual void OnAnalysisFunctionUpdated(BinaryNinja::BinaryView* data, BinaryNinja::Function* func) override;
+ virtual void OnDataVariableAdded(BinaryNinja::BinaryView* data, const BinaryNinja::DataVariable& var) override;
+ virtual void OnDataVariableRemoved(BinaryNinja::BinaryView* data, const BinaryNinja::DataVariable& var) override;
+ virtual void OnDataVariableUpdated(BinaryNinja::BinaryView* data, const BinaryNinja::DataVariable& var) override;
+ virtual void OnStringFound(BinaryNinja::BinaryView* data, BNStringType type, uint64_t offset, size_t len) override;
+ virtual void OnStringRemoved(BinaryNinja::BinaryView* data, BNStringType type, uint64_t offset, size_t len) override;
+
+ void drawImageRect(uint64_t addr, size_t len, uint8_t color);
+
+ virtual QSize sizeHint() const override;
+
+protected:
+ virtual void contextMenuEvent(QContextMenuEvent* event) override;
+ virtual void mouseMoveEvent(QMouseEvent* event) override;
+ virtual void mousePressEvent(QMouseEvent* event) override;
+ virtual void resizeEvent(QResizeEvent* event) override;
+ virtual void paintEvent(QPaintEvent* event) override;
+ void scrollTo(int x, int y, bool addHistoryEntry = false);
+
+Q_SIGNALS:
+ void notifyThemeUpdated();
+
+private Q_SLOTS:
+ void refresh();
+ void updateThemeInternal();
+ void updateTimerEvent();
+};
diff --git a/ui/filecontext.h b/ui/filecontext.h
new file mode 100644
index 00000000..bd11a4ff
--- /dev/null
+++ b/ui/filecontext.h
@@ -0,0 +1,77 @@
+#pragma once
+
+#include <QtCore/QString>
+#include <map>
+#include <set>
+#include <string>
+#include "binaryninjaapi.h"
+#include "uicontext.h"
+
+class ViewFrame;
+class ViewType;
+
+// This base class is required for building the Python bindings. The other base classes of FileContext are
+// ignored (as they have no functions that should be exported to Python), but this would leave the binding
+// generator with a derived class with no base and a compiler error.
+class FileContextBase
+{
+public:
+ FileContextBase() {}
+};
+
+class BINARYNINJAUIAPI FileContext: public FileContextBase, public BinaryNinja::NavigationHandler
+{
+ QString m_filename;
+ bool m_isValidSaveFilename;
+ FileMetadataRef m_file;
+
+ BinaryViewRef m_rawData;
+ std::map<QString, BinaryViewRef> m_dataViews;
+
+ ViewFrame* m_currentViewFrame;
+ std::set<ViewFrame*> m_viewFrames;
+
+ static std::set<FileContext*> m_openFiles;
+
+ friend class ViewFrame;
+ void registerViewFrame(ViewFrame* frame);
+ void unregisterViewFrame(ViewFrame* frame);
+
+public:
+ FileContext(FileMetadataRef file, BinaryViewRef rawData,
+ const QString& filename = QString(), bool isValidSaveName = false);
+ virtual ~FileContext();
+
+ void close();
+ static void closeAllOpenFiles();
+
+ BinaryViewRef getRawData() const { return m_rawData; }
+ QString getFilename() const { return m_filename; }
+ ViewFrame* getCurrentViewFrame() const { return m_currentViewFrame; }
+
+ bool isValidSaveFilename() const { return m_isValidSaveFilename; }
+ void markAsSaved(const QString& filename);
+
+ bool isModified();
+
+ BinaryViewRef getDataView(const QString& type, bool createView = false);
+ std::vector<BinaryViewRef> getAllDataViews();
+
+ void setCurrentViewFrame(ViewFrame* view);
+
+ virtual std::string GetCurrentView() override;
+ virtual uint64_t GetCurrentOffset() override;
+ virtual bool Navigate(const std::string& view, uint64_t offset) override;
+
+ void createBinaryViews();
+ QString getBestType();
+ std::vector<QString> getAvailableTypes();
+ bool isTypeAvailable(const QString& type);
+ bool resolveType(const QString& type, ViewType*& viewType, BinaryViewTypeRef& data);
+ bool resolveTypeAndData(const QString& type, ViewType*& viewType, BinaryViewRef& data);
+
+ void updateAnalysis();
+
+ static FileContext* newFile();
+ static FileContext* openFilename(const QString& path);
+};
diff --git a/ui/filter.h b/ui/filter.h
new file mode 100644
index 00000000..5a43100f
--- /dev/null
+++ b/ui/filter.h
@@ -0,0 +1,54 @@
+#pragma once
+
+#include <QtWidgets/QLineEdit>
+#include "binaryninjaapi.h"
+#include "uicontext.h"
+
+class BINARYNINJAUIAPI FilterTarget
+{
+public:
+ virtual ~FilterTarget() {}
+
+ virtual void setFilter(const std::string& filter) = 0;
+ virtual void scrollToFirstItem() = 0;
+ virtual void scrollToCurrentItem() = 0;
+ virtual void selectFirstItem() = 0;
+ virtual void activateFirstItem() = 0;
+ virtual void closeFilter();
+};
+
+class BINARYNINJAUIAPI FilterEdit: public QLineEdit
+{
+ Q_OBJECT
+
+ FilterTarget* m_target;
+
+public:
+ FilterEdit(QWidget* parent, FilterTarget* target);
+
+protected:
+ virtual void keyPressEvent(QKeyEvent* event) override;
+};
+
+class BINARYNINJAUIAPI FilteredView: public QWidget
+{
+ Q_OBJECT
+
+ FilterTarget* m_target;
+ QWidget* m_widget;
+ FilterEdit* m_filter;
+
+public:
+ FilteredView(QWidget* parent, QWidget* filtered, FilterTarget* target);
+ void updateFonts();
+ void clearFilter();
+ void showFilter(const QString& initialText);
+
+ static bool match(const std::string& name, const std::string& filter);
+
+protected:
+ virtual void keyPressEvent(QKeyEvent* event) override;
+
+private Q_SLOTS:
+ void filterChanged(const QString& filter);
+};
diff --git a/ui/flowgraphwidget.h b/ui/flowgraphwidget.h
new file mode 100644
index 00000000..1ebaded2
--- /dev/null
+++ b/ui/flowgraphwidget.h
@@ -0,0 +1,285 @@
+#pragma once
+
+#include <QtWidgets/QWidget>
+#include <QtWidgets/QAbstractScrollArea>
+#include "binaryninjaapi.h"
+#include "render.h"
+#include "viewframe.h"
+#include "menus.h"
+#include "uicontext.h"
+#include "commentdialog.h"
+#include "instructionedit.h"
+
+class BINARYNINJAUIAPI GraphLayoutCompleteEvent: public QEvent
+{
+ FlowGraphRef m_graph;
+public:
+ GraphLayoutCompleteEvent(QEvent::Type type, const FlowGraphRef& graph);
+ FlowGraphRef GetGraph() { return m_graph; }
+};
+
+class BINARYNINJAUIAPI FlowGraphHistoryEntry: public HistoryEntry
+{
+ PlatformRef m_platform;
+ ArchitectureRef m_arch;
+ uint64_t m_func;
+ int m_scrollX, m_scrollY;
+ float m_scale;
+ uint64_t m_addr;
+ HighlightTokenState m_highlight;
+
+public:
+ PlatformRef getPlatform() const { return m_platform; }
+ ArchitectureRef getArchitecture() const { return m_arch; }
+ uint64_t getFunction() const { return m_func; }
+ int getScrollX() const { return m_scrollX; }
+ int getScrollY() const { return m_scrollY; }
+ float getScale() const { return m_scale; }
+ uint64_t getCurrentAddress() const { return m_addr; }
+ const HighlightTokenState& getHighlightTokenState() const { return m_highlight; }
+
+ void setPlatform(PlatformRef platform) { m_platform = platform; }
+ void setArchitecture(ArchitectureRef arch) { m_arch = arch; }
+ void setFunction(uint64_t f) { m_func = f; }
+ void setScrollX(int x) { m_scrollX = x; }
+ void setScrollY(int y) { m_scrollY = y; }
+ void setScale(float s) { m_scale = s; }
+ void setCurrentAddress(uint64_t a) { m_addr = a; }
+ void setHighlightTokenState(const HighlightTokenState& state) { m_highlight = state; }
+};
+
+class BINARYNINJAUIAPI FlowGraphWidget: public QAbstractScrollArea, public View, public PreviewScrollHandler,
+ public BinaryNinja::BinaryDataNotification
+{
+ Q_OBJECT
+
+ struct CursorPosition
+ {
+ size_t lineInNode;
+ uint64_t address;
+ size_t instrIndex;
+ size_t lineIndexForAddress;
+ };
+
+ BinaryViewRef m_data;
+ FlowGraphRef m_graph;
+ FlowGraphRef m_updateGraph;
+ FlowGraphLayoutRequestRef m_graphLayoutRequest;
+ FlowGraphLayoutRequestRef m_updateGraphLayoutRequest;
+ FunctionRef m_func;
+ BinaryNinja::AdvancedFunctionAnalysisDataRequestor m_advancedAnalysisData;
+ View* m_navigationTarget;
+
+ bool m_ready;
+ QTimer* m_loadingTimer;
+ QTimer* m_updateTimer;
+ QTimer* m_zoomTimer;
+ QTimer* m_zoomPauseTimer;
+
+ std::mutex m_updateMutex;
+ bool m_updated;
+
+ RenderContext m_render;
+ int m_width, m_height;
+ int m_renderXOfs, m_renderYOfs, m_renderWidth, m_renderHeight;
+ float m_scale;
+ QRect m_renderRect;
+ QRect m_miniRenderRect;
+
+ bool m_scrollMode;
+ int m_scrollBaseX, m_scrollBaseY;
+
+ FlowGraphNodeRef m_selectedNode;
+ CursorPosition m_cursorPos, m_selectionStartPos;
+ HighlightTokenState m_highlight;
+
+ ContextMenuManager m_contextMenuManager;
+ QPointer<CommentDialog> m_commentDialog;
+
+ BinaryNinja::Ref<FlowGraphHistoryEntry> m_pendingHistoryEntry, m_layoutHistoryEntry;
+ bool m_useAddrAfterLayout;
+ uint64_t m_addrAfterLayout;
+ bool m_pendingXrefNavigation, m_xrefNavigation;
+ uint64_t m_xrefTarget;
+
+ InstructionEdit* m_instrEdit;
+
+ bool m_isPreview;
+ QPointF m_previewPos;
+ QTimer* m_hoverTimer;
+
+ static int m_layoutCompleteEventType;
+ static int m_updateCompleteEventType;
+
+ void adjustSize(int width, int height);
+
+ void defineNameAtAddr(uint64_t addr);
+
+ static std::string getValueStr(int64_t value);
+ static std::string getValueStr(uint64_t value);
+
+ FlowGraphNodeRef findUpdatedNode(FlowGraphRef oldGraph, FlowGraphNodeRef oldNode, CursorPosition& pos);
+ bool updatePositionForNode(FlowGraphNodeRef oldNode, FlowGraphNodeRef newNode, CursorPosition& pos);
+ void recenterUpdatedGraph(FlowGraphRef oldGraph, int oldXOfs, int oldYOfs);
+
+protected:
+ virtual void paintEvent(QPaintEvent* event) override;
+ virtual void resizeEvent(QResizeEvent* event) override;
+
+ virtual void mousePressEvent(QMouseEvent* event) override;
+ virtual void mouseReleaseEvent(QMouseEvent* event) override;
+ virtual void mouseMoveEvent(QMouseEvent* event) override;
+ virtual void mouseDoubleClickEvent(QMouseEvent* event) override;
+ virtual void wheelEvent(QWheelEvent* event) override;
+
+ virtual void customEvent(QEvent* event) override;
+
+ virtual void scrollContentsBy(int dx, int dy) override;
+
+ bool getNodeForMouseEvent(QMouseEvent* event, FlowGraphNodeRef& node);
+ bool getLineForMouseEvent(QMouseEvent* event, CursorPosition& pos);
+ HighlightTokenState getTokenForMouseEvent(QMouseEvent* event);
+
+ void showContextMenu();
+ void bindActions();
+
+ void navigateToAddress(uint64_t addr);
+
+ void setGraphInternal(FlowGraphRef graph, FlowGraphHistoryEntry* entry, bool useAddr, uint64_t addr, bool notify);
+
+public:
+ FlowGraphWidget(QWidget* parent, BinaryViewRef view, FlowGraphRef graph = FlowGraphRef());
+ ~FlowGraphWidget();
+
+ virtual void OnAnalysisFunctionUpdated(BinaryNinja::BinaryView* data, BinaryNinja::Function* func) override;
+ virtual void OnAnalysisFunctionUpdateRequested(BinaryNinja::BinaryView* data, BinaryNinja::Function* func) override;
+
+ void setInitialGraph(FlowGraphRef graph);
+ void setInitialGraph(FlowGraphRef graph, uint64_t addr);
+
+ void setGraph(FlowGraphRef graph);
+ void setGraph(FlowGraphRef graph, uint64_t addr);
+ void setGraph(FlowGraphRef graph, FlowGraphHistoryEntry* entry);
+ void updateToGraph(FlowGraphRef graph);
+ virtual void updateFonts() override;
+
+ virtual BinaryViewRef getData() override { return m_data; }
+ virtual uint64_t getCurrentOffset() override;
+ virtual void getSelectionOffsets(uint64_t& begin, uint64_t& end) override;
+ virtual void getSelectionForInfo(uint64_t& begin, uint64_t& end) override;
+ virtual bool navigate(uint64_t pos) override;
+ virtual bool navigateToFunction(FunctionRef func, uint64_t pos) override;
+ bool navigateWithHistoryEntry(uint64_t addr, FlowGraphHistoryEntry* entry);
+ bool navigateWithHistoryEntry(FunctionRef func, uint64_t addr, FlowGraphHistoryEntry* entry);
+ void setNavigationTarget(View* target) { m_navigationTarget = target; }
+
+ virtual void zoom(bool direction);
+ virtual void zoomActual();
+ virtual bool event(QEvent* event) override;
+ void disableZoom();
+ virtual void sendWheelEvent(QWheelEvent* event) override;
+
+ virtual void cut() override;
+ virtual void copy(TransformRef xform) override;
+ virtual void paste(TransformRef xform) override;
+
+ virtual bool canAssemble() override;
+ virtual bool canCompile() override;
+ virtual bool canPaste() override;
+
+ virtual void closing() override;
+
+ virtual HistoryEntry* getHistoryEntry() override;
+ void populateDefaultHistoryEntry(FlowGraphHistoryEntry* entry);
+ virtual void navigateToHistoryEntry(HistoryEntry* entry) override;
+
+ virtual FunctionRef getCurrentFunction() override;
+ virtual BasicBlockRef getCurrentBasicBlock() override;
+ virtual ArchitectureRef getCurrentArchitecture() override;
+
+ virtual LowLevelILFunctionRef getCurrentLowLevelILFunction() override;
+ virtual MediumLevelILFunctionRef getCurrentMediumLevelILFunction() override;
+ virtual size_t getCurrentILInstructionIndex() override;
+
+ void scrollToCursor();
+ bool isUpdating();
+
+ QFont getFont() override { return m_render.getFont(); }
+ virtual HighlightTokenState getHighlightTokenState() override { return m_highlight; }
+ QRect getMiniRenderRect() const { return m_miniRenderRect; }
+ void paintMiniGraphAndViewport(QWidget* owner);
+ bool paintMiniGraph(QWidget* owner, QPainter& p);
+
+ void showAddress(uint64_t addr, bool select = false);
+ void showTopNode();
+ void showNode(FlowGraphNodeRef node);
+ void showLineInNode(FlowGraphNodeRef node, size_t lineIndex);
+
+ void viewInTypesView(std::string typeName);
+
+ void setInstructionHighlight(BNHighlightColor color);
+ void setBlockHighlight(BNHighlightColor color);
+
+ virtual bool goToReference(FunctionRef func, uint64_t source, uint64_t target) override;
+
+ void setHighlightToken(const HighlightTokenState& state, bool notify = true);
+
+ virtual void onFunctionSelected(FunctionRef func);
+ virtual void onHighlightChanged(const HighlightTokenState& highlight);
+
+ static std::string getPossibleValueSetStateName(BNRegisterValueType state);
+ static std::string getStringForRegisterValue(ArchitectureRef arch, BinaryNinja::RegisterValue value);
+ static std::string getStringForPossibleValueSet(ArchitectureRef arch, const BinaryNinja::PossibleValueSet& values);
+
+Q_SIGNALS:
+ void layoutComplete();
+ void updateMiniGraph();
+
+private Q_SLOTS:
+ void loadingTimerEvent();
+ void updateTimerEvent();
+ void hoverTimerEvent();
+ void zoomTimerEvent();
+ bool zoomDisabled();
+ void zoomPauseTimerEvent();
+
+ void goToAddress();
+ void followPointer();
+ void defineName();
+ void undefineName();
+ void defineFuncName();
+ void undefineFunc();
+ void createFunc();
+ void changeType();
+ void comment();
+ void functionComment();
+ void commentAccepted();
+ void functionCommentAccepted();
+
+ void convertToNop();
+ void alwaysBranch();
+ void invertBranch();
+ void skipAndReturnZero();
+ void skipAndReturnValue();
+
+ void displayAsDefault();
+ void displayAsBinary();
+ void displayAsSignedOctal();
+ void displayAsUnsignedOctal();
+ void displayAsSignedDecimal();
+ void displayAsUnsignedDecimal();
+ void displayAsSignedHexadecimal();
+ void displayAsUnsignedHexadecimal();
+ void displayAsCharacterConstant();
+ void displayAsPointer();
+
+ void makePtr();
+ void makeString();
+
+ void reanalyze();
+
+ void setStackAdjustment();
+
+ void editInstruction();
+ void instrEditDoneEvent();
+};
diff --git a/ui/fontsettings.h b/ui/fontsettings.h
new file mode 100644
index 00000000..ede68a24
--- /dev/null
+++ b/ui/fontsettings.h
@@ -0,0 +1,32 @@
+#pragma once
+
+#include <QtGui/QFont>
+#include <QtWidgets/QWidget>
+#include "uicontext.h"
+
+enum AntialiasingStyle
+{
+ SubpixelAntialiasing,
+ GrayscaleAntialiasing,
+ SubpixelAntialiasingUnlessHighDPI,
+ NoAntialiasing
+};
+
+QFont BINARYNINJAUIAPI getDefaultMonospaceFont();
+QFont BINARYNINJAUIAPI getMonospaceFont(QWidget* widget);
+void BINARYNINJAUIAPI setMonospaceFont(const QFont& font);
+
+int BINARYNINJAUIAPI getDefaultExtraFontSpacing();
+int BINARYNINJAUIAPI getExtraFontSpacing();
+void BINARYNINJAUIAPI setExtraFontSpacing(int spacing);
+
+int BINARYNINJAUIAPI getFontVerticalOffset();
+
+bool BINARYNINJAUIAPI allowBoldFonts();
+void BINARYNINJAUIAPI setAllowBoldFonts(bool allow);
+
+AntialiasingStyle BINARYNINJAUIAPI getAntialiasingStyle();
+void BINARYNINJAUIAPI setAntialiasingStyle(AntialiasingStyle style);
+void BINARYNINJAUIAPI adjustFontForAntialiasingSettings(QFont& font, QWidget* widget);
+
+int BINARYNINJAUIAPI getFontWidthAndAdjustSpacing(QFont& font);
diff --git a/ui/forminputdialog.h b/ui/forminputdialog.h
new file mode 100644
index 00000000..1a46d2ea
--- /dev/null
+++ b/ui/forminputdialog.h
@@ -0,0 +1,28 @@
+#pragma once
+
+#include <QtWidgets/QDialog>
+#include <QtWidgets/QLineEdit>
+#include <QtWidgets/QTextEdit>
+#include <QtWidgets/QComboBox>
+#include <QtWidgets/QLabel>
+#include <vector>
+#include "binaryninjaapi.h"
+#include "uicontext.h"
+
+class BINARYNINJAUIAPI FormInputDialog: public QDialog
+{
+ Q_OBJECT
+
+ std::vector<BinaryNinja::FormInputField>* m_fields;
+ std::vector<QWidget*> m_fieldControls;
+
+ void openFileName(QLineEdit* edit, const std::string& ext);
+ void saveFileName(QLineEdit* edit, const std::string& ext, const std::string& defaultName);
+ void directoryName(QLineEdit* edit, const std::string& defaultName);
+
+public:
+ FormInputDialog(QWidget* parent, std::vector<BinaryNinja::FormInputField>* fields, const std::string& title);
+
+protected Q_SLOTS:
+ void finish();
+};
diff --git a/ui/functionlist.h b/ui/functionlist.h
new file mode 100644
index 00000000..893a09ce
--- /dev/null
+++ b/ui/functionlist.h
@@ -0,0 +1,135 @@
+#pragma once
+
+#include <QtWidgets/QListView>
+#include <QtCore/QAbstractItemModel>
+#include <QtCore/QTimer>
+#include <QtWidgets/QLineEdit>
+#include <vector>
+#include <mutex>
+#include "binaryninjaapi.h"
+#include "viewframe.h"
+#include "filter.h"
+#include "uicontext.h"
+
+#define FUNCTION_LIST_UPDATE_INTERVAL 250
+
+class BINARYNINJAUIAPI FunctionListModel: public QAbstractItemModel, public BinaryNinja::BinaryDataNotification
+{
+ Q_OBJECT
+
+ enum FunctonListUpdateType
+ {
+ AddedToFunctionList,
+ RemovedFromFunctionList,
+ UpdatedInFunctionList
+ };
+
+ struct FunctionListUpdateEvent
+ {
+ FunctionRef func;
+ FunctonListUpdateType type;
+ };
+
+ struct NamedFunction
+ {
+ FunctionRef func;
+ std::string name;
+ bool named;
+ };
+
+ class FunctionListUpdate: public BinaryNinja::RefCountObject
+ {
+ std::mutex m_mutex;
+ bool m_valid;
+ FunctionListModel* m_model;
+
+ public:
+ FunctionListUpdate(FunctionListModel* model);
+ void start();
+ void abort();
+ };
+
+ QWidget* m_funcList;
+ ViewFrame* m_view;
+ BinaryViewRef m_data;
+ std::vector<FunctionRef> m_funcs;
+ std::vector<NamedFunction> m_allFuncs;
+ FunctionRef m_currentFunc;
+ std::string m_filter;
+
+ std::mutex m_updateMutex;
+ std::vector<FunctionListUpdateEvent> m_updates;
+ bool m_fullUpdate;
+
+ BinaryNinja::Ref<FunctionListUpdate> m_backgroundUpdate;
+ volatile bool m_backgroundUpdateComplete;
+ std::vector<FunctionRef> m_backgroundUpdateFuncs;
+
+
+ static bool functionComparison(const FunctionRef& a, const FunctionRef& b);
+ static bool allFunctionComparison(const NamedFunction& a, const NamedFunction& b);
+
+public:
+ FunctionListModel(QWidget* parent, ViewFrame* view, BinaryViewRef data);
+ virtual ~FunctionListModel();
+
+ virtual QModelIndex index(int row, int col, const QModelIndex& parent) const override;
+ virtual QModelIndex parent(const QModelIndex& i) const override;
+ virtual bool hasChildren(const QModelIndex& parent) const override;
+ virtual int rowCount(const QModelIndex& parent = QModelIndex()) const override;
+ virtual int columnCount(const QModelIndex& parent) const override;
+ virtual QVariant data(const QModelIndex& i, int role) const override;
+
+ virtual void OnAnalysisFunctionAdded(BinaryNinja::BinaryView* data, BinaryNinja::Function* func) override;
+ virtual void OnAnalysisFunctionRemoved(BinaryNinja::BinaryView* data, BinaryNinja::Function* func) override;
+ virtual void OnAnalysisFunctionUpdated(BinaryNinja::BinaryView* data, BinaryNinja::Function* func) override;
+
+ void updateFonts();
+ bool setCurrentFunction(FunctionRef func);
+ QModelIndex findFunction(FunctionRef func);
+ QModelIndex findCurrentFunction();
+ FunctionRef getFunctionForIndex(int i);
+
+ void updateFunctions();
+ void backgroundUpdate();
+ bool hasFunctions() const;
+
+ void setFilter(const std::string& filter);
+};
+
+class BINARYNINJAUIAPI FunctionList: public QListView, public FilterTarget
+{
+ Q_OBJECT
+
+ ViewFrame* m_view;
+ BinaryViewRef m_data;
+ FunctionListModel* m_list;
+ QTimer* m_updateTimer;
+ bool m_disableScrollToFunction;
+
+public:
+ FunctionList(QWidget* parent, ViewFrame* frame, BinaryViewRef data);
+
+ void updateFonts();
+ void setCurrentFunction(FunctionRef func);
+
+ virtual void scrollToFirstItem() override;
+ virtual void scrollToCurrentItem() override;
+ virtual void selectFirstItem() override;
+ virtual void activateFirstItem() override;
+ virtual void setFilter(const std::string& filter) override;
+
+ bool hasFunctions();
+
+ virtual void copy();
+ virtual void paste();
+ virtual bool canCopy();
+
+protected:
+ virtual void focusOutEvent(QFocusEvent* event) override;
+ virtual void keyPressEvent(QKeyEvent* event) override;
+
+private Q_SLOTS:
+ void goToFunction(const QModelIndex& i);
+ void updateTimerEvent();
+};
diff --git a/ui/functionsview.h b/ui/functionsview.h
new file mode 100644
index 00000000..02164079
--- /dev/null
+++ b/ui/functionsview.h
@@ -0,0 +1,41 @@
+#pragma once
+
+#include <QtCore/QTimer>
+#include "binaryninjaapi.h"
+#include "dockhandler.h"
+#include "filter.h"
+
+class ViewFrame;
+class FunctionList;
+
+class BINARYNINJAUIAPI FunctionsView: public QWidget, public DockContextHandler, public BinaryNinja::BinaryDataNotification
+{
+ Q_OBJECT
+
+ BinaryViewRef m_data;
+
+ FunctionList* m_funcList;
+ FilteredView* m_funcFilter;
+
+ bool m_updatesPending;
+ QTimer* m_updateTimer;
+
+public:
+ FunctionsView(ViewFrame* frame, BinaryViewRef data);
+ virtual ~FunctionsView();
+
+ FunctionList* getFunctionList() { return m_funcList; }
+ FilteredView* getFunctionFilter() { return m_funcFilter; }
+
+ virtual void OnBinaryDataWritten(BinaryNinja::BinaryView* data, uint64_t offset, size_t len) override;
+ virtual void OnBinaryDataInserted(BinaryNinja::BinaryView* data, uint64_t offset, size_t len) override;
+ virtual void OnBinaryDataRemoved(BinaryNinja::BinaryView* data, uint64_t offset, uint64_t len) override;
+
+protected:
+ virtual void contextMenuEvent(QContextMenuEvent* event) override;
+ virtual bool shouldBeVisible(ViewFrame* frame) override;
+ virtual void updateFonts() override;
+
+private Q_SLOTS:
+ void updateTimerEvent();
+};
diff --git a/ui/hexeditor.h b/ui/hexeditor.h
new file mode 100644
index 00000000..26f877b9
--- /dev/null
+++ b/ui/hexeditor.h
@@ -0,0 +1,217 @@
+#pragma once
+
+#include <QtWidgets/QAbstractScrollArea>
+#include <QtCore/QTimer>
+#include "binaryninjaapi.h"
+#include "viewframe.h"
+#include "render.h"
+#include "menus.h"
+#include "statusbarwidget.h"
+#include "uicontext.h"
+
+#define HEX_EDITOR_UPDATE_CHECK_INTERVAL 200
+
+class BINARYNINJAUIAPI HexEditor : public QAbstractScrollArea, public View, public PreviewScrollHandler,
+ public BinaryNinja::BinaryDataNotification
+{
+ Q_OBJECT
+public:
+ explicit HexEditor(BinaryViewRef data, ViewFrame* view, uint64_t startAddr = 0);
+ virtual ~HexEditor();
+
+ virtual bool canAssemble() override { return true; }
+ virtual bool canCompile() override { return true; }
+
+ virtual BinaryViewRef getData() override { return m_data; }
+ virtual uint64_t getCurrentOffset() override;
+ virtual void getSelectionOffsets(uint64_t& begin, uint64_t& end) override;
+ virtual bool navigate(uint64_t pos) override;
+
+ virtual void OnBinaryDataWritten(BinaryNinja::BinaryView* data, uint64_t offset, size_t len) override;
+ virtual void OnBinaryDataInserted(BinaryNinja::BinaryView* data, uint64_t offset, size_t len) override;
+ virtual void OnBinaryDataRemoved(BinaryNinja::BinaryView* data, uint64_t offset, uint64_t len) override;
+
+ virtual void writeData(const BinaryNinja::DataBuffer& data) override;
+ virtual void selectAll();
+ virtual void selectNone();
+
+ void setSelectionRange(uint64_t begin, uint64_t end);
+
+ virtual void updateFonts() override;
+
+ virtual StatusBarWidget* getStatusBarWidget() override;
+
+ virtual void followPointer();
+
+ void setHighlightMode(HexEditorHighlightMode mode);
+ void setColorMode(HexEditorColorMode mode);
+ void setContrast(HexEditorHighlightContrast mode);
+
+ virtual void sendWheelEvent(QWheelEvent* event) override;
+
+ QFont getFont() override { return m_render.getFont(); }
+
+ static void registerActions();
+
+private:
+ class HexEditorHighlightWidget: public QLabel
+ {
+ public:
+ HexEditorHighlightWidget(HexEditor* parent);
+
+ protected:
+ virtual void mousePressEvent(QMouseEvent* event);
+ virtual void enterEvent(QEvent* event);
+ virtual void leaveEvent(QEvent* event);
+
+ private:
+ HexEditor* m_editor;
+ Menu m_menu;
+ ContextMenuManager m_contextMenuManager;
+ };
+
+ class HexEditorStatusBarWidget: public StatusBarWidget
+ {
+ public:
+ HexEditorStatusBarWidget(HexEditor* parent);
+ virtual void updateStatus() override;
+
+ private:
+ HexEditor* m_editor;
+ HexEditorHighlightWidget* m_highlight;
+ };
+
+ struct HexEditorLine
+ {
+ bool separator;
+ uint64_t addr;
+ size_t len;
+ };
+
+ uint64_t getStart();
+ uint64_t getEnd();
+ uint64_t getLength();
+
+ void updateRanges();
+
+ void adjustSize(int width, int height);
+
+ uint64_t getContiguousOffsetForAddress(uint64_t addr);
+ uint64_t getAddressForContiguousOffset(uint64_t offset);
+
+ void setTopToAddress(uint64_t addr);
+ void refreshLines();
+ void refreshAtCurrentLocation();
+ bool cachePreviousLines();
+ bool cacheNextLines();
+ void updateCache();
+ void scrollLines(int count);
+
+ uint64_t getCursorPos();
+ void setCursorPos(uint64_t pos);
+ void repositionCaret();
+ void updateCaret();
+ void bindActions();
+
+ std::pair<uint64_t, uint64_t> getSelectionRange();
+ bool isSelectionActive();
+
+ void goToAddress(bool selection);
+ void searchRegEx();
+ void findNext();
+
+ void inputByte(uint8_t byte);
+ void inputHexDigit(uint8_t digit);
+
+ void adjustAddressAfterBackwardMovement();
+ void adjustAddressAfterForwardMovement();
+
+ void left(size_t count, bool selecting);
+ void right(size_t count, bool selecting);
+ void up(bool selecting);
+ void down(bool selecting);
+ void pageUp(bool selecting);
+ void pageDown(bool selecting);
+ void moveToStartOfLine(bool selecting);
+ void moveToEndOfLine(bool selecting);
+ void moveToStartOfView(bool selecting);
+ void moveToEndOfView(bool selecting);
+ void toggleHexOrAscii();
+ void toggleInsertMode();
+ void deleteBack();
+ void deleteForward();
+
+ BinaryViewRef m_data;
+ ViewFrame* m_view;
+
+ std::vector<HexEditorLine> m_lines;
+ size_t m_topLine;
+ uint64_t m_topAddr, m_bottomAddr;
+
+ std::vector<BNAddressRange> m_ranges;
+ uint64_t m_allocatedLength;
+ uint64_t m_scrollBarMultiplier;
+ int m_wheelDelta;
+ bool m_updatingScrollBar;
+ bool m_updatesRequired;
+
+ uint64_t m_minAddr;
+ uint64_t m_cursorAddr, m_prevCursorAddr;
+ int m_cursorOffset;
+ uint64_t m_selectionStartAddr;
+ int m_cols, m_visibleRows;
+ int m_lastMouseX, m_lastMouseY;
+ bool m_selectionVisible;
+ bool m_cursorAscii;
+ bool m_caretVisible, m_caretBlink;
+ bool m_insertMode;
+ bool m_leftButtonDown;
+ QString m_status;
+ QTimer* m_cursorTimer;
+ QTimer* m_updateTimer;
+ Qt::KeyboardModifiers m_ctrl, m_command;
+
+ RenderContext m_render;
+ HexEditorHighlightState m_highlightState;
+
+ ContextMenuManager m_contextMenuManager;
+
+protected:
+ virtual void resizeEvent(QResizeEvent* event) override;
+ virtual void paintEvent(QPaintEvent* event) override;
+ virtual void focusInEvent(QFocusEvent* event) override;
+ virtual void focusOutEvent(QFocusEvent* event) override;
+ virtual void keyPressEvent(QKeyEvent* event) override;
+ virtual void keyReleaseEvent(QKeyEvent* event) override;
+ virtual void mousePressEvent(QMouseEvent* event) override;
+ virtual void mouseMoveEvent(QMouseEvent* event) override;
+ virtual void mouseReleaseEvent(QMouseEvent* event) override;
+ virtual bool event(QEvent* event) override;
+ virtual void wheelEvent(QWheelEvent* event) override;
+
+Q_SIGNALS:
+
+public Q_SLOTS:
+ void disassembly();
+ void createFunc();
+ void createFuncWithPlatform(PlatformRef platform);
+
+private Q_SLOTS:
+ void scrollBarMoved(int value);
+ void scrollBarAction(int action);
+ void cursorTimerEvent();
+ void updateTimerEvent();
+};
+
+class HexEditorViewType: public ViewType
+{
+ static HexEditorViewType* m_instance;
+
+public:
+ HexEditorViewType();
+ virtual int getPriority(BinaryViewRef data, const QString& filename) override;
+ virtual QWidget* create(BinaryViewRef data, ViewFrame* viewFrame) override;
+ virtual QString getDisplayName(BinaryViewTypeRef type) override;
+ virtual QString getDisplayLongName(BinaryViewTypeRef type) override;
+ static void init();
+};
diff --git a/ui/instructionedit.h b/ui/instructionedit.h
new file mode 100644
index 00000000..9e388210
--- /dev/null
+++ b/ui/instructionedit.h
@@ -0,0 +1,29 @@
+#pragma once
+
+#include <QtWidgets/QLineEdit>
+#include "binaryninjaapi.h"
+#include "uicontext.h"
+
+class BINARYNINJAUIAPI InstructionEdit: public QLineEdit
+{
+ Q_OBJECT
+
+ BinaryViewRef m_data;
+ ArchitectureRef m_arch;
+ FunctionRef m_func;
+ uint64_t m_offset;
+ bool m_preventDismiss;
+
+public:
+ InstructionEdit(QWidget* parent, BinaryViewRef data, ArchitectureRef arch, FunctionRef func, uint64_t offset);
+
+ void acceptInstruction();
+ void rejectInstruction();
+
+protected:
+ virtual void keyPressEvent(QKeyEvent* event);
+ virtual void focusOutEvent(QFocusEvent* event);
+
+Q_SIGNALS:
+ void done();
+};
diff --git a/ui/linearview.h b/ui/linearview.h
new file mode 100644
index 00000000..4c67e8d8
--- /dev/null
+++ b/ui/linearview.h
@@ -0,0 +1,235 @@
+#pragma once
+
+#include <QtWidgets/QAbstractScrollArea>
+#include <QtCore/QTimer>
+#include "binaryninjaapi.h"
+#include "viewframe.h"
+#include "render.h"
+#include "commentdialog.h"
+#include "menus.h"
+#include "statusbarwidget.h"
+#include "uicontext.h"
+
+#define LINEAR_VIEW_UPDATE_CHECK_INTERVAL 200
+#define MAX_STRING_TYPE_LENGTH 1048576
+#define EDGE_GUTTER_WIDTH 4
+
+class BINARYNINJAUIAPI LinearViewHistoryEntry: public HistoryEntry
+{
+ BinaryNinja::LinearDisassemblyPosition m_topPosition, m_cursorPosition;
+ size_t m_topLineOffset;
+ HighlightTokenState m_highlight;
+
+public:
+ const BinaryNinja::LinearDisassemblyPosition& getTopPosition() const { return m_topPosition; }
+ const BinaryNinja::LinearDisassemblyPosition& getCursorPosition() const { return m_cursorPosition; }
+ size_t getTopLineOffset() const { return m_topLineOffset; }
+ const HighlightTokenState& getHighlightTokenState() const { return m_highlight; }
+
+ void setTopPosition(const BinaryNinja::LinearDisassemblyPosition& pos) { m_topPosition = pos; }
+ void setCursorPosition(const BinaryNinja::LinearDisassemblyPosition& pos) { m_cursorPosition = pos; }
+ void setTopLineOffset(size_t offset) { m_topLineOffset = offset; }
+ void setHighlightTokenState(const HighlightTokenState& state) { m_highlight = state; }
+};
+
+class BINARYNINJAUIAPI LinearView: public QAbstractScrollArea, public View, public BinaryNinja::BinaryDataNotification
+{
+ Q_OBJECT
+
+ class LinearViewOptionsWidget: public QLabel
+ {
+ public:
+ LinearViewOptionsWidget(LinearView* parent);
+
+ protected:
+ virtual void mousePressEvent(QMouseEvent* event);
+ virtual void enterEvent(QEvent* event);
+ virtual void leaveEvent(QEvent* event);
+
+ private:
+ LinearView* m_view;
+ Menu m_menu;
+ ContextMenuManager m_contextMenuManager;
+ };
+
+ class LinearViewStatusBarWidget: public StatusBarWidget
+ {
+ public:
+ LinearViewStatusBarWidget(LinearView* parent);
+ virtual void updateStatus() override;
+
+ private:
+ LinearView* m_view;
+ LinearViewOptionsWidget* m_options;
+ };
+
+ BinaryViewRef m_data;
+ ViewFrame* m_view;
+ std::vector<BNAddressRange> m_ranges;
+ uint64_t m_allocatedLength;
+
+ RenderContext m_render;
+ int m_cols, m_rows;
+ uint64_t m_scrollBarMultiplier;
+ int m_wheelDelta;
+ bool m_updatingScrollBar;
+
+ bool m_updatesRequired;
+ bool m_updateBounds, m_updateBlockRef;
+
+ BinaryNinja::LinearDisassemblyPosition m_cursorPosition;
+ bool m_cursorPositionHasOffset = false;
+ size_t m_cursorPositionOffset = 0;
+ HighlightTokenState m_highlight;
+ uint64_t m_navByRefTarget;
+ bool m_navByRef = false;
+
+ DisassemblySettingsRef m_settings;
+
+ BinaryNinja::LinearDisassemblyPosition m_topPosition, m_bottomPosition;
+ std::vector<BinaryNinja::LinearDisassemblyLine> m_lines;
+ size_t m_topLine;
+
+ QTimer* m_updateTimer;
+
+ ContextMenuManager m_contextMenuManager;
+ QPointer<CommentDialog> m_commentDialog;
+
+ void adjustSize(int width, int height);
+
+ uint64_t getContiguousOffsetForAddress(uint64_t addr);
+ uint64_t getAddressForContiguousOffset(uint64_t offset);
+
+ void setTopToAddress(uint64_t addr);
+ void refreshLines(size_t lineOffset = 0, bool refreshUIContext = true);
+ bool cachePreviousLines();
+ bool cacheNextLines(size_t& topLineAdjustment);
+ void updateCache();
+ void refreshAtCurrentLocation();
+ bool navigateToAddress(uint64_t addr, bool center, bool updateHighlight, bool navByRef = false);
+
+ void scrollLines(int count);
+
+ void bindActions();
+ void getHexDumpLineBytes(const BinaryNinja::LinearDisassemblyLine& line, size_t& skippedBytes, size_t& totalBytes,
+ size_t& totalCols);
+
+ void setSectionSemantics(const std::string& name, BNSectionSemantics semantics);
+
+private Q_SLOTS:
+ void viewInHexEditor();
+ void viewInGraph();
+ void viewInTypesView(std::string typeName = "");
+ void copyAddressSlot();
+ void goToAddress();
+ void defineNameAtAddr(uint64_t addr);
+ void defineName();
+ void undefineName();
+ void createFunc();
+ void defineFuncName();
+ void undefineFunc();
+ void reanalyze();
+ void comment();
+ void commentAccepted();
+
+ void convertToNop();
+ void alwaysBranch();
+ void invertBranch();
+ void skipAndReturnZero();
+ void skipAndReturnValue();
+
+ void makeInt8();
+ void makeInt16();
+ void makeInt32();
+ void makeInt64();
+ void toggleIntSize();
+ void makePtr();
+ void makeString();
+ void changeType();
+ size_t getStringLength(uint64_t startAddr);
+
+ void displayAsDefault();
+ void displayAsBinary();
+ void displayAsSignedOctal();
+ void displayAsUnsignedOctal();
+ void displayAsSignedDecimal();
+ void displayAsUnsignedDecimal();
+ void displayAsSignedHexadecimal();
+ void displayAsUnsignedHexadecimal();
+ void displayAsCharacterConstant();
+ void displayAsPointer();
+
+ void setInstructionHighlight(BNHighlightColor color);
+ void setBlockHighlight(BNHighlightColor color);
+
+ void scrollBarMoved(int value);
+ void scrollBarAction(int action);
+ void updateTimerEvent();
+
+public:
+ explicit LinearView(BinaryViewRef data, ViewFrame* view);
+ virtual ~LinearView();
+
+ virtual bool canAssemble() override { return true; }
+ virtual bool canCompile() override { return true; }
+
+ virtual BinaryViewRef getData() override { return m_data; }
+ virtual uint64_t getCurrentOffset() override;
+ virtual void getSelectionOffsets(uint64_t& begin, uint64_t& end) override;
+ virtual void getSelectionForInfo(uint64_t& begin, uint64_t& end) override;
+ virtual FunctionRef getCurrentFunction() override;
+ virtual BasicBlockRef getCurrentBasicBlock() override;
+ virtual ArchitectureRef getCurrentArchitecture() override;
+ virtual bool navigate(uint64_t pos) override;
+
+ virtual HistoryEntry* getHistoryEntry() override;
+ virtual void navigateToHistoryEntry(HistoryEntry* entry) override;
+
+ virtual void OnBinaryDataWritten(BinaryNinja::BinaryView* data, uint64_t offset, size_t len) override;
+ virtual void OnBinaryDataInserted(BinaryNinja::BinaryView* data, uint64_t offset, size_t len) override;
+ virtual void OnBinaryDataRemoved(BinaryNinja::BinaryView* data, uint64_t offset, uint64_t len) override;
+ virtual void OnAnalysisFunctionAdded(BinaryNinja::BinaryView* view, BinaryNinja::Function* func) override;
+ virtual void OnAnalysisFunctionRemoved(BinaryNinja::BinaryView* view, BinaryNinja::Function* func) override;
+ virtual void OnAnalysisFunctionUpdated(BinaryNinja::BinaryView* view, BinaryNinja::Function* func) override;
+ virtual void OnDataVariableAdded(BinaryNinja::BinaryView* view, const BinaryNinja::DataVariable& var) override;
+ virtual void OnDataVariableRemoved(BinaryNinja::BinaryView* view, const BinaryNinja::DataVariable& var) override;
+ virtual void OnDataVariableUpdated(BinaryNinja::BinaryView* view, const BinaryNinja::DataVariable& var) override;
+
+ virtual void updateFonts() override;
+
+ virtual StatusBarWidget* getStatusBarWidget() override;
+
+ virtual void followPointer();
+
+ virtual void cut() override;
+ virtual void copy(TransformRef xform = nullptr) override;
+ virtual void paste(TransformRef xform = nullptr) override;
+ virtual void copyAddress() override;
+
+ virtual HighlightTokenState getHighlightTokenState() override { return m_highlight; }
+
+ void toggleOption(BNDisassemblyOption option);
+
+ virtual bool goToReference(FunctionRef func, uint64_t source, uint64_t target) override;
+ QFont getFont() override { return m_render.getFont(); }
+
+ static void registerActions();
+
+protected:
+ virtual void resizeEvent(QResizeEvent* event) override;
+ virtual void paintEvent(QPaintEvent* event) override;
+ virtual void wheelEvent(QWheelEvent* event) override;
+ virtual void mousePressEvent(QMouseEvent* event) override;
+ virtual void mouseDoubleClickEvent(QMouseEvent* event) override;
+};
+
+class LinearViewType: public ViewType
+{
+ static LinearViewType* m_instance;
+
+public:
+ LinearViewType();
+ virtual int getPriority(BinaryViewRef data, const QString& filename) override;
+ virtual QWidget* create(BinaryViewRef data, ViewFrame* viewFrame) override;
+ static void init();
+};
diff --git a/ui/logview.h b/ui/logview.h
new file mode 100644
index 00000000..b8566ee7
--- /dev/null
+++ b/ui/logview.h
@@ -0,0 +1,165 @@
+#pragma once
+
+#include <QtWidgets/QListView>
+#include <QtCore/QItemSelection>
+#include <QtCore/QPointer>
+#include <QtCore/QTimer>
+#include <QtWidgets/QStyledItemDelegate>
+#include <QtWidgets/QLabel>
+#include <QtWidgets/QToolButton>
+#include <mutex>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "binaryninjaapi.h"
+#include "action.h"
+#include "dockhandler.h"
+
+#define DEFAULT_MAX_LOG_SIZE 10000
+#define LOG_UPDATE_INTERVAL 100
+
+class LogStatus;
+class View;
+class ViewFrame;
+
+struct BINARYNINJAUIAPI LogListItem
+{
+ BNLogLevel level;
+ std::string text;
+ bool selected;
+
+ LogListItem(BNLogLevel level, std::string text, bool selected = false) : level(level), text(text), selected(selected) { };
+};
+
+
+class BINARYNINJAUIAPI LogListModel: public QAbstractItemModel, public BinaryNinja::LogListener
+{
+ Q_OBJECT
+
+ QWidget* m_owner;
+ std::deque<LogListItem> m_items;
+ std::deque<LogListItem> m_visibleItems;
+ size_t m_maxSize;
+
+ std::vector<LogListItem> m_pendingItems;
+ std::mutex m_mutex;
+ std::mutex m_pendingMutex;
+
+public:
+ LogListModel(QWidget* parent);
+ ~LogListModel();
+
+ void addPendingItems();
+ void clear();
+ std::vector<LogListItem> getSelectedItems();
+ bool hasSelectedItems();
+
+ virtual void LogMessage(BNLogLevel level, const std::string& msg) override;
+ virtual BNLogLevel GetLogLevel() override;
+
+ virtual QModelIndex index(int row, int col, const QModelIndex& parent) const override;
+ virtual QModelIndex parent(const QModelIndex& i) const override;
+ virtual bool hasChildren(const QModelIndex& parent) const override;
+ virtual int rowCount(const QModelIndex& parent) const override;
+ virtual int columnCount(const QModelIndex& parent) const override;
+ virtual QVariant data(const QModelIndex& i, int role) const override;
+ virtual bool setData(const QModelIndex& i, const QVariant& value, int role) override;
+};
+
+
+class BINARYNINJAUIAPI LogItemDelegate: public QStyledItemDelegate
+{
+ Q_OBJECT
+
+ QWidget* m_owner;
+ ViewFrame* m_viewFrame = nullptr;
+ View* m_view = nullptr;
+ BinaryViewRef m_data;
+
+ QFont m_font;
+ int m_height;
+
+ bool IsNavigable(const QString& str, const std::pair<int, int>& offsetLen, uint64_t& value, bool highlight) const;
+
+public:
+ LogItemDelegate(QWidget* parent);
+
+ void updateFonts();
+ virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& idx) const override;
+ virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& idx) const override;
+
+protected:
+ bool editorEvent(QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index) override;
+
+public Q_SLOTS:
+ void viewChanged(QWidget* frame);
+};
+
+
+class BINARYNINJAUIAPI LogView: public QListView, public DockContextHandler
+{
+ Q_OBJECT
+
+ QPointer<LogStatus> m_logStatus;
+ std::vector<std::pair<QAction*, bool>> m_actionEnableList;
+ LogListModel* m_listModel;
+ LogItemDelegate* m_itemDelegate;
+ QTimer* m_updateTimer;
+
+ bool m_doClear;
+ bool m_scrolledToEnd;
+ bool m_hasSelection = false;
+
+public:
+ LogView(QWidget* parent, LogStatus* logStatus);
+
+ virtual void copy();
+ virtual bool canCopy();
+
+ static void SetLogLevel(BNLogLevel level);
+
+protected:
+ void contextMenuEvent(QContextMenuEvent* event) override;
+ void focusInput() override;
+ void notifyViewChanged(ViewFrame* frame) override;
+ void updateFonts() override;
+
+Q_SIGNALS:
+ void notifyUiStatus();
+ void viewChanged(QWidget* frame);
+
+public Q_SLOTS:
+ void clear();
+
+private Q_SLOTS:
+ void scrollRangeChanged(int minimum, int maximum);
+ void scrollValueChanged(int value);
+ void updateSelection(const QItemSelection& selected, const QItemSelection& deselected);
+ void updateTimerEvent();
+ void updateUiStatus();
+};
+
+
+class BINARYNINJAUIAPI LogStatus: public QWidget
+{
+ Q_OBJECT
+
+ QToolButton* m_errorIndicator;
+ QToolButton* m_warnIndicator;
+
+ int m_errorCount = 0;
+ int m_warnCount = 0;
+
+public:
+ LogStatus(QWidget* parent);
+
+ void incrementErrorCount(int count);
+ void incrementWarningCount(int count);
+ void clearIndicators();
+
+ void updateTheme();
+
+private Q_SLOTS:
+ void clearStatus();
+};
diff --git a/ui/menus.h b/ui/menus.h
new file mode 100644
index 00000000..0a455243
--- /dev/null
+++ b/ui/menus.h
@@ -0,0 +1,25 @@
+#pragma once
+
+#include <QtCore/QPointer>
+#include <QtWidgets/QMenu>
+#include <QtWidgets/QWidget>
+#include <functional>
+#include <map>
+#include <string>
+#include "binaryninjaapi.h"
+#include "viewframe.h"
+
+class BINARYNINJAUIAPI ContextMenuManager
+{
+ QWidget* m_parent;
+ QPointer<QMenu> m_menu;
+ MenuInstance* m_instance;
+
+public:
+ ContextMenuManager(QWidget* parent);
+ ~ContextMenuManager();
+ QMenu* create();
+ MenuInstance* show(View* view);
+ MenuInstance* show(Menu* source, UIActionHandler* handler);
+ bool isActive() { return !m_menu.isNull(); }
+};
diff --git a/ui/minigraph.h b/ui/minigraph.h
new file mode 100644
index 00000000..25baa58c
--- /dev/null
+++ b/ui/minigraph.h
@@ -0,0 +1,39 @@
+#pragma once
+
+#include <QtGui/QMouseEvent>
+#include <QtGui/QPaintEvent>
+#include <QtWidgets/QWidget>
+
+#include "binaryninjaapi.h"
+#include "dockhandler.h"
+#include "uitypes.h"
+
+class ContextMenuManager;
+class DisassemblyView;
+class Menu;
+class ViewFrame;
+
+class BINARYNINJAUIAPI MiniGraph: public QWidget, public DockContextHandler
+{
+ Q_OBJECT
+
+ DisassemblyView* m_disassemblyView = nullptr;
+
+public:
+ MiniGraph(QWidget* parent);
+ ~MiniGraph();
+
+ virtual bool isAvailable(ViewFrame* frame) override;
+ virtual void notifyViewChanged(ViewFrame* frame) override;
+ virtual bool shouldBeVisible(ViewFrame* frame) override;
+
+protected:
+ virtual void contextMenuEvent(QContextMenuEvent* event) override;
+ virtual void mouseMoveEvent(QMouseEvent* event) override;
+ virtual void mousePressEvent(QMouseEvent* event) override;
+ virtual void paintEvent(QPaintEvent* event) override;
+ virtual void scrollTo(int x, int y);
+
+public Q_SLOTS:
+ void notifyUpdate();
+};
diff --git a/ui/platformdialog.h b/ui/platformdialog.h
new file mode 100644
index 00000000..01f2c75f
--- /dev/null
+++ b/ui/platformdialog.h
@@ -0,0 +1,30 @@
+#pragma once
+
+#include <QtWidgets/QDialog>
+#include <QtWidgets/QComboBox>
+#include "binaryninjaapi.h"
+#include "uicontext.h"
+
+class BINARYNINJAUIAPI PlatformDialog: public QDialog
+{
+ Q_OBJECT
+
+ QComboBox* m_arch;
+ QComboBox* m_os;
+ QComboBox* m_platform;
+
+ std::map<QString, PlatformRef> m_platformsByName;
+ PlatformRef m_selectedPlatform;
+
+public:
+ PlatformDialog(QWidget* parent, ArchitectureRef defaultArch = nullptr);
+
+ PlatformRef getPlatform();
+ void saveDefaults();
+
+private Q_SLOTS:
+ void architectureChanged(const QString& name);
+ void osChanged(const QString& name);
+
+ void selectPlatform();
+};
diff --git a/ui/preview.h b/ui/preview.h
new file mode 100644
index 00000000..670e8fb9
--- /dev/null
+++ b/ui/preview.h
@@ -0,0 +1,35 @@
+#pragma once
+
+#include <QtWidgets/QLabel>
+#include <QtWidgets/QWidget>
+#include "uitypes.h"
+
+class BINARYNINJAUIAPI PreviewScrollHandler
+{
+public:
+ virtual ~PreviewScrollHandler() {}
+ virtual void sendWheelEvent(QWheelEvent* event) = 0;
+};
+
+class BINARYNINJAUIAPI PreviewWidget: public QFrame
+{
+ Q_OBJECT
+
+ QWidget* m_contents;
+ PreviewScrollHandler* m_scrollHandler;
+
+protected:
+ virtual bool eventFilter(QObject* obj, QEvent* event) override;
+ virtual void wheelEvent(QWheelEvent* event) override;
+
+public:
+ PreviewWidget();
+ virtual ~PreviewWidget();
+
+ void setContents(QWidget* widget);
+ void setScrollHandler(PreviewScrollHandler* handler);
+ void sendWheelEvent(QWheelEvent* event);
+ void closePreview();
+
+ static bool isPreviewWidget(QWidget* widget);
+};
diff --git a/ui/progressindicator.h b/ui/progressindicator.h
new file mode 100644
index 00000000..91932d3b
--- /dev/null
+++ b/ui/progressindicator.h
@@ -0,0 +1,111 @@
+// Copyright (c) 2011 Morgan Leborgne
+//
+// 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.
+
+#ifndef QPROGRESSINDICATOR_H
+#define QPROGRESSINDICATOR_H
+
+#include <QtWidgets/QWidget>
+#include <QtGui/QColor>
+#include "uicontext.h"
+
+/*!
+ \class QProgressIndicator
+ \brief The QProgressIndicator class lets an application display a progress indicator to show that a lengthy task is under way.
+
+ Progress indicators are indeterminate and do nothing more than spin to show that the application is busy.
+ \sa QProgressBar
+*/
+class BINARYNINJAUIAPI QProgressIndicator : public QWidget
+{
+ Q_OBJECT
+ Q_PROPERTY(int delay READ animationDelay WRITE setAnimationDelay)
+ Q_PROPERTY(bool displayedWhenStopped READ isDisplayedWhenStopped WRITE setDisplayedWhenStopped)
+ Q_PROPERTY(QColor color READ color WRITE setColor)
+ int m_width = 18;
+
+public:
+ QProgressIndicator(QWidget* parent = 0);
+
+ /*! Returns the delay between animation steps.
+ \return The number of milliseconds between animation steps. By default, the animation delay is set to 40 milliseconds.
+ \sa setAnimationDelay
+ */
+ int animationDelay() const { return m_delay; }
+
+ /*! Returns a Boolean value indicating whether the component is currently animated.
+ \return Animation state.
+ \sa startAnimation stopAnimation
+ */
+ bool isAnimated () const;
+
+ /*! Returns a Boolean value indicating whether the receiver shows itself even when it is not animating.
+ \return Return true if the progress indicator shows itself even when it is not animating. By default, it returns false.
+ \sa setDisplayedWhenStopped
+ */
+ bool isDisplayedWhenStopped() const;
+
+ /*! Returns the color of the component.
+ \sa setColor
+ */
+ const QColor & color() const { return m_color; }
+
+ virtual QSize sizeHint() const { return QSize(m_width, m_width); };
+ void setWidth(int width) { m_width = width; };
+ int heightForWidth(int w) const;
+public Q_SLOTS:
+ /*! Starts the spin animation.
+ \sa stopAnimation isAnimated
+ */
+ void startAnimation();
+
+ /*! Stops the spin animation.
+ \sa startAnimation isAnimated
+ */
+ void stopAnimation();
+
+ /*! Sets the delay between animation steps.
+ Setting the \a delay to a value larger than 40 slows the animation, while setting the \a delay to a smaller value speeds it up.
+ \param delay The delay, in milliseconds.
+ \sa animationDelay
+ */
+ void setAnimationDelay(int delay);
+
+ /*! Sets whether the component hides itself when it is not animating.
+ \param state The animation state. Set false to hide the progress indicator when it is not animating; otherwise true.
+ \sa isDisplayedWhenStopped
+ */
+ void setDisplayedWhenStopped(bool state);
+
+ /*! Sets the color of the components to the given color.
+ \sa color
+ */
+ void setColor(const QColor & color);
+protected:
+ virtual void timerEvent(QTimerEvent * event);
+ virtual void paintEvent(QPaintEvent * event);
+private:
+ int m_angle;
+ int m_timerId;
+ int m_delay;
+ bool m_displayedWhenStopped;
+ QColor m_color;
+};
+
+#endif // QPROGRESSINDICATOR_H
diff --git a/ui/qfileaccessor.h b/ui/qfileaccessor.h
new file mode 100644
index 00000000..f04e0bdd
--- /dev/null
+++ b/ui/qfileaccessor.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#include <QtCore/QFile>
+#include "binaryninjaapi.h"
+#include "action.h"
+
+class BINARYNINJAUIAPI QFileAccessor : public BinaryNinja::FileAccessor
+{
+ QFile* m_file;
+
+public:
+ QFileAccessor(const QString& name, bool write = false);
+ virtual ~QFileAccessor();
+
+ virtual bool IsValid() const;
+ virtual uint64_t GetLength() const;
+
+ virtual size_t Read(void* dest, uint64_t offset, size_t len);
+ virtual size_t Write(uint64_t offset, const void* src, size_t len);
+
+ void Close();
+};
diff --git a/ui/render.h b/ui/render.h
new file mode 100644
index 00000000..2ae59d63
--- /dev/null
+++ b/ui/render.h
@@ -0,0 +1,94 @@
+#pragma once
+
+#include <QtGui/QPainter>
+#include "binaryninjaapi.h"
+#include "uicontext.h"
+#include "action.h"
+
+enum HexEditorHighlightMode
+{
+ NoHighlight,
+ ColumnHighlight,
+ ByteValueHighlight
+};
+
+enum HexEditorColorMode
+{
+ NoColorization,
+ AsciiColorization,
+ ModificationColorization
+};
+
+enum HexEditorHighlightContrast
+{
+ NormalContrastHighlight,
+ MediumContrastHighlight,
+ HighContrastHighlight
+};
+
+struct BINARYNINJAUIAPI HexEditorHighlightState
+{
+ HexEditorHighlightMode mode;
+ HexEditorColorMode color;
+ HexEditorHighlightContrast contrast;
+
+ void restoreSettings();
+ void saveSettings();
+};
+
+class BINARYNINJAUIAPI FontParameters
+{
+ QWidget* m_owner;
+ QFont m_font;
+ int m_baseline, m_charWidth, m_charHeight, m_charOffset;
+ float m_fontScale;
+ bool m_customFont;
+
+public:
+ FontParameters(QWidget* parent, float fontScale = 1.0f);
+ void update();
+
+ QFont& getFont() { return m_font; }
+ void setFont(const QFont& font);
+ int getBaseline() const { return m_baseline; }
+ int getWidth() const { return m_charWidth; }
+ int getHeight() const { return m_charHeight; }
+ int getOffset() const { return m_charOffset; }
+};
+
+class BINARYNINJAUIAPI RenderContext
+{
+ QWidget* m_owner;
+ FontParameters m_fontParams;
+
+public:
+ RenderContext(QWidget* parent, float fontScale = 1.0f);
+ void update();
+
+ FontParameters& getFontParamters() { return m_fontParams; }
+ int getFontWidth() const { return m_fontParams.getWidth(); }
+ int getFontHeight() const { return m_fontParams.getHeight(); }
+
+ void init(QPainter& p);
+
+ QColor getColorForHexDumpByte(const HexEditorHighlightState& state, BNModificationStatus modification, uint8_t byte);
+ QColor getHighlightColor(BNHighlightColor color);
+
+ HighlightTokenState getTokenForDisassemblyLinePosition(size_t col, const std::vector<BinaryNinja::InstructionTextToken>& tokens);
+
+ void drawText(QPainter& p, int x, int y, QColor color, const QString& text);
+
+ void drawSeparatorLine(QPainter& p, QColor top, QColor bottom, QColor line, const QRect& rect);
+ void drawInstructionHighlight(QPainter& p, const QRect& rect);
+
+ void drawLinearDisassemblyLineBackground(QPainter& p, BNLinearDisassemblyLineType type, const QRect& rect,
+ int gutterWidth);
+ void drawDisassemblyLine(QPainter& p, int left, int top, const std::vector<BinaryNinja::InstructionTextToken>& tokens,
+ HighlightTokenState& highlight, bool highlightOnly=false);
+
+ void drawHexEditorLine(QPainter& p, int left, int top, const HexEditorHighlightState& highlight,
+ BinaryViewRef view, uint64_t lineStartAddr, size_t cols, size_t firstCol, size_t count,
+ bool cursorVisible, bool cursorAscii, size_t cursorPos, bool byteCursor);
+ QFont getFont() { return m_fontParams.getFont(); }
+ void setFont(const QFont& font);
+};
diff --git a/ui/reportcollectionwidget.h b/ui/reportcollectionwidget.h
new file mode 100644
index 00000000..95dc9262
--- /dev/null
+++ b/ui/reportcollectionwidget.h
@@ -0,0 +1,32 @@
+#pragma once
+
+#include <QtWidgets/QWidget>
+#include <QtWidgets/QSplitter>
+#include <QtWidgets/QListWidget>
+#include <QtWidgets/QVBoxLayout>
+#include "binaryninjaapi.h"
+#include "viewframe.h"
+#include "uicontext.h"
+
+class BINARYNINJAUIAPI ReportCollectionWidget: public QWidget, public ViewContainer
+{
+ Q_OBJECT
+
+ QSplitter* m_splitter;
+ QListWidget* m_list;
+ QWidget* m_report;
+ QWidget* m_reportContainer;
+ QVBoxLayout* m_reportLayout;
+
+ ReportCollectionRef m_collection;
+ int m_currentReportIndex;
+ std::string m_title;
+
+public:
+ ReportCollectionWidget(QWidget* parent, ReportCollectionRef reports, const std::string& title);
+
+ virtual View* getView() override;
+
+private Q_SLOTS:
+ void selectReport(int i);
+};
diff --git a/ui/reportwidget.h b/ui/reportwidget.h
new file mode 100644
index 00000000..22d51604
--- /dev/null
+++ b/ui/reportwidget.h
@@ -0,0 +1,33 @@
+#pragma once
+
+#include <QtWidgets/QWidget>
+#include <QtWidgets/QTextBrowser>
+#include <QtWidgets/QScrollArea>
+#include "binaryninjaapi.h"
+#include "action.h"
+
+class BINARYNINJAUIAPI ReportWidget: public QScrollArea, public UIActionHandler
+{
+ Q_OBJECT
+
+ QTextBrowser* m_contents;
+ BinaryViewRef m_view;
+ std::string m_original;
+ std::string m_title;
+ BNReportType m_type;
+ std::string m_plaintext;
+
+private Q_SLOTS:
+ void onLinkClicked(QUrl url);
+
+public:
+ ReportWidget(QWidget* parent, BinaryViewRef view, const std::string& contents,
+ BNReportType type, const std::string& title, const std::string& plaintext = "");
+ std::string getContents() const { return m_original; }
+ std::string getTitle() const { return m_title; }
+ BNReportType getType() const { return m_type; }
+ std::string getPlainText() const { return m_plaintext; }
+
+ void save();
+ void saveAs();
+};
diff --git a/ui/scriptingconsole.h b/ui/scriptingconsole.h
new file mode 100644
index 00000000..430e4b21
--- /dev/null
+++ b/ui/scriptingconsole.h
@@ -0,0 +1,115 @@
+#pragma once
+
+#include <QtCore/QTimer>
+#include <QtWidgets/QLabel>
+#include <QtWidgets/QLineEdit>
+#include <QtWidgets/QPushButton>
+#include <QtWidgets/QTextEdit>
+#include <QtWidgets/QWidget>
+#include <mutex>
+#include <string>
+#include <utility>
+#include <vector>
+#include "binaryninjaapi.h"
+#include "action.h"
+#include "dockhandler.h"
+#include "uitypes.h"
+
+#define SCRIPT_OUTPUT_UPDATE_INTERVAL 100
+#define SCRIPT_HISTORY_LENGTH 100
+
+class ScriptingConsole;
+
+class BINARYNINJAUIAPI ScriptingConsoleEdit: public QTextEdit
+{
+ Q_OBJECT
+
+ ScriptingConsole* m_console;
+ int m_charHeight;
+ bool m_continuation;
+
+public:
+ ScriptingConsoleEdit(ScriptingConsole* parent);
+ void setCharHeight(int height);
+ void setContinutation(bool cont);
+
+protected:
+ virtual void keyPressEvent(QKeyEvent* event) override;
+};
+
+class BINARYNINJAUIAPI ScriptingConsoleOutput: public QTextEdit
+{
+ Q_OBJECT
+
+ ScriptingConsole* m_console;
+ QAction* m_outputActionClear;
+
+public:
+ ScriptingConsoleOutput(ScriptingConsole* parent);
+
+protected:
+ virtual void contextMenuEvent(QContextMenuEvent *event) override;
+};
+
+class ScriptingConsoleWidget;
+
+class BINARYNINJAUIAPI ScriptingConsole: public QWidget, public DockContextHandler, BinaryNinja::ScriptingOutputListener
+{
+ Q_OBJECT
+
+ struct ScriptOutput
+ {
+ std::string text;
+ bool isError;
+ };
+
+ QString m_providerName;
+ QString m_instanceName;
+ ScriptingInstanceRef m_instance;
+ ScriptingConsoleOutput* m_output;
+ ScriptingConsoleEdit* m_input;
+ QLabel* m_prompt;
+ QPushButton* m_button;
+ QTimer* m_runTimer;
+
+ std::mutex m_mutex;
+ std::vector<ScriptOutput> m_pendingOutput;
+ QTimer* m_updateTimer;
+
+ BNScriptingProviderInputReadyState m_currentState;
+
+ QStringList m_history;
+ QString m_inputOutsideHistory;
+ int m_currentHistoryEntry;
+
+ static int m_stateUpdatedEventType;
+
+private Q_SLOTS:
+ void updateTimerEvent();
+ void cancel();
+ void showCancelButton();
+
+protected:
+ void customEvent(QEvent* event) override;
+ void focusInput() override;
+ void updateFonts() override;
+
+public:
+ ScriptingConsole(QWidget* parent, const QString& providerName, const QString& instanceName, ScriptingInstanceRef instance);
+ virtual ~ScriptingConsole();
+
+ QString getProviderName() const { return m_providerName; }
+ QString getInstanceName() const { return m_instanceName; }
+ ScriptingInstanceRef getInstance() { return m_instance; }
+
+ void hideConsole();
+
+ void addInput(const std::string& text);
+
+ virtual void NotifyOutput(const std::string& text) override;
+ virtual void NotifyError(const std::string& text) override;
+ virtual void NotifyInputReadyStateChanged(BNScriptingProviderInputReadyState state) override;
+
+ void moveUpInHistory();
+ void moveDownInHistory();
+};
diff --git a/ui/statusbarwidget.h b/ui/statusbarwidget.h
new file mode 100644
index 00000000..b41391a0
--- /dev/null
+++ b/ui/statusbarwidget.h
@@ -0,0 +1,23 @@
+#pragma once
+
+#include <QtWidgets/QFrame>
+#include <QtWidgets/QLabel>
+#include "uicontext.h"
+
+class BINARYNINJAUIAPI StatusBarWidget: public QWidget
+{
+ Q_OBJECT
+
+public:
+ StatusBarWidget(QWidget* parent);
+ virtual void updateStatus();
+};
+
+class BINARYNINJAUIAPI DisabledOptionsStatusBarWidget: public StatusBarWidget
+{
+public:
+ DisabledOptionsStatusBarWidget(QFrame* parent);
+
+private:
+ QLabel* m_label;
+};
diff --git a/ui/stringsview.h b/ui/stringsview.h
new file mode 100644
index 00000000..dd3d54ff
--- /dev/null
+++ b/ui/stringsview.h
@@ -0,0 +1,149 @@
+#pragma once
+
+#include <QtWidgets/QListView>
+#include <QtWidgets/QStyledItemDelegate>
+#include <mutex>
+#include "viewframe.h"
+#include "filter.h"
+#include "uicontext.h"
+
+#define STRINGS_LIST_UPDATE_INTERVAL 250
+
+class BINARYNINJAUIAPI StringsListModel: public QAbstractItemModel, public BinaryNinja::BinaryDataNotification
+{
+ Q_OBJECT
+
+ struct StringUpdateEvent
+ {
+ BNStringReference ref;
+ bool added;
+ };
+
+ QWidget* m_stringsList;
+ BinaryViewRef m_data;
+ std::vector<BNStringReference> m_allStrings;
+ std::vector<BNStringReference> m_strings;
+ std::string m_filter;
+
+ std::mutex m_updateMutex;
+ std::vector<StringUpdateEvent> m_updates;
+
+ static bool stringComparison(const BNStringReference& a, const BNStringReference& b);
+ bool matchString(const BNStringReference& stringRef);
+
+ std::vector<StringUpdateEvent> getQueuedStringUpdates();
+
+public:
+ StringsListModel(QWidget* parent, BinaryViewRef data);
+ virtual ~StringsListModel();
+
+ virtual QModelIndex index(int row, int col, const QModelIndex& parent) const override;
+ virtual QModelIndex parent(const QModelIndex& i) const override;
+ virtual bool hasChildren(const QModelIndex& parent) const override;
+ virtual int rowCount(const QModelIndex& parent) const override;
+ virtual int columnCount(const QModelIndex& parent) const override;
+ virtual QVariant data(const QModelIndex& i, int role) const override;
+
+ BNStringReference getStringAt(const QModelIndex& i);
+ QModelIndex findString(const BNStringReference& ref);
+
+ virtual void OnStringFound(BinaryNinja::BinaryView* data, BNStringType type, uint64_t offset, size_t len) override;
+ virtual void OnStringRemoved(BinaryNinja::BinaryView* data, BNStringType type, uint64_t offset, size_t len) override;
+ void updateStrings();
+
+ void setFilter(const std::string& filter);
+};
+
+class BINARYNINJAUIAPI StringItemDelegate: public QStyledItemDelegate
+{
+ Q_OBJECT
+
+ QWidget* m_owner;
+ QFont m_font;
+ int m_baseline, m_charWidth, m_charHeight, m_charOffset;
+
+ void initFont();
+
+public:
+ StringItemDelegate(QWidget* parent);
+
+ void updateFonts();
+
+ virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& idx) const override;
+ virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& idx) const override;
+ QFont getFont() const { return m_font; }
+};
+
+class StringsContainer;
+
+class BINARYNINJAUIAPI StringsView: public QListView, public View, public FilterTarget
+{
+ Q_OBJECT
+
+ BinaryViewRef m_data;
+ ViewFrame* m_view;
+ StringsContainer* m_container;
+
+ StringsListModel* m_list;
+ StringItemDelegate* m_itemDelegate;
+ QTimer* m_updateTimer;
+
+ uint64_t m_selectionBegin, m_selectionEnd;
+
+public:
+ StringsView(BinaryViewRef data, ViewFrame* view, StringsContainer* container);
+
+ virtual BinaryViewRef getData() override { return m_data; }
+ virtual uint64_t getCurrentOffset() override;
+ virtual void getSelectionOffsets(uint64_t& begin, uint64_t& end) override;
+ virtual bool navigate(uint64_t offset) override;
+
+ virtual void updateFonts() override;
+
+ virtual StatusBarWidget* getStatusBarWidget() override;
+
+ virtual void selectionChanged(const QItemSelection& selected, const QItemSelection& deselected) override;
+
+ virtual void setFilter(const std::string& filter) override;
+ virtual void scrollToFirstItem() override;
+ virtual void scrollToCurrentItem() override;
+ virtual void selectFirstItem() override;
+ virtual void activateFirstItem() override;
+ virtual QFont getFont() override { return m_itemDelegate->getFont(); }
+protected:
+ virtual void keyPressEvent(QKeyEvent* event) override;
+
+private Q_SLOTS:
+ void goToString(const QModelIndex& idx);
+ void updateTimerEvent();
+};
+
+class BINARYNINJAUIAPI StringsContainer: public QWidget, public ViewContainer
+{
+ Q_OBJECT
+
+ ViewFrame* m_view;
+ StringsView* m_strings;
+ FilteredView* m_filter;
+
+public:
+ StringsContainer(BinaryViewRef data, ViewFrame* view);
+ virtual View* getView() override { return m_strings; }
+
+ StringsView* getStringsView() { return m_strings; }
+ FilteredView* getFilter() { return m_filter; }
+
+protected:
+ virtual void focusInEvent(QFocusEvent* event) override;
+};
+
+class StringsViewType: public ViewType
+{
+ static StringsViewType* m_instance;
+
+public:
+ StringsViewType();
+ virtual int getPriority(BinaryViewRef data, const QString& filename);
+ virtual QWidget* create(BinaryViewRef data, ViewFrame* viewFrame);
+ static void init();
+};
diff --git a/ui/textdialog.h b/ui/textdialog.h
new file mode 100644
index 00000000..b9771cc0
--- /dev/null
+++ b/ui/textdialog.h
@@ -0,0 +1,28 @@
+#pragma once
+
+#include <QtWidgets/QDialog>
+#include "binaryninjaapi.h"
+#include "uitypes.h"
+
+class BINARYNINJAUIAPI TextDialog: public QDialog
+{
+ Q_OBJECT
+ QWidget* m_parent;
+ QString m_title;
+ QString m_msg;
+ QStringList m_options;
+ Qt::WindowFlags m_flags;
+ QString m_qSettingsListName;
+ int m_historySize;
+ QString m_historyEntry;
+ QString m_initialText;
+
+public:
+ TextDialog(QWidget* parent, const QString& title, const QString& msg, const QString& qSettingsListName,
+ const std::string& initialText = "");
+ TextDialog(QWidget* parent, const QString& title, const QString& msg, const QString& qSettingsListName,
+ const QString& initialText);
+ QString getItem(bool& ok);
+ void setInitialText(const std::string& initialText) { m_initialText = QString::fromStdString(initialText); }
+ void commitHistory();
+}; \ No newline at end of file
diff --git a/ui/theme.h b/ui/theme.h
new file mode 100644
index 00000000..8cebf40d
--- /dev/null
+++ b/ui/theme.h
@@ -0,0 +1,119 @@
+#pragma once
+
+#include <QtGui/QPalette>
+#include <QtWidgets/QProxyStyle>
+#include <vector>
+#include "binaryninjaapi.h"
+#include "uicontext.h"
+
+class BINARYNINJAUIAPI CustomFusionStyle: public QProxyStyle
+{
+public:
+ CustomFusionStyle(QStyle* parent);
+ virtual int pixelMetric(PixelMetric metric, const QStyleOption* option, const QWidget* widget) const override;
+ virtual QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption* option,
+ const QWidget* widget) const override;
+ virtual QPixmap standardPixmap(StandardPixmap standardPixmap, const QStyleOption* option,
+ const QWidget* widget) const override;
+};
+
+enum ThemeColor
+{
+ // Hex dump colors
+ AddressColor,
+ ModifiedColor,
+ InsertedColor,
+ NotPresentColor,
+ SelectionColor,
+ OutlineColor,
+ BackgroundHighlightDarkColor,
+ BackgroundHighlightLightColor,
+ BoldBackgroundHighlightDarkColor,
+ BoldBackgroundHighlightLightColor,
+ AlphanumericHighlightColor,
+ PrintableHighlightColor,
+
+ // Graph colors
+ GraphBackgroundDarkColor,
+ GraphBackgroundLightColor,
+ GraphNodeDarkColor,
+ GraphNodeLightColor,
+ GraphNodeOutlineColor,
+ TrueBranchColor,
+ FalseBranchColor,
+ UnconditionalBranchColor,
+ AltTrueBranchColor,
+ AltFalseBranchColor,
+ AltUnconditionalBranchColor,
+
+ // Disassembly colors
+ RegisterColor,
+ NumberColor,
+ CodeSymbolColor,
+ DataSymbolColor,
+ StackVariableColor,
+ ImportColor,
+ InstructionHighlightColor,
+ TokenHighlightColor,
+ AnnotationColor,
+ OpcodeColor,
+ LinearDisassemblyFunctionHeaderColor,
+ LinearDisassemblyBlockColor,
+ LinearDisassemblyNoteColor,
+ LinearDisassemblySeparatorColor,
+ StringColor,
+ TypeNameColor,
+ FieldNameColor,
+ KeywordColor,
+ UncertainColor,
+ NameSpaceColor,
+ NameSpaceSeparatorColor,
+
+ // Script console colors
+ ScriptConsoleOutputColor,
+ ScriptConsoleErrorColor,
+ ScriptConsoleEchoColor,
+
+ // Highlighting colors
+ BlueStandardHighlightColor,
+ GreenStandardHighlightColor,
+ CyanStandardHighlightColor,
+ RedStandardHighlightColor,
+ MagentaStandardHighlightColor,
+ YellowStandardHighlightColor,
+ OrangeStandardHighlightColor,
+ WhiteStandardHighlightColor,
+ BlackStandardHighlightColor,
+
+ // MiniGraph
+ MiniGraphOverlayColor,
+
+ // FeatureMap
+ FeatureMapBaseColor,
+ FeatureMapNavLineColor,
+ FeatureMapNavHighlightColor,
+ FeatureMapDataVariableColor,
+ FeatureMapAsciiStringColor,
+ FeatureMapUnicodeStringColor,
+ FeatureMapFunctionColor,
+ FeatureMapImportColor,
+ FeatureMapExternColor
+};
+
+void BINARYNINJAUIAPI initThemes();
+void BINARYNINJAUIAPI resetUserThemes();
+void BINARYNINJAUIAPI refreshUserThemes();
+std::vector<QString> BINARYNINJAUIAPI getAvailableThemes();
+QString BINARYNINJAUIAPI getActiveTheme();
+void BINARYNINJAUIAPI setActiveTheme(const QString& name, bool saveToSettings = true);
+
+bool BINARYNINJAUIAPI isColorBlindMode();
+void BINARYNINJAUIAPI setColorBlindMode(bool active);
+
+QColor BINARYNINJAUIAPI getThemeColor(ThemeColor color);
+QColor BINARYNINJAUIAPI getTokenColor(QWidget* widget, BNInstructionTextTokenType token);
+
+QColor BINARYNINJAUIAPI avgColor(QColor a, QColor b);
+QColor BINARYNINJAUIAPI mixColor(QColor a, QColor b, uint8_t mix);
+
+QColor BINARYNINJAUIAPI getThemeHighlightColor(BNHighlightStandardColor color);
diff --git a/ui/transformparam.h b/ui/transformparam.h
new file mode 100644
index 00000000..042a38c3
--- /dev/null
+++ b/ui/transformparam.h
@@ -0,0 +1,18 @@
+#pragma once
+
+#include <QtWidgets/QDialog>
+#include "binaryninjaapi.h"
+#include "uicontext.h"
+
+class BINARYNINJAUIAPI TransformParameterDialog: public QDialog
+{
+ Q_OBJECT
+
+ std::vector<BinaryNinja::TransformParameter> m_params;
+ std::map<std::string, BinaryDataRef> m_paramData;
+
+public:
+ TransformParameterDialog(QWidget* parent, TransformRef xform,
+ const std::vector<BinaryNinja::TransformParameter>& params);
+ std::map<std::string, BinaryNinja::DataBuffer> getParameterData();
+};
diff --git a/ui/typeview.h b/ui/typeview.h
new file mode 100644
index 00000000..558954ee
--- /dev/null
+++ b/ui/typeview.h
@@ -0,0 +1,253 @@
+#pragma once
+
+#include <QtWidgets/QAbstractScrollArea>
+#include <QtWidgets/QAction>
+#include <QtCore/QTimer>
+#include <string>
+#include <utility>
+#include <vector>
+#include "binaryninjaapi.h"
+#include "viewframe.h"
+#include "render.h"
+#include "menus.h"
+
+#define TYPE_VIEW_UPDATE_CHECK_INTERVAL 200
+
+class BINARYNINJAUIAPI TypeViewHistoryEntry: public HistoryEntry
+{
+ BinaryNinja::QualifiedName m_cursorType;
+ size_t m_cursorLine;
+ size_t m_cursorOffset;
+ bool m_selectionValid;
+ std::string m_selectionStartType;
+ size_t m_selectionStartLine;
+ size_t m_selectionStartOffset;
+ HighlightTokenState m_highlight;
+
+public:
+ const BinaryNinja::QualifiedName& getCursorType() const { return m_cursorType; }
+ size_t getCursorLine() const { return m_cursorLine; }
+ size_t getCursorOffset() const { return m_cursorOffset; }
+
+ bool isSelectionValid() const { return m_selectionValid; }
+ const std::string& getSelectionStartType() const { return m_selectionStartType; }
+ size_t getSelectionStartLine() const { return m_selectionStartLine; }
+ size_t getSelectionStartOffset() const { return m_selectionStartOffset; }
+
+ const HighlightTokenState& getHighlightTokenState() const { return m_highlight; }
+
+ void setCursorType(const BinaryNinja::QualifiedName& type) { m_cursorType = type; }
+ void setCursorLine(size_t line) { m_cursorLine = line; }
+ void setCursorOffset(size_t offset) { m_cursorOffset = offset; }
+
+ void setSelectionValid(bool valid) { m_selectionValid = valid; }
+ void setSelectionStartType(const std::string& type) { m_selectionStartType = type; }
+ void setSelectionStartLine(size_t line) { m_selectionStartLine = line; }
+ void setSelectionStartOffset(size_t offset) { m_selectionStartOffset = offset; }
+
+ void setHighlightTokenState(const HighlightTokenState& state) { m_highlight = state; }
+};
+
+class BINARYNINJAUIAPI TypeView: public QAbstractScrollArea, public View, public BinaryNinja::BinaryDataNotification
+{
+ Q_OBJECT
+
+ enum TypeDefinitionLineType
+ {
+ TypedefLineType,
+ StructDefinitionLineType,
+ StructFieldLineType,
+ StructDefinitionEndLineType,
+ EnumDefinitionLineType,
+ EnumMemberLineType,
+ EnumDefinitionEndLineType,
+ PaddingLineType
+ };
+
+ struct TypeDefinitionLine
+ {
+ TypeDefinitionLineType lineType;
+ std::vector<BinaryNinja::InstructionTextToken> tokens;
+ TypeRef type, rootType;
+ uint64_t offset;
+ size_t fieldIndex;
+ };
+
+ struct TypeLineIndex
+ {
+ BinaryNinja::QualifiedName name;
+ int line, end;
+ };
+
+ BinaryViewRef m_data;
+ ViewFrame* m_view;
+
+ RenderContext m_render;
+ QWidget* m_lineNumberArea;
+ int m_lineNumberAreaWidth = 0;
+ int m_lineCount = 0;
+ int m_cols, m_rows, m_paddingCols;
+ uint64_t m_maxOffset;
+ size_t m_offsetWidth;
+ HighlightTokenState m_highlight;
+ BinaryNinja::QualifiedName m_cursorType;
+ size_t m_cursorTypeIndex;
+ size_t m_cursorLine;
+ size_t m_cursorOffset;
+ std::string m_navigationMode = "TypeNavigation";
+
+ bool m_selectionValid;
+ size_t m_selectionStartTypeIndex;
+ size_t m_selectionStartLine;
+ size_t m_selectionStartOffset;
+ bool m_leftButtonDown;
+
+ std::map<BinaryNinja::QualifiedName, std::vector<TypeDefinitionLine>> m_typeLines;
+ std::vector<TypeLineIndex> m_types;
+
+ bool m_updatesRequired;
+ QTimer* m_updateTimer;
+
+ Qt::KeyboardModifiers m_ctrl, m_command;
+
+ ContextMenuManager m_contextMenuManager;
+ QAction* m_actionCopy;
+ QAction* m_actionSelectAll;
+
+ void adjustSize(int width, int height);
+
+ std::vector<TypeDefinitionLine> getLinesForType(const std::string& name, const std::string& varName, size_t index,
+ TypeRef type, TypeRef parent);
+ void refreshAllTypes();
+ void ensureCursorVisible();
+ void focusOnCursor();
+
+ void changeToSpecificType(TypeRef type);
+ bool canCreateMembersInSelectedRegion();
+ void createMembersInSelectedRegion(TypeRef type);
+ void deleteMembersInSelectedRegion();
+
+ void moveUp(bool selecting);
+ void moveDown(bool selecting);
+ void moveLeft(size_t count, bool selecting);
+ void moveRight(size_t count, bool selecting);
+ void pageUp(bool selecting);
+ void pageDown(bool selecting);
+ void setCursorAbsoluteLine(size_t line);
+ void moveToStartOfLine(bool selecting);
+ void moveToEndOfLine(bool selecting);
+ void moveToStartOfView(bool selecting);
+ void moveToEndOfView(bool selecting);
+ void goToAddress(bool selecting);
+
+ void moveCursorToMouse(QMouseEvent* event, bool selecting);
+ void createNewTypes(const QString& definition = "");
+ void bindActions();
+
+ void checkForValidSelection();
+
+public:
+ explicit TypeView(BinaryViewRef data, ViewFrame* view);
+ virtual ~TypeView();
+
+ virtual bool findNextData(uint64_t start, uint64_t end, const BinaryNinja::DataBuffer& data, uint64_t& addr, BNFindFlag flags,
+ const std::function<bool (size_t current, size_t total)>& cb) override;
+ virtual bool findNextText(uint64_t start, uint64_t end, const std::string& text, uint64_t& addr,
+ DisassemblySettingsRef settings, BNFindFlag flags,
+ const std::function<bool (size_t current, size_t total)>& cb) override;
+ virtual BinaryViewRef getData() override { return m_data; }
+ virtual uint64_t getCurrentOffset() override;
+ virtual void getSelectionOffsets(uint64_t& begin, uint64_t& end) override;
+ virtual bool navigate(uint64_t) override;
+
+ virtual std::string getNavigationMode() override;
+ virtual void setNavigationMode(std::string mode) override;
+ virtual std::vector<std::string> getNavigationModes() override;
+
+ bool navigateToType(const std::string& name);
+
+ virtual void OnTypeDefined(BinaryNinja::BinaryView* view, const BinaryNinja::QualifiedName& name,
+ BinaryNinja::Type* type) override;
+ virtual void OnTypeUndefined(BinaryNinja::BinaryView* view, const BinaryNinja::QualifiedName& name,
+ BinaryNinja::Type* type) override;
+
+ virtual void updateFonts() override;
+
+ virtual StatusBarWidget* getStatusBarWidget() override;
+
+ virtual HistoryEntry* getHistoryEntry() override;
+ virtual void navigateToHistoryEntry(HistoryEntry* entry) override;
+
+ void lineNumberAreaPaintEvent(QPaintEvent *event);
+ int lineNumberAreaWidth();
+
+ virtual bool canCut() override { return false; }
+ virtual bool canCopy() override;
+ virtual bool canCopyWithTransform() override { return false; }
+ virtual bool canPaste() override { return false; }
+ virtual bool canPasteWithTransform() override { return false; }
+ virtual bool canTransform() override { return false; }
+ virtual bool canCopyAddress() override { return false; }
+
+ virtual void copy(TransformRef xform = nullptr) override;
+ virtual QFont getFont() override { return m_render.getFont(); }
+
+ virtual HighlightTokenState getHighlightTokenState() override { return m_highlight; }
+
+ static void registerActions();
+
+protected:
+ virtual void resizeEvent(QResizeEvent* event) override;
+ virtual void paintEvent(QPaintEvent* event) override;
+ virtual void mousePressEvent(QMouseEvent* event) override;
+ virtual void mouseMoveEvent(QMouseEvent* event) override;
+ virtual void mouseReleaseEvent(QMouseEvent* event) override;
+ virtual void mouseDoubleClickEvent(QMouseEvent* event) override;
+ virtual void scrollContentsBy(int dx, int dy) override;
+
+private Q_SLOTS:
+ void copySelection();
+ void selectAll();
+ void updateTimerEvent();
+ void defineName();
+ void undefine();
+ void changeType();
+ void makeInt8();
+ void makeInt16();
+ void makeInt32();
+ void makeInt64();
+ void makePtr();
+ void makeString();
+ void makeArray();
+ void newTypes();
+ void createStructure();
+ void createUnion();
+ void setStructureSize();
+ void updateLineNumberAreaWidth(size_t lineCount);
+};
+
+
+class BINARYNINJAUIAPI LineNumberArea : public QWidget
+{
+public:
+ LineNumberArea(TypeView *editor) : QWidget(editor), m_typeEditor(editor) { }
+
+ QSize sizeHint() const override { return QSize(m_typeEditor->lineNumberAreaWidth(), 0); }
+
+protected:
+ void paintEvent(QPaintEvent *event) override { m_typeEditor->lineNumberAreaPaintEvent(event); }
+
+private:
+ TypeView* m_typeEditor;
+};
+
+class TypeViewType: public ViewType
+{
+ static TypeViewType* m_instance;
+
+public:
+ TypeViewType();
+ virtual int getPriority(BinaryViewRef data, const QString& filename) override;
+ virtual QWidget* create(BinaryViewRef data, ViewFrame* viewFrame) override;
+ static void init();
+};
diff --git a/ui/uicontext.h b/ui/uicontext.h
new file mode 100644
index 00000000..e65a603f
--- /dev/null
+++ b/ui/uicontext.h
@@ -0,0 +1,76 @@
+#pragma once
+
+#include <QtWidgets/QWidget>
+#include <QtCore/QMetaType>
+#include <QtWidgets/QMainWindow>
+#include <QtGui/QWheelEvent>
+#include "binaryninjaapi.h"
+#include "action.h"
+#include "preview.h"
+
+#define PREVIEW_HOVER_TIME 500
+
+typedef bool (*UIPluginInitFunction)(void);
+typedef void (*UIPluginDependencyFunction)(void);
+
+class ViewFrame;
+class UIActionHandler;
+class FileContext;
+
+class BINARYNINJAUIAPI UIContextHandler
+{
+public:
+ virtual ~UIContextHandler();
+ virtual void updateStatus(bool updateInfo) = 0;
+ virtual void notifyThemeChanged() = 0;
+};
+
+class BINARYNINJAUIAPI UIContext
+{
+ static UIContextHandler* m_handler;
+ static std::set<UIContext*> m_contexts;
+ UIActionHandler m_globalActions;
+
+ static QPointer<PreviewWidget> m_currentPreview;
+
+protected:
+ void setupUIContext(QWidget* obj);
+
+public:
+ UIContext();
+ virtual ~UIContext();
+
+ virtual QMainWindow* mainWindow() = 0;
+ virtual void viewChanged(ViewFrame* frame, const QString& type);
+ virtual bool navigateForBinaryView(BinaryViewRef view, uint64_t addr);
+ virtual void createTabForWidget(const QString& name, QWidget* widget) = 0;
+ virtual bool openFilename(const QString& path, bool openOptions = false);
+ virtual ViewFrame* openFileContext(FileContext* file, const QString& forcedView = "", bool addTab = true);
+
+ UIActionHandler* globalActions() { return &m_globalActions; }
+ virtual UIActionHandler* contentActionHandler() = 0;
+
+ static void setHandler(UIContextHandler* handler);
+
+ static QSize getScaledWindowSize(int x, int y);
+ static void updateStatus(bool updateInfo = true);
+ static void notifyThemeChanged();
+ static void showPreview(QWidget* parent, PreviewWidget* preview, QPoint localPos);
+ static void closePreview();
+ static bool sendPreviewWheelEvent(QWheelEvent* event);
+ static void closeOtherActiveModalWidget(QWidget* current);
+
+ static UIContext* contextForWidget(QWidget* widget);
+ static UIContext* activeContext();
+ static std::set<UIContext*> allContexts();
+};
+
+Q_DECLARE_METATYPE(UIContext*)
+
+void BINARYNINJAUIAPI InitUIViews();
+void BINARYNINJAUIAPI InitUIActions();
+
+void BINARYNINJAUIAPI InitUIPlugins();
+void BINARYNINJAUIAPI SetCurrentUIPluginLoadOrder(BNPluginLoadOrder order);
+void BINARYNINJAUIAPI AddRequiredUIPluginDependency(const std::string& name);
+void BINARYNINJAUIAPI AddOptionalUIPluginDependency(const std::string& name);
diff --git a/ui/uitypes.h b/ui/uitypes.h
new file mode 100644
index 00000000..1ebdc373
--- /dev/null
+++ b/ui/uitypes.h
@@ -0,0 +1,56 @@
+#pragma once
+
+#include "binaryninjaapi.h"
+
+#ifdef __GNUC__
+# ifdef BINARYNINJAUI_LIBRARY
+# define BINARYNINJAUIAPI __attribute__((visibility("default")))
+# else
+# define BINARYNINJAUIAPI
+# endif
+#else
+#ifdef _MSC_VER
+# ifdef BINARYNINJAUI_LIBRARY
+# define BINARYNINJAUIAPI __declspec(dllexport)
+# else
+# define BINARYNINJAUIAPI __declspec(dllimport)
+# endif
+#else
+#define BINARYNINJAUIAPI
+#endif
+#endif
+
+#ifdef BINARYNINJAUI_PYTHON_BINDINGS
+#include "bindings.h"
+#endif
+
+// The Python bindings generator does not recognize automatic conversion of API types into their
+// Python equivalents if using templates (Ref<*>), so we typedef all API references so that
+// the Python bindings can be easily generated for them.
+typedef BinaryNinja::Ref<BinaryNinja::Architecture> ArchitectureRef;
+typedef BinaryNinja::Ref<BinaryNinja::BackgroundTask> BackgroundTaskRef;
+typedef BinaryNinja::Ref<BinaryNinja::BasicBlock> BasicBlockRef;
+typedef BinaryNinja::Ref<BinaryNinja::BinaryData> BinaryDataRef;
+typedef BinaryNinja::Ref<BinaryNinja::BinaryView> BinaryViewRef;
+typedef BinaryNinja::Ref<BinaryNinja::BinaryViewType> BinaryViewTypeRef;
+typedef BinaryNinja::Ref<BinaryNinja::DisassemblySettings> DisassemblySettingsRef;
+typedef BinaryNinja::Ref<BinaryNinja::DownloadProvider> DownloadProviderRef;
+typedef BinaryNinja::Ref<BinaryNinja::FileMetadata> FileMetadataRef;
+typedef BinaryNinja::Ref<BinaryNinja::FlowGraph> FlowGraphRef;
+typedef BinaryNinja::Ref<BinaryNinja::FlowGraphLayoutRequest> FlowGraphLayoutRequestRef;
+typedef BinaryNinja::Ref<BinaryNinja::FlowGraphNode> FlowGraphNodeRef;
+typedef BinaryNinja::Ref<BinaryNinja::Function> FunctionRef;
+typedef BinaryNinja::Ref<BinaryNinja::LowLevelILFunction> LowLevelILFunctionRef;
+typedef BinaryNinja::Ref<BinaryNinja::MainThreadAction> MainThreadActionRef;
+typedef BinaryNinja::Ref<BinaryNinja::MediumLevelILFunction> MediumLevelILFunctionRef;
+typedef BinaryNinja::Ref<BinaryNinja::Platform> PlatformRef;
+typedef BinaryNinja::Ref<BinaryNinja::ReportCollection> ReportCollectionRef;
+typedef BinaryNinja::Ref<BinaryNinja::ScriptingInstance> ScriptingInstanceRef;
+typedef BinaryNinja::Ref<BinaryNinja::ScriptingProvider> ScriptingProviderRef;
+typedef BinaryNinja::Ref<BinaryNinja::Section> SectionRef;
+typedef BinaryNinja::Ref<BinaryNinja::Segment> SegmentRef;
+typedef BinaryNinja::Ref<BinaryNinja::Structure> StructureRef;
+typedef BinaryNinja::Ref<BinaryNinja::Symbol> SymbolRef;
+typedef BinaryNinja::Ref<BinaryNinja::TemporaryFile> TemporaryFileRef;
+typedef BinaryNinja::Ref<BinaryNinja::Transform> TransformRef;
+typedef BinaryNinja::Ref<BinaryNinja::Type> TypeRef;
diff --git a/ui/viewframe.h b/ui/viewframe.h
new file mode 100644
index 00000000..402c95c9
--- /dev/null
+++ b/ui/viewframe.h
@@ -0,0 +1,262 @@
+#pragma once
+
+#include <QtWidgets/QAction>
+#include <QtWidgets/QGestureEvent>
+#include <QtWidgets/QLabel>
+#include <QtCore/QPointer>
+#include <QtWidgets/QVBoxLayout>
+#include <QtWidgets/QWidget>
+#include <map>
+#include <stack>
+#include <utility>
+#include <vector>
+#include "filecontext.h"
+#include "viewtype.h"
+#include "action.h"
+
+class BINARYNINJAUIAPI HistoryEntry: public BinaryNinja::RefCountObject
+{
+ QString m_viewType;
+
+public:
+ virtual ~HistoryEntry() {}
+
+ QString getViewType() const { return m_viewType; }
+ void setViewType(const QString& type) { m_viewType = type; }
+};
+
+class AssembleDialog;
+class CompileDialog;
+class FeatureMap;
+class StatusBarWidget;
+class ViewNavigationMode;
+
+class BINARYNINJAUIAPI View
+{
+protected:
+ Menu m_contextMenu;
+ UIActionHandler m_actionHandler;
+
+ bool writeDataToClipboard(const BinaryNinja::DataBuffer& data, bool binary, TransformRef xform);
+ BinaryNinja::DataBuffer readDataFromClipboard(TransformRef xform);
+
+ // FIXME: Support for typeview, where the default navigation mode is not compatible with the navigation interface
+ // The view concept and navigation interface needs to be revisited at some point
+ // New interface/design should be pushed to NavigationHandler and through API
+ // The empty string is global navigation (inside view) by default, allows offset to be interpreted by mode
+ friend class ViewNavigationMode;
+ virtual std::string getNavigationMode() { return ""; }
+ virtual void setNavigationMode(std::string mode) { (void)mode; }
+ virtual std::vector<std::string> getNavigationModes() { return {}; }
+
+public:
+ View();
+ virtual ~View() {}
+
+ void setupView(QWidget* widget);
+
+ virtual bool canAssemble() { return false; }
+ virtual bool canCompile() { return false; }
+
+ virtual bool findNextData(uint64_t start, uint64_t end, const BinaryNinja::DataBuffer& data, uint64_t& addr, BNFindFlag flags,
+ const std::function<bool (size_t current, size_t total)>& cb);
+ virtual bool findNextText(uint64_t start, uint64_t end, const std::string& text, uint64_t& addr,
+ DisassemblySettingsRef settings, BNFindFlag flags,
+ const std::function<bool (size_t current, size_t total)>& cb);
+ virtual bool findNextConstant(uint64_t start, uint64_t end, uint64_t constant, uint64_t& addr, DisassemblySettingsRef settings,
+ const std::function<bool (size_t current, size_t total)>& cb);
+
+ virtual BinaryViewRef getData() = 0;
+ virtual uint64_t getCurrentOffset() = 0;
+ virtual void getSelectionOffsets(uint64_t& begin, uint64_t& end);
+ virtual void getSelectionForInfo(uint64_t& begin, uint64_t& end);
+ virtual bool navigate(uint64_t offset) = 0;
+ virtual bool navigateToFunction(FunctionRef func, uint64_t offset);
+ virtual bool goToReference(FunctionRef func, uint64_t source, uint64_t target);
+
+ virtual bool closeRequest() { return true; }
+ virtual void closing() {}
+ virtual void updateFonts() {}
+
+ virtual void undo();
+ virtual void redo();
+ virtual bool canUndo();
+ virtual bool canRedo();
+
+ virtual void cut();
+ virtual void copy(TransformRef xform = nullptr);
+ virtual void copyAddress();
+ virtual void paste(TransformRef xform = nullptr);
+ virtual bool canCut();
+ virtual bool canCopy();
+ virtual bool canCopyWithTransform();
+ virtual bool canCopyAddress();
+ virtual bool canPaste();
+ virtual bool canPasteWithTransform();
+
+ virtual void transform(TransformRef xform, bool encode);
+ virtual bool canTransform();
+
+ virtual void writeData(const BinaryNinja::DataBuffer& data);
+
+ virtual bool canDisplayAs(const UIActionContext& context);
+ virtual void displayAs(const UIActionContext& context, BNIntegerDisplayType type);
+
+ virtual HistoryEntry* getHistoryEntry();
+ virtual void navigateToHistoryEntry(HistoryEntry* entry);
+
+ virtual StatusBarWidget* getStatusBarWidget() { return nullptr; }
+
+ static View* getViewFromWidget(QWidget* widget);
+
+ virtual FunctionRef getCurrentFunction() { return nullptr; }
+ virtual BasicBlockRef getCurrentBasicBlock() { return nullptr; }
+ virtual ArchitectureRef getCurrentArchitecture() { return nullptr; }
+
+ virtual LowLevelILFunctionRef getCurrentLowLevelILFunction() { return nullptr; }
+ virtual MediumLevelILFunctionRef getCurrentMediumLevelILFunction() { return nullptr; }
+ virtual size_t getCurrentILInstructionIndex() { return BN_INVALID_EXPR; }
+
+ virtual QFont getFont() = 0;
+ DisassemblySettingsRef getDisassemblySettings();
+
+ virtual HighlightTokenState getHighlightTokenState();
+
+ virtual UIActionContext actionContext();
+ Menu& contextMenu() { return m_contextMenu; }
+ UIActionHandler* actionHandler() { return &m_actionHandler; }
+ QWidget* widget() { return m_actionHandler.widget(); }
+
+ static void registerActions();
+};
+
+
+class BINARYNINJAUIAPI ViewNavigationMode
+{
+ View* m_view;
+ std::string m_mode;
+
+ ViewNavigationMode();
+
+public:
+ ViewNavigationMode(View* view, std::string mode) : m_view(view) { m_mode = m_view->getNavigationMode(); m_view->setNavigationMode(mode); }
+ ~ViewNavigationMode() { m_view->setNavigationMode(m_mode); }
+};
+
+class BINARYNINJAUIAPI ViewContainer
+{
+public:
+ virtual ~ViewContainer() {}
+ virtual View* getView() = 0;
+};
+
+class FunctionsView;
+
+class BINARYNINJAUIAPI ViewFrame : public QWidget
+{
+ Q_OBJECT
+
+private:
+ QWidget* createView(const QString& typeName, ViewType* type, BinaryViewRef data);
+ HistoryEntry* getHistoryEntry();
+
+ FileContext* m_context;
+ BinaryViewRef m_data;
+ QWidget* m_view;
+ QWidget* m_viewContainer;
+ QVBoxLayout* m_viewLayout;
+ std::map<QString, QPointer<QWidget>> m_extendedViewCache;
+ std::map<QString, QWidget*> m_viewCache;
+ std::stack<BinaryNinja::Ref<HistoryEntry>> m_back, m_forward;
+ bool m_graphViewPreferred = false;
+ std::vector<QString> m_viewTypePriority;
+
+ FunctionsView* m_funcs = nullptr;
+ FeatureMap* m_featureMap = nullptr;
+
+ UIActionHandler m_actionHandler;
+
+protected:
+ QPointer<CompileDialog> compileDialog;
+
+ bool event(QEvent* event) override;
+ virtual void mousePressEvent(QMouseEvent* event) override;
+ bool gestureEvent(QGestureEvent* event);
+
+ void setView(QWidget* view);
+
+public:
+ explicit ViewFrame(QWidget* parent, FileContext* file, const QString& type, bool createExtendedViews = false);
+ virtual ~ViewFrame();
+
+ FileContext* getFileContext() const { return m_context; }
+ FunctionsView* getFunctionsView() const { return m_funcs; }
+
+ QString getTabName();
+ QString getShortFileName();
+ std::vector<QString> getAvailableTypes() const;
+
+ QString getCurrentView();
+ QString getCurrentDataType();
+ uint64_t getCurrentOffset();
+ void getSelectionOffsets(uint64_t& begin, uint64_t& end);
+
+ View* getCurrentViewInterface() const { return View::getViewFromWidget(m_view); }
+ QWidget* getCurrentWidget() const { return m_view; }
+
+ bool setViewType(const QString& type);
+ bool isGraphViewPreferred() { return m_graphViewPreferred; }
+ void setGraphViewPreferred(bool graphViewPreferred) { m_graphViewPreferred = graphViewPreferred; }
+ void focus();
+ void closeFeatureMap();
+ QWidget* createFeatureMap();
+ void refreshFeatureMap();
+
+ QWidget* getExtendedView(const QString& name, bool create = false);
+
+ bool navigate(const QString& type, uint64_t offset, bool updateInfo = true);
+ bool navigate(const QString& type, const std::function<bool(View*)>& handler, bool updateInfo = true);
+ bool navigate(BinaryViewRef data, uint64_t offset, bool updateInfo = true);
+ bool navigateToFunction(FunctionRef func, uint64_t offset, bool updateInfo = true);
+ bool goToReference(BinaryViewRef data, FunctionRef func, uint64_t source, uint64_t target);
+ QString getTypeForView(QWidget* view);
+ QString getDataTypeForView(QWidget* view);
+
+ bool closeRequest();
+ void closing();
+
+ void updateFonts();
+ void updateTheme();
+ void addHistoryEntry();
+ void back();
+ void forward();
+
+ static bool getAddressFromString(QWidget* parent, BinaryViewRef data, uint64_t& offset,
+ uint64_t currentAddress, const QString& addrStr, std::string& errorString);
+ static bool getAddressFromInput(QWidget* parent, BinaryViewRef data, uint64_t& offset,
+ uint64_t currentAddress, const QString& title = "Go to Address", const QString& msg = "Address:");
+
+ void setCurrentFunction(FunctionRef func);
+ void updateFeatureMapLocation(View* view);
+ void updateCrossReferences();
+ void showCrossReferences();
+
+ virtual UIActionContext actionContext();
+ void bindActions();
+ static void registerActions();
+
+ static ViewFrame* viewFrameForWidget(QWidget* widget);
+
+public Q_SLOTS:
+ virtual void assemble();
+ virtual void compile();
+
+private Q_SLOTS:
+ void deleteFeatureMap();
+
+Q_SIGNALS:
+ void notifyCloseFeatureMap();
+ void nofifyViewChanged(ViewFrame* frame);
+};
+
+Q_DECLARE_METATYPE(View*)
diff --git a/ui/viewtype.h b/ui/viewtype.h
new file mode 100644
index 00000000..2216b9dd
--- /dev/null
+++ b/ui/viewtype.h
@@ -0,0 +1,40 @@
+#pragma once
+
+#include <QtCore/QString>
+#include <QtWidgets/QWidget>
+#include <vector>
+#include "binaryninjaapi.h"
+#include "uicontext.h"
+
+class ViewFrame;
+
+class BINARYNINJAUIAPI ViewType
+{
+ QString m_name, m_longName;
+
+public:
+ ViewType(const QString& name, const QString& longName);
+ virtual ~ViewType();
+
+ const QString& getName() { return m_name; }
+ const QString& getLongName() { return m_longName; }
+ virtual int getPriority(BinaryViewRef data, const QString& filename) = 0;
+ virtual QWidget* create(BinaryViewRef data, ViewFrame* viewFrame) = 0;
+
+ virtual QString getDisplayName(BinaryViewTypeRef type);
+ virtual QString getDisplayLongName(BinaryViewTypeRef type);
+
+ static ViewType* getTypeByName(const QString& name);
+ static const std::vector<ViewType*>& getTypes();
+
+ static void registerViewType(ViewType* type);
+};
+
+
+class BINARYNINJAUIAPI ViewTypeContainer
+{
+public:
+ std::vector<ViewType*> m_types;
+
+ static ViewTypeContainer& GetViewTypeContainer();
+};
diff --git a/ui/xreflist.h b/ui/xreflist.h
new file mode 100644
index 00000000..961e1238
--- /dev/null
+++ b/ui/xreflist.h
@@ -0,0 +1,87 @@
+#pragma once
+
+#include <QtCore/QAbstractItemModel>
+#include <QtCore/QItemSelectionModel>
+#include <QtWidgets/QListView>
+#include <QtWidgets/QStyledItemDelegate>
+#include "binaryninjaapi.h"
+#include "dockhandler.h"
+#include "viewframe.h"
+
+
+class BINARYNINJAUIAPI CrossReferenceListModel: public QAbstractItemModel
+{
+ Q_OBJECT
+
+ QWidget* m_owner;
+ BinaryViewRef m_data;
+ std::vector<BinaryNinja::ReferenceSource> m_refs;
+
+public:
+ CrossReferenceListModel(QWidget* parent, BinaryViewRef data);
+
+ virtual QModelIndex index(int row, int col, const QModelIndex& parent) const override;
+ virtual QModelIndex parent(const QModelIndex& i) const override;
+ virtual bool hasChildren(const QModelIndex& parent) const override;
+ virtual int rowCount(const QModelIndex& parent) const override;
+ virtual int columnCount(const QModelIndex& parent) const override;
+ virtual QVariant data(const QModelIndex& i, int role) const override;
+
+ bool setModelData(const std::vector<BinaryNinja::ReferenceSource>& refs, QItemSelectionModel* selectionModel, bool& selectionUpdated);
+};
+
+
+class BINARYNINJAUIAPI CrossReferenceItemDelegate: public QStyledItemDelegate
+{
+ Q_OBJECT
+
+ QFont m_font;
+ int m_baseline, m_charWidth, m_charHeight, m_charOffset;
+
+ void initFont();
+
+public:
+ CrossReferenceItemDelegate(QWidget* parent);
+
+ void updateFonts();
+
+ virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& idx) const override;
+ virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& idx) const override;
+};
+
+
+class BINARYNINJAUIAPI CrossReferenceList: public QListView, public DockContextHandler
+{
+ Q_OBJECT
+
+ ViewFrame* m_view;
+ CrossReferenceListModel* m_list;
+ CrossReferenceItemDelegate* m_itemDelegate;
+ BinaryViewRef m_data;
+
+ QTimer* m_hoverTimer;
+ QPoint m_hoverPos;
+
+ uint64_t m_curRefTarget = 0;
+
+protected:
+ virtual void contextMenuEvent(QContextMenuEvent* event) override;
+ virtual void keyPressEvent(QKeyEvent* e) override;
+ virtual void mouseMoveEvent(QMouseEvent* e) override;
+ virtual void mousePressEvent(QMouseEvent* e) override;
+ virtual bool shouldBeVisible(ViewFrame* frame) override;
+ virtual void updateFonts() override;
+ virtual void wheelEvent(QWheelEvent* e) override;
+
+private Q_SLOTS:
+ void goToReference(const QModelIndex& idx);
+ void hoverTimerEvent();
+
+public:
+ CrossReferenceList(ViewFrame* view, BinaryViewRef data);
+ virtual ~CrossReferenceList();
+
+ void setCurrentSelection(uint64_t begin, uint64_t end);
+
+ bool hasSelection();
+};