-
Notifications
You must be signed in to change notification settings - Fork 283
Expand file tree
/
Copy pathutil.h
More file actions
223 lines (182 loc) · 8.97 KB
/
util.h
File metadata and controls
223 lines (182 loc) · 8.97 KB
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
#pragma once
#include "uitypes.h"
#include "viewframe.h"
#include "qfileaccessor.h"
#include "lowlevelilinstruction.h"
#include "mediumlevelilinstruction.h"
#include "highlevelilinstruction.h"
#include <QtWidgets/QWidget>
#include <QtCore/QFileInfo>
#include <optional>
/*!
@addtogroup Util
\ingroup uiapi
@{
*/
std::string BINARYNINJAUIAPI getStringForLocalVariable(ArchitectureRef arch, FunctionRef func, BinaryNinja::Variable localVar);
std::string BINARYNINJAUIAPI getStringForRegisterValue(ArchitectureRef arch, BinaryNinja::RegisterValue value);
std::string BINARYNINJAUIAPI getPossibleValueSetStateName(BNRegisterValueType state);
std::string BINARYNINJAUIAPI getStringForIntegerValue(int64_t value);
std::string BINARYNINJAUIAPI getStringForUIntegerValue(uint64_t value);
bool BINARYNINJAUIAPI canDisplayIntegerTokenAs(const HighlightTokenState& token, BNIntegerDisplayType displayType);
BNIntegerDisplayType BINARYNINJAUIAPI getInvertedIntegerDisplayType(BNIntegerDisplayType displayType, const std::string& text);
BNIntegerDisplayType BINARYNINJAUIAPI getToggledIntegerRadixDisplayType(BNIntegerDisplayType displayType, const std::string& text);
BNIntegerDisplayType BINARYNINJAUIAPI getToggledIntegerComplementDisplayType(BNIntegerDisplayType displayType, const std::string& text);
TypeRef BINARYNINJAUIAPI getIntegerTypePreservingDisplay(TypeRef type, size_t width, BinaryNinja::Confidence<bool> isSigned);
TypeRef BINARYNINJAUIAPI getIntegerTypeWithWidthPreservingAttributes(TypeRef type, size_t width);
TypeRef BINARYNINJAUIAPI getIntegerTypeWithSignPreservingAttributes(TypeRef type, BinaryNinja::Confidence<bool> isSigned);
std::string BINARYNINJAUIAPI getStringForPossibleValueSet(ArchitectureRef arch, const BinaryNinja::PossibleValueSet& values, bool pretty = true);
std::string BINARYNINJAUIAPI getStringForInstructionDataflowDetails(BinaryViewRef data, ArchitectureRef arch, FunctionRef func, uint64_t address);
std::optional<BinaryNinja::PossibleValueSet> BINARYNINJAUIAPI getPossibleValueSetForToken(View* view, BinaryViewRef data, ArchitectureRef arch,
FunctionRef func, HighlightTokenState token, size_t instrIdx);
std::optional<BinaryNinja::PossibleValueSet> BINARYNINJAUIAPI getPossibleValueSetForILToken(View* view, HighlightTokenState token);
std::optional<uint64_t> BINARYNINJAUIAPI getAddressOfILTokenExpr(View* view, HighlightTokenState token);
void BINARYNINJAUIAPI setCallStackAdjustment(QWidget* parent, FunctionRef func, ArchitectureRef arch, uint64_t instrAddress);
// Resolve the address of the call instruction that the user is currently on,
// given the active function, architecture, IL view, highlight, and cursor
// position. This is the address of the calling instruction itself, not the
// call target.
std::optional<uint64_t> BINARYNINJAUIAPI getCallInstructionAddress(
FunctionRef function,
ArchitectureRef arch,
BNFunctionGraphType viewType,
const HighlightTokenState& highlight,
uint64_t cursorAddress,
size_t cursorInstrIndex);
template <typename T>
std::optional<T> visitILInstructionForToken(View* view, const HighlightTokenState& token,
const std::function<std::optional<T>(BinaryNinja::LowLevelILInstruction&)>& llil,
const std::function<std::optional<T>(BinaryNinja::MediumLevelILInstruction&)>& mlil,
const std::function<std::optional<T>(BinaryNinja::HighLevelILInstruction&)>& hlil)
{
if (token.token.exprIndex == BN_INVALID_EXPR)
return {};
BNFunctionGraphType type = view->getILViewType().type;
switch (type)
{
case InvalidILViewType:
case NormalFunctionGraph:
break;
case LiftedILFunctionGraph:
case MappedMediumLevelILFunctionGraph:
case MappedMediumLevelILSSAFormFunctionGraph:
// omitted because I don't know how to get to _exactly_ the right mapped mlil
// function from the View frame -- if we go through the Function object we may
// not get the same IL function object the token corresponds to due to an update
break;
case LowLevelILFunctionGraph:
case LowLevelILSSAFormFunctionGraph:
{
LowLevelILFunctionRef llilFunc = view->getCurrentLowLevelILFunction();
if (llilFunc && type == LowLevelILSSAFormFunctionGraph)
llilFunc = llilFunc->GetSSAForm();
if (!llilFunc)
break;
if (token.token.exprIndex >= llilFunc->GetExprCount())
{
FunctionRef func = llilFunc->GetFunction();
uint64_t start = func ? func->GetStart() : 0;
BinaryNinja::LogErrorF("Invalid LowLevelIL token exprIndex {} in {} of {:x}", token.token.exprIndex, type, start);
break;
}
BinaryNinja::LowLevelILInstruction instr = llilFunc->GetExpr(token.token.exprIndex);
if (instr.instructionIndex >= llilFunc->GetInstructionCount())
{
FunctionRef func = llilFunc->GetFunction();
uint64_t start = func ? func->GetStart() : 0;
BinaryNinja::LogErrorF("Invalid LowLevelIL token exprIndex {} in {} of {:x} (reported instrIndex {})", token.token.exprIndex, type, start, instr.instructionIndex);
break;
}
return llil(instr);
}
case MediumLevelILFunctionGraph:
case MediumLevelILSSAFormFunctionGraph:
{
MediumLevelILFunctionRef mlilFunc = view->getCurrentMediumLevelILFunction();
if (mlilFunc && type == MediumLevelILSSAFormFunctionGraph)
mlilFunc = mlilFunc->GetSSAForm();
if (!mlilFunc)
break;
if (token.token.exprIndex >= mlilFunc->GetExprCount())
{
FunctionRef func = mlilFunc->GetFunction();
uint64_t start = func ? func->GetStart() : 0;
BinaryNinja::LogErrorF("Invalid MediumLevelIL token exprIndex {} in {} of {:x}", token.token.exprIndex, type, start);
break;
}
BinaryNinja::MediumLevelILInstruction instr = mlilFunc->GetExpr(token.token.exprIndex);
if (instr.instructionIndex >= mlilFunc->GetInstructionCount())
{
FunctionRef func = mlilFunc->GetFunction();
uint64_t start = func ? func->GetStart() : 0;
BinaryNinja::LogErrorF("Invalid MediumLevelIL token exprIndex {} in {} of {:x} (reported instrIndex {})", token.token.exprIndex, type, start, instr.instructionIndex);
break;
}
return mlil(instr);
}
case HighLevelILFunctionGraph:
case HighLevelILSSAFormFunctionGraph:
case HighLevelLanguageRepresentationFunctionGraph:
{
HighLevelILFunctionRef hlilFunc = view->getCurrentHighLevelILFunction();
if (hlilFunc && type == HighLevelILSSAFormFunctionGraph)
hlilFunc = hlilFunc->GetSSAForm();
if (!hlilFunc)
break;
if (token.token.exprIndex >= hlilFunc->GetExprCount())
{
FunctionRef func = hlilFunc->GetFunction();
uint64_t start = func ? func->GetStart() : 0;
BinaryNinja::LogErrorF("Invalid HighLevelIL token exprIndex {} in {} of {:x}", token.token.exprIndex, type, start);
break;
}
BinaryNinja::HighLevelILInstruction instr = hlilFunc->GetExpr(token.token.exprIndex);
if (instr.instructionIndex >= hlilFunc->GetInstructionCount())
{
FunctionRef func = hlilFunc->GetFunction();
uint64_t start = func ? func->GetStart() : 0;
BinaryNinja::LogErrorF("Invalid HighLevelIL token exprIndex {} in {} of {:x} (reported instrIndex {})", token.token.exprIndex, type, start, instr.instructionIndex);
break;
}
return hlil(instr);
}
default:
break;
}
return {};
}
void BINARYNINJAUIAPI showHexPreview(QWidget* parent, ViewFrame* frame, const QPoint& previewPos, BinaryViewRef data, uint64_t address);
bool BINARYNINJAUIAPI showDisassemblyPreview(QWidget* parent, ViewFrame* frame, const QPoint& previewPos,BinaryViewRef data, FunctionRef func,
const ViewLocation& location);
void BINARYNINJAUIAPI showTextTooltip(QWidget* parent, const QPoint& previewPos, const QString& text);
void BINARYNINJAUIAPI showTokenTooltip(QWidget* parent, const QPoint& previewPos,
const std::vector<std::vector<BinaryNinja::InstructionTextToken>>& lines);
// Interpret the hovered token and, if applicable, displays a tooltip or preview. If no token-driven preview matches
// and `dataflowFallbackAddress` is set, a dataflow-details tooltip is shown for that address.
void BINARYNINJAUIAPI dispatchTokenHoverPreview(View* view, const QPoint& globalPos, const HighlightTokenState& token,
FunctionRef func, uint64_t lineAddr, size_t instrIndex, const std::vector<TagRef>& lineTags,
std::optional<uint64_t> dataflowFallbackAddress);
bool BINARYNINJAUIAPI isBinaryNinjaDatabase(QFileInfo& info, QFileAccessor& accessor);
PlatformRef BINARYNINJAUIAPI getOrAskForPlatform(QWidget* parent, BinaryViewRef data);
PlatformRef BINARYNINJAUIAPI getOrAskForPlatform(QWidget* parent, PlatformRef defaultValue);
std::optional<std::string> BINARYNINJAUIAPI getStringForGraphType(BNFunctionGraphType type);
std::optional<BinaryNinja::FunctionViewType> BINARYNINJAUIAPI getGraphTypeForString(const std::string& type);
namespace fmt
{
template<typename... T>
QString qformat(format_string<T...> fmt, T&&... args)
{
return QString::fromStdString(vformat(fmt, fmt::make_format_args(args...)));
}
}
template<> struct fmt::formatter<QString>
{
format_context::iterator format(const QString& obj, format_context& ctx) const
{
return fmt::format_to(ctx.out(), "{}", obj.toStdString());
}
constexpr auto parse(format_parse_context& ctx) -> format_parse_context::iterator { return ctx.begin(); }
};
/*!
@}
*/