1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
|
#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
struct BINARYNINJAUIAPI LinearViewCursorPosition: public BinaryNinja::LinearDisassemblyPosition
{
uint64_t lineAddress;
size_t lineIndexForAddress;
size_t tokenIndex;
LinearViewCursorPosition();
LinearViewCursorPosition(const LinearViewCursorPosition& pos);
LinearViewCursorPosition(const BinaryNinja::LinearDisassemblyPosition& pos);
LinearViewCursorPosition& operator=(const LinearViewCursorPosition& pos);
};
class BINARYNINJAUIAPI LinearViewHistoryEntry: public HistoryEntry
{
BinaryNinja::LinearDisassemblyPosition m_topPosition;
LinearViewCursorPosition m_cursorPosition;
size_t m_topLineOffset;
HighlightTokenState m_highlight;
public:
const BinaryNinja::LinearDisassemblyPosition& getTopPosition() const { return m_topPosition; }
const LinearViewCursorPosition& 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 LinearViewCursorPosition& 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 MenuHelper
{
public:
LinearViewOptionsWidget(LinearView* parent);
protected:
virtual void showMenu();
private:
LinearView* m_view;
};
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;
LinearViewCursorPosition m_cursorPosition, m_selectionStartPos;
bool m_tokenSelection = false;
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);
bool isLineValidHighlight(const BinaryNinja::LinearDisassemblyLine& line);
void ensureLineVisible(size_t line);
TypeRef createStructure(BinaryNinja::QualifiedName& name, uint64_t size);
StructureRef defineInnerType(TypeRef type, TypeRef baseType, uint64_t offset, uint64_t size);
StructureRef defineInnerPointer(TypeRef type, ArchitectureRef arch, uint64_t baseAddress, uint64_t offset, uint64_t size);
StructureRef defineInnerStruct(TypeRef type, uint64_t offset, uint64_t size);
StructureRef defineInnerArray(TypeRef type, uint64_t offset, uint64_t size);
StructureRef defineInnerName(TypeRef type, uint64_t offset, uint64_t size);
StructureRef defineInnerUnknownType(QWidget* parent, TypeRef type, uint64_t offset, uint64_t size);
StructureRef defineInnerIntegerSize(TypeRef type, uint64_t offset, uint64_t size);
StructureRef defineInnerSign(TypeRef type, uint64_t offset, uint64_t size);
TypeRef getPointerTypeAndName(ArchitectureRef arch, uint64_t addr, std::string& name);
std::string getVariableName(uint64_t addr);
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 addUserXref();
void bookmarkAddress();
void unbookmarkAddress();
void tagAddress();
void tagAddressAccepted(TagTypeRef tt);
void manageAddressTags();
void convertToNop();
void alwaysBranch();
void invertBranch();
void skipAndReturnZero();
void skipAndReturnValue();
void makeTypes(TypeRef type);
void makeInt8();
void makeInt16();
void makeInt32();
void makeInt64();
void toggleIntSize();
void toggleIntSign();
void makePtr();
void makeString();
void changeType();
void createStructOrinferStructureType();
void createArray();
void createStruct();
void createNewTypes();
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; }
void getCurrentOffsetByType(TypeRef resType, uint64_t baseAddr, uint64_t& begin, uint64_t& end, bool singleLine);
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 OnDataMetadataUpdated(BinaryNinja::BinaryView* view, uint64_t offset) override;
virtual void OnTagUpdated(BinaryNinja::BinaryView* data, const BinaryNinja::TagReference& tagRef) 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 mouseMoveEvent(QMouseEvent* event) override;
virtual void mouseDoubleClickEvent(QMouseEvent* event) override;
void up(bool selecting, size_t count = 1);
void down(bool selecting, size_t count = 1);
void left(bool selecting);
void right(bool selecting);
void leftToSymbol(bool selecting);
void rightToSymbol(bool selecting);
void moveToStartOfLine(bool selecting);
void moveToEndOfLine(bool selecting);
void moveToStartOfView();
void moveToEndOfView();
void selectNone();
void navigateToHighlightedToken();
};
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();
};
|