diff options
| -rw-r--r-- | python/examples/linear_mlil.py | 35 | ||||
| -rw-r--r-- | ui/action.h | 3 | ||||
| -rw-r--r-- | ui/disassemblyview.h | 7 | ||||
| -rw-r--r-- | ui/flowgraphwidget.h | 15 | ||||
| -rw-r--r-- | ui/linearview.h | 7 | ||||
| -rw-r--r-- | ui/tokenizedtextview.h | 7 | ||||
| -rw-r--r-- | ui/typeview.h | 7 | ||||
| -rw-r--r-- | ui/viewframe.h | 44 |
8 files changed, 95 insertions, 30 deletions
diff --git a/python/examples/linear_mlil.py b/python/examples/linear_mlil.py index 2af28741..40292c52 100644 --- a/python/examples/linear_mlil.py +++ b/python/examples/linear_mlil.py @@ -51,11 +51,11 @@ class LinearMLILView(TokenizedTextView): # Function header result = [] result.append(LinearDisassemblyLine(LinearDisassemblyLineType.FunctionHeaderStartLineType, - self.function, None, 0, DisassemblyTextLine([], self.function.start))) + self.function, None, DisassemblyTextLine([], self.function.start))) result.append(LinearDisassemblyLine(LinearDisassemblyLineType.FunctionHeaderLineType, - self.function, None, 0, DisassemblyTextLine(self.function.type_tokens, self.function.start))) + self.function, None, DisassemblyTextLine(self.function.type_tokens, self.function.start))) result.append(LinearDisassemblyLine(LinearDisassemblyLineType.FunctionHeaderEndLineType, - self.function, None, 0, DisassemblyTextLine([], self.function.start))) + self.function, None, DisassemblyTextLine([], self.function.start))) # Display IL instructions in order lastAddr = self.function.start @@ -65,19 +65,19 @@ class LinearMLILView(TokenizedTextView): if lastBlock is not None: # Blank line between basic blocks result.append(LinearDisassemblyLine(LinearDisassemblyLineType.CodeDisassemblyLineType, - self.function, block, 0, DisassemblyTextLine([], lastAddr))) + self.function, block, DisassemblyTextLine([], lastAddr))) for i in block: lines, length = renderer.get_disassembly_text(i.instr_index) lastAddr = i.address lineIndex = 0 for line in lines: result.append(LinearDisassemblyLine(LinearDisassemblyLineType.CodeDisassemblyLineType, - self.function, block, lineIndex, line)) + self.function, block, line)) lineIndex += 1 lastBlock = block result.append(LinearDisassemblyLine(LinearDisassemblyLineType.FunctionEndLineType, - self.function, lastBlock, lineIndex, DisassemblyTextLine([], lastAddr))) + self.function, lastBlock, DisassemblyTextLine([], lastAddr))) return result @@ -104,17 +104,28 @@ class LinearMLILView(TokenizedTextView): def getHistoryEntry(self): class LinearMLILHistoryEntry(TokenizedTextViewHistoryEntry): - def __init__(self, function): - super(LinearMLILHistoryEntry, self).__init__() - self.function = function + def __init__(self, function_start): + TokenizedTextViewHistoryEntry.__init__(self) + self.function_start = function_start - result = LinearMLILHistoryEntry(self.function) + def serialize(self): + v = TokenizedTextViewHistoryEntry.serialize(self) + v["function_start"] = self.function_start + return v + + def deserialize(self, v): + if not TokenizedTextViewHistoryEntry.deserialize(self, v): + return False + self.function_start = v["function_start"] + return True + + result = LinearMLILHistoryEntry(self.function.start) self.populateDefaultHistoryEntry(result) return result def navigateToHistoryEntry(self, entry): - if hasattr(entry, 'function'): - self.function = entry.function + if hasattr(entry, 'function_start'): + self.function = self.data.get_functions_at(entry.function_start)[0] self.setFunction(self.function) self.updateLines() super(LinearMLILView, self).navigateToHistoryEntry(entry) diff --git a/ui/action.h b/ui/action.h index 31d2e397..a9c70937 100644 --- a/ui/action.h +++ b/ui/action.h @@ -39,6 +39,9 @@ struct BINARYNINJAUIAPI HighlightTokenState size_t characterIndex; HighlightTokenState(); + + Json::Value serialize() const; + bool deserialize(const Json::Value& value); }; diff --git a/ui/disassemblyview.h b/ui/disassemblyview.h index cf3103eb..4f200c54 100644 --- a/ui/disassemblyview.h +++ b/ui/disassemblyview.h @@ -24,6 +24,9 @@ class BINARYNINJAUIAPI DisassemblyHistoryEntry: public FlowGraphHistoryEntry public: BNFunctionGraphType getGraphType() const { return m_graphType; } void setGraphType(BNFunctionGraphType type) { m_graphType = type; } + + virtual Json::Value serialize() const override; + virtual bool deserialize(const Json::Value& value) override; }; class DisassemblyContainer; @@ -44,8 +47,8 @@ public: virtual bool navigateToFunction(FunctionRef func, uint64_t pos) override; virtual bool navigateToViewLocation(const ViewLocation& viewLocation) override; - virtual HistoryEntry* getHistoryEntry() override; - virtual void navigateToHistoryEntry(HistoryEntry* entry) override; + virtual BinaryNinja::Ref<HistoryEntry> getHistoryEntry() override; + virtual void navigateToHistoryEntry(BinaryNinja::Ref<HistoryEntry> entry) override; virtual StatusBarWidget* getStatusBarWidget() override; diff --git a/ui/flowgraphwidget.h b/ui/flowgraphwidget.h index 6d759401..9399b26e 100644 --- a/ui/flowgraphwidget.h +++ b/ui/flowgraphwidget.h @@ -46,6 +46,9 @@ public: void setScale(float s) { m_scale = s; } void setCurrentAddress(uint64_t a) { m_addr = a; } void setHighlightTokenState(const HighlightTokenState& state) { m_highlight = state; } + + virtual Json::Value serialize() const override; + virtual bool deserialize(const Json::Value& value) override; }; class BINARYNINJAUIAPI FlowGraphWidget: public QAbstractScrollArea, public View, public PreviewScrollHandler, @@ -164,7 +167,7 @@ protected: void navigateToAddress(uint64_t addr); void navigateToGotoLabel(uint64_t label); - void setGraphInternal(FlowGraphRef graph, FlowGraphHistoryEntry* entry, bool useAddr, uint64_t addr, + void setGraphInternal(FlowGraphRef graph, BinaryNinja::Ref<FlowGraphHistoryEntry> entry, bool useAddr, uint64_t addr, bool notify, bool recenterWithPreviousGraph, size_t index = BN_INVALID_EXPR); void up(bool selecting, size_t count = 1); @@ -200,7 +203,7 @@ public: void setGraph(FlowGraphRef graph); void setGraph(FlowGraphRef graph, uint64_t addr); void setGraphAtIndex(FlowGraphRef graph, size_t index); - void setGraph(FlowGraphRef graph, FlowGraphHistoryEntry* entry); + void setGraph(FlowGraphRef graph, BinaryNinja::Ref<FlowGraphHistoryEntry> entry); void setRelatedGraph(FlowGraphRef graph); void setRelatedGraph(FlowGraphRef graph, uint64_t addr); void updateToGraph(FlowGraphRef graph); @@ -214,8 +217,8 @@ public: virtual bool navigate(uint64_t pos) override; virtual bool navigateToFunction(FunctionRef func, uint64_t pos) override; virtual bool navigateToViewLocation(const ViewLocation& viewLocation) override; - bool navigateWithHistoryEntry(uint64_t addr, FlowGraphHistoryEntry* entry); - bool navigateWithHistoryEntry(FunctionRef func, uint64_t addr, FlowGraphHistoryEntry* entry); + bool navigateWithHistoryEntry(uint64_t addr, BinaryNinja::Ref<FlowGraphHistoryEntry> entry); + bool navigateWithHistoryEntry(FunctionRef func, uint64_t addr, BinaryNinja::Ref<FlowGraphHistoryEntry> entry); void setNavigationTarget(View* target) { m_navigationTarget = target; } virtual void clearRelatedHighlights(); @@ -238,9 +241,9 @@ public: virtual void closing() override; - virtual HistoryEntry* getHistoryEntry() override; + virtual BinaryNinja::Ref<HistoryEntry> getHistoryEntry() override; void populateDefaultHistoryEntry(FlowGraphHistoryEntry* entry); - virtual void navigateToHistoryEntry(HistoryEntry* entry) override; + virtual void navigateToHistoryEntry(BinaryNinja::Ref<HistoryEntry> entry) override; virtual FunctionRef getCurrentFunction() override; virtual BasicBlockRef getCurrentBasicBlock() override; diff --git a/ui/linearview.h b/ui/linearview.h index 6d662807..f875a853 100644 --- a/ui/linearview.h +++ b/ui/linearview.h @@ -85,6 +85,9 @@ public: void setFunction(uint64_t f) { m_func = f; } void setInFunction(bool inFunc) { m_inFunc = inFunc; } void setHighlightTokenState(const HighlightTokenState& state) { m_highlight = state; } + + virtual Json::Value serialize() const override; + virtual bool deserialize(const Json::Value& value) override; }; class BINARYNINJAUIAPI LinearView: public QAbstractScrollArea, public View, public BinaryNinja::BinaryDataNotification @@ -316,8 +319,8 @@ public: virtual void setNavigationMode(std::string mode) override; virtual std::vector<std::string> getNavigationModes() override; - virtual HistoryEntry* getHistoryEntry() override; - virtual void navigateToHistoryEntry(HistoryEntry* entry) override; + virtual BinaryNinja::Ref<HistoryEntry> getHistoryEntry() override; + virtual void navigateToHistoryEntry(BinaryNinja::Ref<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; diff --git a/ui/tokenizedtextview.h b/ui/tokenizedtextview.h index c76d65af..99726c08 100644 --- a/ui/tokenizedtextview.h +++ b/ui/tokenizedtextview.h @@ -22,6 +22,9 @@ public: void setTopLine(size_t line) { m_topLine = line; } void setCursorLine(size_t line) { m_cursorLine = line; } void setHighlightTokenState(const HighlightTokenState& state) { m_highlight = state; } + + virtual Json::Value serialize() const override; + virtual bool deserialize(const Json::Value& value) override; }; class BINARYNINJAUIAPI TokenizedTextView: public QAbstractScrollArea, public View, public BinaryNinja::BinaryDataNotification @@ -118,9 +121,9 @@ public: virtual ArchitectureRef getCurrentArchitecture() override; virtual bool navigate(uint64_t pos) override; - virtual HistoryEntry* getHistoryEntry() override; + virtual BinaryNinja::Ref<HistoryEntry> getHistoryEntry() override; void populateDefaultHistoryEntry(TokenizedTextViewHistoryEntry* entry); - virtual void navigateToHistoryEntry(HistoryEntry* entry) override; + virtual void navigateToHistoryEntry(BinaryNinja::Ref<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; diff --git a/ui/typeview.h b/ui/typeview.h index 8ff01946..1f8b4106 100644 --- a/ui/typeview.h +++ b/ui/typeview.h @@ -74,6 +74,9 @@ public: void setSelectionStartOffset(size_t offset) { m_selectionStartOffset = offset; } void setHighlightTokenState(const HighlightTokenState& state) { m_highlight = state; } + + virtual Json::Value serialize() const override; + virtual bool deserialize(const Json::Value& value) override; }; class TypesContainer; @@ -188,8 +191,8 @@ public: virtual StatusBarWidget* getStatusBarWidget() override; - virtual HistoryEntry* getHistoryEntry() override; - virtual void navigateToHistoryEntry(HistoryEntry* entry) override; + virtual BinaryNinja::Ref<HistoryEntry> getHistoryEntry() override; + virtual void navigateToHistoryEntry(BinaryNinja::Ref<HistoryEntry> entry) override; void lineNumberAreaPaintEvent(QPaintEvent *event); int lineNumberAreaWidth(); diff --git a/ui/viewframe.h b/ui/viewframe.h index 4d1ebf32..1a87e7af 100644 --- a/ui/viewframe.h +++ b/ui/viewframe.h @@ -14,6 +14,7 @@ #include <stack> #include <utility> #include <vector> +#include <functional> #include "binaryninjaapi.h" #include "filecontext.h" #include "viewtype.h" @@ -68,6 +69,19 @@ public: QString getViewType() const { return m_viewType; } void setViewType(const QString& type) { m_viewType = type; } + + /*! + Serialize to json representation + \return Json representation of history entry. In the Python api, this must be a dict. + */ + virtual Json::Value serialize() const; + /*! + Deserialize from json representation. This method should clear any previously entered data + on the HistoryEntry as if it were newly created. + \param value Json representation of history entry. In the Python api, this will be a dict. + \return If deserialization was successful + */ + virtual bool deserialize(const Json::Value& value); }; @@ -178,8 +192,8 @@ public: virtual bool canDisplayAs(const UIActionContext& context, const BNIntegerDisplayType); virtual void displayAs(const UIActionContext& context, BNIntegerDisplayType type); - virtual HistoryEntry* getHistoryEntry(); - virtual void navigateToHistoryEntry(HistoryEntry* entry); + virtual BinaryNinja::Ref<HistoryEntry> getHistoryEntry(); + virtual void navigateToHistoryEntry(BinaryNinja::Ref<HistoryEntry> entry); virtual StatusBarWidget* getStatusBarWidget() { return nullptr; } @@ -205,6 +219,8 @@ public: UIActionHandler* actionHandler() { return &m_actionHandler; } QWidget* widget() { return m_actionHandler.widget(); } + QString viewType(); + static void registerActions(); }; @@ -284,7 +300,7 @@ class BINARYNINJAUIAPI ViewFrame : public QWidget private: QWidget* createView(const QString& typeName, ViewType* type, BinaryViewRef data, bool createDynamicWidgets = true); - HistoryEntry* getHistoryEntry(); + BinaryNinja::Ref<HistoryEntry> getHistoryEntry(); FileContext* m_context; bool m_fileContentsLock = true; // file contents protection from accidental modification in the UI @@ -296,7 +312,7 @@ private: QVBoxLayout* m_viewLayout; std::map<QString, std::map<QString, QPointer<QWidget>>> m_extViewCache; std::map<QString, QWidget*> m_viewCache; - std::stack<BinaryNinja::Ref<HistoryEntry>> m_back, m_forward; + std::list<BinaryNinja::Ref<HistoryEntry>> m_back, m_forward; bool m_graphViewPreferred = false; std::vector<QString> m_viewTypePriority; @@ -310,6 +326,12 @@ protected: bool gestureEvent(QGestureEvent* event); void setView(QWidget* view); + /*! + Load one history entry from json representation + \param json Json rep of history entry + \return Entry, if successful, else nullptr + */ + BinaryNinja::Ref<HistoryEntry> deserializeHistoryEntry(const Json::Value& json); public: explicit ViewFrame(QWidget* parent, FileContext* file, const QString& type, bool createDynamicWidgets = false); @@ -354,9 +376,12 @@ public: bool goToReference(BinaryViewRef data, FunctionRef func, uint64_t source, uint64_t target, bool addHistoryEntry = true); bool navigateToViewLocation(BinaryViewRef data, const ViewLocation& viewLocation, bool addHistoryEntry = true); + bool navigateToHistoryEntry(BinaryNinja::Ref<HistoryEntry> entry); QString getTypeForView(QWidget* view) const; QString getDataTypeForView(const QString& type) const; QString getDataTypeForView(QWidget* view) const; + QWidget* getViewWidgetForType(const QString& type); + View* getViewForType(const QString& type); bool closeRequest(); void closing(); @@ -364,6 +389,17 @@ public: void updateFonts(); void updateTheme(); void addHistoryEntry(); + /*! + Parse history entries from the raw data associated with a BinaryView, loading them into the back/forward + navigation stacks, and navigating to the saved position. + \param data View containing history entries + */ + void readHistoryEntries(BinaryViewRef data); + /*! + Serialize history entries and current position, storing them in the raw data associated with a BinaryView. + \param data View for saving history entries + */ + void writeHistoryEntries(BinaryViewRef data); void back(); void forward(); |
