diff options
| author | Xusheng <xusheng@vector35.com> | 2020-11-16 17:51:46 +0800 |
|---|---|---|
| committer | Xusheng <xusheng@vector35.com> | 2021-02-17 12:05:47 +0800 |
| commit | d9b1df165f9daad6a5229718ecd0ee50a5ef6bf1 (patch) | |
| tree | 6307b8c16c80f8203bdb96ebc3d54a8d9f10b3bf /ui | |
| parent | b651141704a555cf0b6c53152ab0f70d011ec8af (diff) | |
add support for type xref and variable xref
Diffstat (limited to 'ui')
| -rw-r--r-- | ui/commands.h | 5 | ||||
| -rw-r--r-- | ui/flowgraphwidget.h | 4 | ||||
| -rw-r--r-- | ui/linearview.h | 4 | ||||
| -rw-r--r-- | ui/tokenizedtextview.h | 4 | ||||
| -rw-r--r-- | ui/typeview.h | 7 | ||||
| -rw-r--r-- | ui/viewframe.h | 43 | ||||
| -rw-r--r-- | ui/xreflist.h | 148 |
7 files changed, 186 insertions, 29 deletions
diff --git a/ui/commands.h b/ui/commands.h index d0e8b981..a47f9ab5 100644 --- a/ui/commands.h +++ b/ui/commands.h @@ -33,7 +33,10 @@ bool BINARYNINJAUIAPI overwriteCode(BinaryViewRef data, ArchitectureRef arch, StructureRef BINARYNINJAUIAPI getInnerMostStructureContaining(BinaryViewRef data, StructureRef structure, size_t& memberIndex, const std::vector<std::string>& nameList, size_t nameIndex, TypeRef& type, std::string& typeName); StructureRef BINARYNINJAUIAPI getInnerMostStructureContainingOffset(BinaryViewRef data, StructureRef structure, - const std::vector<std::string>& nameList, size_t nameIndex, size_t& offset, TypeRef& type, std::string& typeName); + const std::vector<std::string>& nameList, size_t nameIndex, size_t offset, TypeRef& type, std::string& typeName); +// Get the offset of the inner most structure, ralative to the supplied outer most structure +uint64_t BINARYNINJAUIAPI getInnerMostStructureOffset(BinaryViewRef data, StructureRef structure, + const std::vector<std::string>& nameList, size_t nameIndex); // Auto generate a structure name std::string BINARYNINJAUIAPI createStructureName(BinaryViewRef data); diff --git a/ui/flowgraphwidget.h b/ui/flowgraphwidget.h index 7b6fc036..1b313c31 100644 --- a/ui/flowgraphwidget.h +++ b/ui/flowgraphwidget.h @@ -213,7 +213,7 @@ public: virtual BinaryViewRef getData() override { return m_data; } virtual uint64_t getCurrentOffset() override; virtual BNAddressRange getSelectionOffsets() override; - virtual BNAddressRange getSelectionForInfo() override; + virtual SelectionInfoForXref getSelectionForXref() override; virtual void setSelectionOffsets(BNAddressRange range) override; virtual bool navigate(uint64_t pos) override; virtual bool navigateToFunction(FunctionRef func, uint64_t pos) override; @@ -275,7 +275,7 @@ public: void showLineInNode(FlowGraphNodeRef node, size_t lineIndex); void ensureCursorVisible(); - void viewInTypesView(std::string typeName); + void viewInTypesView(std::string typeName, uint64_t offset = 0); void setInstructionHighlight(BNHighlightColor color); void setBlockHighlight(BNHighlightColor color); diff --git a/ui/linearview.h b/ui/linearview.h index 2d03248c..5c1d51bd 100644 --- a/ui/linearview.h +++ b/ui/linearview.h @@ -217,7 +217,7 @@ private Q_SLOTS: void adjustSize(int width, int height); void viewInHexEditor(); void viewInGraph(); - void viewInTypesView(std::string typeName = ""); + void viewInTypesView(std::string typeName = "", uint64_t offset = 0); void cycleILView(bool forward); void copyAddressSlot(); void goToAddress(); @@ -295,7 +295,7 @@ public: virtual uint64_t getCurrentOffset() override; virtual UIActionContext actionContext() override; virtual BNAddressRange getSelectionOffsets() override; - virtual BNAddressRange getSelectionForInfo() override; + virtual SelectionInfoForXref getSelectionForXref() override; virtual void setSelectionOffsets(BNAddressRange range) override; virtual FunctionRef getCurrentFunction() override; virtual BasicBlockRef getCurrentBasicBlock() override; diff --git a/ui/tokenizedtextview.h b/ui/tokenizedtextview.h index d937760a..01174e82 100644 --- a/ui/tokenizedtextview.h +++ b/ui/tokenizedtextview.h @@ -63,7 +63,7 @@ class BINARYNINJAUIAPI TokenizedTextView: public QAbstractScrollArea, public Vie void viewInHexEditor(); void viewInGraph(); - void viewInTypesView(std::string typeName = ""); + void viewInTypesView(std::string typeName = "", uint64_t offset = 0); void goToAddress(); void defineNameAtAddr(uint64_t addr); void defineName(); @@ -108,7 +108,7 @@ public: virtual BinaryViewRef getData() override { return m_data; } virtual uint64_t getCurrentOffset() override; virtual BNAddressRange getSelectionOffsets() override; - virtual BNAddressRange getSelectionForInfo() override; + virtual SelectionInfoForXref getSelectionForXref() override; virtual void setSelectionOffsets(BNAddressRange range) override; virtual FunctionRef getCurrentFunction() override; virtual BasicBlockRef getCurrentBasicBlock() override; diff --git a/ui/typeview.h b/ui/typeview.h index bc2fcc10..23985c59 100644 --- a/ui/typeview.h +++ b/ui/typeview.h @@ -157,6 +157,7 @@ public: virtual BinaryViewRef getData() override { return m_data; } virtual uint64_t getCurrentOffset() override; virtual BNAddressRange getSelectionOffsets() override; + virtual SelectionInfoForXref getSelectionForXref() override; virtual void setSelectionOffsets(BNAddressRange range) override; virtual bool navigate(uint64_t) override; @@ -164,7 +165,8 @@ public: virtual void setNavigationMode(std::string mode) override; virtual std::vector<std::string> getNavigationModes() override; - bool navigateToType(const std::string& name); + uint64_t findMatchingLine(const BinaryNinja::QualifiedName& name, uint64_t offset); + bool navigateToType(const std::string& name, uint64_t offset = 0); virtual void OnTypeDefined(BinaryNinja::BinaryView* view, const BinaryNinja::QualifiedName& name, BinaryNinja::Type* type) override; @@ -196,6 +198,8 @@ public: static void registerActions(); + virtual ArchitectureRef getOrAskForArchitecture(); + protected: virtual void resizeEvent(QResizeEvent* event) override; virtual void paintEvent(QPaintEvent* event) override; @@ -222,6 +226,7 @@ private Q_SLOTS: void createStructure(); void createUnion(); void setStructureSize(); + void addUserXref(); void updateLineNumberAreaWidth(size_t lineCount); }; diff --git a/ui/viewframe.h b/ui/viewframe.h index 91303cad..162dac11 100644 --- a/ui/viewframe.h +++ b/ui/viewframe.h @@ -14,6 +14,45 @@ #include "viewtype.h" #include "action.h" +// this struct is used to pass selection information for cross references +struct SelectionInfoForXref +{ + // Check these booleans before accessing the address/type/variable info, + // since the invalid fields are not guaranteed to be initialized/zero-ed. + // At any given time, at most one of these four should be true. + bool addrValid, typeValid, typeFieldValid, localVarValid; + + BNFunctionGraphType ilSource; + + uint64_t start; + uint64_t end; + + BinaryNinja::QualifiedName type; + uint64_t offset; + + BinaryNinja::Variable var; + + // These two need to be tested against nullptr before de-referencing + FunctionRef func; + ArchitectureRef arch; + + bool operator== (const SelectionInfoForXref& other) const + { + if (addrValid && other.addrValid) + return (start == other.start) && (end == other.end) && + (func == other.func) && (arch == other.arch); + else if (typeValid && other.typeValid) + return type == other.type; + else if (typeFieldValid && other.typeFieldValid) + return (type == other.type) && (offset == other.offset); + else if (localVarValid && other.localVarValid) + return (var == other.var) && (ilSource == other.ilSource); + return false; + } + + bool operator!= (const SelectionInfoForXref& other) const { return !(*this == other); } + bool isValid() const { return addrValid || typeValid || typeFieldValid || localVarValid; } +}; class BINARYNINJAUIAPI HistoryEntry: public BinaryNinja::RefCountObject { @@ -77,7 +116,7 @@ public: virtual BinaryViewRef getData() = 0; virtual uint64_t getCurrentOffset() = 0; virtual BNAddressRange getSelectionOffsets(); - virtual BNAddressRange getSelectionForInfo(); + virtual SelectionInfoForXref getSelectionForXref(); virtual void setSelectionOffsets(BNAddressRange range) = 0; virtual bool navigate(uint64_t offset) = 0; virtual bool navigateToFunction(FunctionRef func, uint64_t offset); @@ -290,6 +329,8 @@ public: bool navigate(BinaryViewRef data, uint64_t offset, bool updateInfo = true, bool addHistoryEntry = true); bool navigateToFunction(FunctionRef func, uint64_t offset, bool updateInfo = true, bool addHistoryEntry = true); 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); QString getTypeForView(QWidget* view); QString getDataTypeForView(const QString& type); QString getDataTypeForView(QWidget* view); diff --git a/ui/xreflist.h b/ui/xreflist.h index 5194a7e2..fe59d3d4 100644 --- a/ui/xreflist.h +++ b/ui/xreflist.h @@ -41,13 +41,19 @@ public: { DataXrefType, CodeXrefType, - VariableXrefType + VariableXrefType, + TypeXrefType }; protected: FunctionRef m_func; ArchitectureRef m_arch; uint64_t m_addr; + BinaryNinja::QualifiedName m_typeName; + uint64_t m_offset; + BinaryNinja::Variable m_var; + BNFunctionGraphType m_ilType; + size_t m_instrId; XrefType m_type; XrefDirection m_direction; mutable XrefHeader* m_parentItem; @@ -57,7 +63,11 @@ protected: public: explicit XrefItem(); explicit XrefItem(XrefHeader* parent, XrefType type, FunctionRef func); - explicit XrefItem(BinaryNinja::ReferenceSource referenceSource, XrefType type, XrefDirection direction); + // The four constructors are used for code/data/type/variable referecens, respectively + explicit XrefItem(BinaryNinja::ReferenceSource ref, XrefType type, XrefDirection direction); + explicit XrefItem(uint64_t addr, XrefType type, XrefDirection direction); + explicit XrefItem(BinaryNinja::TypeReferenceSource ref, XrefType type, XrefDirection direction); + explicit XrefItem(BinaryNinja::Variable var, BinaryNinja::ILReferenceSource ref, XrefType type, XrefDirection direction); XrefItem(const XrefItem& ref); virtual ~XrefItem(); @@ -65,6 +75,11 @@ public: const FunctionRef& func() const { return m_func; } const ArchitectureRef& arch() const { return m_arch; } uint64_t addr() const { return m_addr; } + BinaryNinja::QualifiedName typeName() const { return m_typeName; } + uint64_t offset() const { return m_offset; } + BinaryNinja::Variable variable() const { return m_var; } + BNFunctionGraphType ilType() const { return m_ilType; } + size_t instrId() const { return m_instrId; } XrefType type() const { return m_type; } int size() const { return m_size; } void setSize(int size) const { m_size = size; } @@ -113,6 +128,34 @@ public: }; +class XrefTypeHeader : public XrefHeader +{ + std::deque<XrefItem*> m_refs; +public: + XrefTypeHeader(); + XrefTypeHeader(BinaryNinja::QualifiedName name, XrefHeader* parent, XrefItem* child); + XrefTypeHeader(const XrefTypeHeader& header); + virtual int childCount() const override { return (int)m_refs.size(); } + virtual void appendChild(XrefItem* ref) override; + virtual int row(const XrefItem* item) const override; + virtual XrefItem* child(int i) const override; +}; + + +class XrefVariableHeader : public XrefHeader +{ + std::deque<XrefItem*> m_refs; +public: + XrefVariableHeader(); + XrefVariableHeader(XrefHeader* parent, XrefItem* child); + XrefVariableHeader(const XrefVariableHeader& header); + virtual int childCount() const override { return (int)m_refs.size(); } + virtual void appendChild(XrefItem* ref) override; + virtual int row(const XrefItem* item) const override; + virtual XrefItem* child(int i) const override; +}; + + class XrefCodeReferences: public XrefHeader { std::map<FunctionRef, XrefFunctionHeader*> m_refs; @@ -141,9 +184,39 @@ public: }; +class XrefTypeReferences: public XrefHeader +{ + std::map<BinaryNinja::QualifiedName, XrefTypeHeader*> m_refs; + std::deque<XrefTypeHeader*> m_refList; +public: + XrefTypeReferences(XrefHeader* parent); + virtual ~XrefTypeReferences(); + virtual int childCount() const override { return (int)m_refs.size(); }; + virtual void appendChild(XrefItem* ref) override; + XrefHeader* parentOf(XrefItem* ref) const; + virtual int row(const XrefItem* item) const override; + virtual XrefItem* child(int i) const override; +}; + + +class XrefVariableReferences: public XrefHeader +{ + std::map<BinaryNinja::Variable, XrefVariableHeader*> m_refs; + std::deque<XrefVariableHeader*> m_refList; +public: + XrefVariableReferences(XrefHeader* parent); + virtual ~XrefVariableReferences(); + virtual int childCount() const override { return (int)m_refs.size(); }; + virtual void appendChild(XrefItem* ref) override; + XrefHeader* parentOf(XrefItem* ref) const; + virtual int row(const XrefItem* item) const override; + virtual XrefItem* child(int i) const override; +}; + + class XrefRoot: public XrefHeader { - std::map<int, XrefHeader*> m_refs; + std::map<XrefItem::XrefType, XrefHeader*> m_refs; public: XrefRoot(); XrefRoot(XrefRoot&& root); @@ -162,10 +235,11 @@ class BINARYNINJAUIAPI CrossReferenceTreeModel : public QAbstractItemModel XrefRoot* m_rootItem; QWidget* m_owner; BinaryViewRef m_data; + ViewFrame* m_view; std::vector<XrefItem> m_refs; public: - CrossReferenceTreeModel(QWidget* parent, BinaryViewRef data); + CrossReferenceTreeModel(QWidget* parent, BinaryViewRef data, ViewFrame* view); virtual ~CrossReferenceTreeModel() {} virtual QModelIndex index(int row, int col, const QModelIndex& parent = QModelIndex()) const override; @@ -181,6 +255,7 @@ public: XrefRoot* getRoot() { return m_rootItem; } bool setModelData(std::vector<XrefItem>& refs, QItemSelectionModel* selectionModel, bool& selectionUpdated); int leafCount() const; + ViewFrame* getView() const { return m_view; } }; @@ -190,6 +265,7 @@ class BINARYNINJAUIAPI CrossReferenceTableModel : public QAbstractTableModel QWidget* m_owner; BinaryViewRef m_data; + ViewFrame* m_view; std::vector<XrefItem> m_refs; public: enum ColumnHeaders @@ -200,7 +276,7 @@ public: Preview = 3 }; - CrossReferenceTableModel(QWidget* parent, BinaryViewRef data); + CrossReferenceTableModel(QWidget* parent, BinaryViewRef data, ViewFrame* view); virtual ~CrossReferenceTableModel() {} virtual QModelIndex index(int row, int col, const QModelIndex& parent = QModelIndex()) const override; @@ -213,6 +289,7 @@ public: virtual bool hasChildren(const QModelIndex&) const override { return false; } bool setModelData(std::vector<XrefItem>& refs, QItemSelectionModel* selectionModel, bool& selectionUpdated); const XrefItem& getRow(int idx); + ViewFrame* getView() const { return m_view; } }; @@ -243,6 +320,8 @@ class BINARYNINJAUIAPI CrossReferenceFilterProxyModel : public QSortFilterProxyM bool m_showData = true; bool m_showCode = true; + bool m_showType = true; + bool m_showVariable = true; bool m_showIncoming = true; bool m_showOutgoing = true; bool m_table; @@ -261,8 +340,8 @@ protected: virtual bool hasChildren(const QModelIndex& parent) const override; public Q_SLOTS: - void directionChanged(int index); - void typeChanged(int index); + void directionChanged(int index, bool checked); + void typeChanged(int index, bool checked); void resetFilter(); }; @@ -278,7 +357,7 @@ public: CrossReferenceContainer(CrossReferenceWidget* parent, ViewFrame* view, BinaryViewRef data); virtual ~CrossReferenceContainer() {} virtual QModelIndex translateIndex(const QModelIndex& idx) const = 0; - virtual bool getReference(const QModelIndex& idx, FunctionRef& func, uint64_t& addr) const = 0; + virtual bool getReference(const QModelIndex& idx, XrefItem** refPtr) const = 0; virtual QModelIndex nextIndex() = 0; virtual QModelIndex prevIndex() = 0; virtual QModelIndexList selectedRows() const = 0; @@ -300,7 +379,7 @@ class BINARYNINJAUIAPI CrossReferenceTree: public QTreeView, public CrossReferen protected: void drawBranches(QPainter *painter, const QRect &rect, const QModelIndex &index) const override; - virtual bool getReference(const QModelIndex& idx, FunctionRef& func, uint64_t& addr) const override; + virtual bool getReference(const QModelIndex& idx, XrefItem** refPtr) const override; public: CrossReferenceTree(CrossReferenceWidget* parent, ViewFrame* view, BinaryViewRef data); @@ -344,7 +423,7 @@ public: virtual QModelIndex prevIndex() override; virtual bool hasSelection() const override { return selectionModel()->selectedRows().size() != 0; } virtual QModelIndexList selectedRows() const override { return selectionModel()->selectedRows(); } - virtual bool getReference(const QModelIndex& idx, FunctionRef& func, uint64_t& addr) const override; + virtual bool getReference(const QModelIndex& idx, XrefItem** refPtr) const override; virtual void mouseMoveEvent(QMouseEvent* e) override; virtual void mousePressEvent(QMouseEvent* e) override; virtual void keyPressEvent(QKeyEvent* e) override; @@ -360,6 +439,7 @@ Q_SIGNALS: }; class ExpandableGroup; +class QCheckboxCombo; class BINARYNINJAUIAPI CrossReferenceWidget: public QWidget, public DockContextHandler { Q_OBJECT @@ -370,7 +450,7 @@ class BINARYNINJAUIAPI CrossReferenceWidget: public QWidget, public DockContextH QAbstractItemView* m_object; QLabel* m_label; QCheckBox* m_pinRefs; - QComboBox* m_direction, *m_type; + QCheckboxCombo *m_direction, *m_type; CrossReferenceTable* m_table; CrossReferenceTree* m_tree; CrossReferenceContainer* m_container; @@ -384,10 +464,8 @@ class BINARYNINJAUIAPI CrossReferenceWidget: public QWidget, public DockContextH ExpandableGroup* m_group; bool m_curRefTargetValid = false; - uint64_t m_curRefTarget = 0; - uint64_t m_curRefTargetEnd = 0; - uint64_t m_newRefTarget = 0; - uint64_t m_newRefTargetEnd = 0; + SelectionInfoForXref m_curRef; + SelectionInfoForXref m_newRef; bool m_navigating = false; bool m_navToNextOrPrevStarted = false; bool m_pinned; @@ -400,8 +478,9 @@ public: virtual void notifyFontChanged() override; virtual bool shouldBeVisible(ViewFrame* frame) override; - virtual void setCurrentSelection(uint64_t begin, uint64_t end); - virtual void setCurrentPinnedSelection(uint64_t begin, uint64_t end); + virtual QString getHeaderText(SelectionInfoForXref selectionInfo); + virtual void setCurrentSelection(SelectionInfoForXref selectionInfo); + virtual void setCurrentPinnedSelection(SelectionInfoForXref selectionInfo); void updatePinnedSelection(); virtual void navigateToNext(); virtual void navigateToPrev(); @@ -423,8 +502,8 @@ public Q_SLOTS: void referenceActivated(const QModelIndex& idx); void pinnedStateChanged(bool state); void selectionChanged(); - void typeChanged(int change); - void directionChanged(int change); + void typeChanged(int index, bool checked); + void directionChanged(int change, bool checked); }; @@ -445,4 +524,33 @@ public: explicit ExpandableGroup(const QString& title = "", QWidget* parent = nullptr); void setContentLayout(QLayout* contentLayout); void setTitle(const QString& title) { m_button->setText(title); } -};
\ No newline at end of file +}; + + +// https://github.com/CuriousCrow/QCheckboxCombo +/* + * QCheckboxCombo is a combobox widget that contains items with checkboxes + * User can select proper items by checking corresponding checkboxes. + * Resulting text will contain list of selected items separated by delimiter (", " by default) + */ +class BINARYNINJAUIAPI QCheckboxCombo : public QComboBox +{ + Q_OBJECT + +public: + explicit QCheckboxCombo(QWidget *parent = nullptr); + bool eventFilter(QObject* watched, QEvent* event); + void hidePopup(); + void showPopup(); + void addItem(const QString &text, bool checked = true); + +Q_SIGNALS: + void selectionChanged(const QString& text); + void itemToggled(int index, bool checked); + +private: + bool m_popupVisible = false; + bool m_editable = false; + QString m_selectionString; + const QString m_delimiter = ", "; +}; |
