summaryrefslogtreecommitdiff
path: root/ui
diff options
context:
space:
mode:
authorXusheng <xusheng@vector35.com>2020-11-16 17:51:46 +0800
committerXusheng <xusheng@vector35.com>2021-02-17 12:05:47 +0800
commitd9b1df165f9daad6a5229718ecd0ee50a5ef6bf1 (patch)
tree6307b8c16c80f8203bdb96ebc3d54a8d9f10b3bf /ui
parentb651141704a555cf0b6c53152ab0f70d011ec8af (diff)
add support for type xref and variable xref
Diffstat (limited to 'ui')
-rw-r--r--ui/commands.h5
-rw-r--r--ui/flowgraphwidget.h4
-rw-r--r--ui/linearview.h4
-rw-r--r--ui/tokenizedtextview.h4
-rw-r--r--ui/typeview.h7
-rw-r--r--ui/viewframe.h43
-rw-r--r--ui/xreflist.h148
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 = ", ";
+};