Skip to content

Commit 1652efd

Browse files
committed
core: initial union support with C++ API
1 parent 996ad28 commit 1652efd

9 files changed

Lines changed: 158 additions & 8 deletions

File tree

binaryninjaapi.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8764,6 +8764,12 @@ namespace BinaryNinja {
87648764
{}
87658765
};
87668766

8767+
class FieldResolutionInfo : public CoreRefCountObject<BNFieldResolutionInfo, BNNewFieldResolutionInfoReference, BNFreeFieldResolutionInfo>
8768+
{
8769+
public:
8770+
FieldResolutionInfo(BNFieldResolutionInfo* info);
8771+
};
8772+
87678773
struct QualifiedNameAndType
87688774
{
87698775
QualifiedName name;
@@ -9313,7 +9319,9 @@ namespace BinaryNinja {
93139319
Ref<Type> WithReplacedNamedTypeReference(NamedTypeReference* from, NamedTypeReference* to);
93149320

93159321
bool AddTypeMemberTokens(BinaryView* data, std::vector<InstructionTextToken>& tokens, int64_t offset,
9316-
std::vector<std::string>& nameList, size_t size = 0, bool indirect = false);
9322+
std::vector<std::string>& nameList, size_t size = 0, bool indirect = false, FieldResolutionInfo* info = nullptr);
9323+
bool EnumerateTypesForAccess(BinaryView* data, uint64_t offset, size_t size, uint8_t baseConfidence,
9324+
const std::function<void(const Confidence<Ref<Type>>& type, FieldResolutionInfo* path)>& terminal);
93179325
std::vector<TypeDefinitionLine> GetLines(const TypeContainer& types, const std::string& name,
93189326
int paddingCols = 64, bool collapsed = false, BNTokenEscapingType escaping = NoTokenEscapingType);
93199327

@@ -11247,6 +11255,11 @@ namespace BinaryNinja {
1124711255
void CreateForcedVariableVersion(const Variable& var, const ArchAndAddr& location);
1124811256
void ClearForcedVariableVersion(const Variable& var, const ArchAndAddr& location);
1124911257

11258+
void SetFieldResolutionForVariableAt(const Variable& var, const ArchAndAddr& location, FieldResolutionInfo* info);
11259+
void ClearFieldResolutionForVariableAt(const Variable& var, const ArchAndAddr& location);
11260+
Ref<FieldResolutionInfo> GetFieldResolutionForVariableAt(const Variable& var, const ArchAndAddr& location);
11261+
std::map<Variable, std::map<ArchAndAddr, Ref<FieldResolutionInfo>>> GetAllFieldResolutions();
11262+
1125011263
void RequestDebugReport(const std::string& name);
1125111264

1125211265
/*! Get the name for a given label ID

binaryninjacore.h

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,14 @@
3737
// Current ABI version for linking to the core. This is incremented any time
3838
// there are changes to the API that affect linking, including new functions,
3939
// new types, or modifications to existing functions or types.
40-
#define BN_CURRENT_CORE_ABI_VERSION 99
40+
#define BN_CURRENT_CORE_ABI_VERSION 100
4141

4242
// Minimum ABI version that is supported for loading of plugins. Plugins that
4343
// are linked to an ABI version less than this will not be able to load and
4444
// will require rebuilding. The minimum version is increased when there are
4545
// incompatible changes that break binary compatibility, such as changes to
4646
// existing types or functions.
47-
#define BN_MINIMUM_CORE_ABI_VERSION 97
47+
#define BN_MINIMUM_CORE_ABI_VERSION 100
4848

4949
#ifdef __GNUC__
5050
#ifdef BINARYNINJACORE_LIBRARY
@@ -230,6 +230,7 @@ extern "C"
230230
typedef struct BNTypeBuilder BNTypeBuilder;
231231
typedef struct BNTypeLibrary BNTypeLibrary;
232232
typedef struct BNTypeLibraryMapping BNTypeLibraryMapping;
233+
typedef struct BNFieldResolutionInfo BNFieldResolutionInfo;
233234
typedef struct BNStructure BNStructure;
234235
typedef struct BNStructureBuilder BNStructureBuilder;
235236
typedef struct BNTagType BNTagType;
@@ -2627,6 +2628,13 @@ extern "C"
26272628
BNPossibleValueSet value;
26282629
} BNUserVariableValue;
26292630

2631+
typedef struct BNVariableFieldResolutionInfo
2632+
{
2633+
BNArchitectureAndAddress location;
2634+
BNVariable var;
2635+
BNFieldResolutionInfo* info;
2636+
} BNVariableFieldResolutionInfo;
2637+
26302638
typedef enum BNFunctionUpdateType
26312639
{
26322640
UserFunctionUpdate,
@@ -5422,6 +5430,15 @@ extern "C"
54225430
BINARYNINJACOREAPI void BNCreateForcedVariableVersion(BNFunction* func, const BNVariable* var, const BNArchitectureAndAddress* defSite);
54235431
BINARYNINJACOREAPI void BNClearForcedVariableVersion(BNFunction* func, const BNVariable* var, const BNArchitectureAndAddress* defSite);
54245432

5433+
BINARYNINJACOREAPI void BNSetFieldResolutionForVariableAt(BNFunction* func, const BNVariable* var,
5434+
const BNArchitectureAndAddress* defSite, const BNFieldResolutionInfo* info);
5435+
BINARYNINJACOREAPI BNFieldResolutionInfo* BNGetFieldResolutionForVariableAt(BNFunction* func, const BNVariable* var,
5436+
const BNArchitectureAndAddress* defSite);
5437+
BINARYNINJACOREAPI BNVariableFieldResolutionInfo* BNGetAllVariableFieldResolutions(BNFunction* func, size_t* count);
5438+
BINARYNINJACOREAPI void BNFreeVariableFieldResolutions(BNVariableFieldResolutionInfo* result, size_t count);
5439+
BINARYNINJACOREAPI void BNClearFieldResolutionForVariableAt(BNFunction* func, const BNVariable* var,
5440+
const BNArchitectureAndAddress* defSite);
5441+
54255442
BINARYNINJACOREAPI void BNRequestFunctionDebugReport(BNFunction* func, const char* name);
54265443

54275444
BINARYNINJACOREAPI BNILReferenceSource* BNGetMediumLevelILVariableReferences(
@@ -6290,6 +6307,9 @@ extern "C"
62906307
BINARYNINJACOREAPI char* BNGetLanguageRepresentationFunctionAnnotationEndString(
62916308
BNLanguageRepresentationFunction* func);
62926309

6310+
BINARYNINJACOREAPI BNFieldResolutionInfo* BNNewFieldResolutionInfoReference(BNFieldResolutionInfo* info);
6311+
BINARYNINJACOREAPI void BNFreeFieldResolutionInfo(BNFieldResolutionInfo* info);
6312+
62936313
// Types
62946314
BINARYNINJACOREAPI bool BNTypesEqual(BNType* a, BNType* b);
62956315
BINARYNINJACOREAPI bool BNTypesNotEqual(BNType* a, BNType* b);
@@ -6410,10 +6430,13 @@ extern "C"
64106430
BNType* type, BNNamedTypeReference* from, BNNamedTypeReference* to);
64116431

64126432
BINARYNINJACOREAPI bool BNAddTypeMemberTokens(BNType* type, BNBinaryView* data, BNInstructionTextToken** tokens,
6413-
size_t* tokenCount, int64_t offset, char*** nameList, size_t* nameCount, size_t size, bool indirect);
6433+
size_t* tokenCount, int64_t offset, char*** nameList, size_t* nameCount, size_t size, bool indirect, BNFieldResolutionInfo* info);
64146434
BINARYNINJACOREAPI BNTypeDefinitionLine* BNGetTypeLines(BNType* type, BNTypeContainer* types, const char* name, int paddingCols, bool collapsed, BNTokenEscapingType escaping, size_t* count);
64156435
BINARYNINJACOREAPI void BNFreeTypeDefinitionLineList(BNTypeDefinitionLine* list, size_t count);
64166436

6437+
BINARYNINJACOREAPI bool BNEnumerateTypesForAccess(BNType* type, BNBinaryView* data, uint64_t offset, size_t size, uint8_t baseConfidence,
6438+
void (*terminal)(void*, BNTypeWithConfidence*, BNFieldResolutionInfo*), void* ctxt);
6439+
64176440
BINARYNINJACOREAPI BNQualifiedName BNTypeBuilderGetTypeName(BNTypeBuilder* nt);
64186441
BINARYNINJACOREAPI void BNTypeBuilderSetTypeName(BNTypeBuilder* type, BNQualifiedName* name);
64196442
BINARYNINJACOREAPI void BNTypeBuilderSetAlternateName(BNTypeBuilder* type, const char* name);

function.cpp

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2699,6 +2699,73 @@ void Function::ClearForcedVariableVersion(const Variable& var, const ArchAndAddr
26992699
}
27002700

27012701

2702+
void Function::SetFieldResolutionForVariableAt(const Variable& var, const ArchAndAddr& location, FieldResolutionInfo* info)
2703+
{
2704+
auto defSite = BNArchitectureAndAddress();
2705+
defSite.arch = location.arch->m_object;
2706+
defSite.address = location.address;
2707+
2708+
auto var_data = BNVariable();
2709+
var_data.type = var.type;
2710+
var_data.index = var.index;
2711+
var_data.storage = var.storage;
2712+
2713+
BNSetFieldResolutionForVariableAt(m_object, &var_data, &defSite, info->m_object);
2714+
}
2715+
2716+
2717+
void Function::ClearFieldResolutionForVariableAt(const Variable& var, const ArchAndAddr& location)
2718+
{
2719+
auto defSite = BNArchitectureAndAddress();
2720+
defSite.arch = location.arch->m_object;
2721+
defSite.address = location.address;
2722+
2723+
auto var_data = BNVariable();
2724+
var_data.type = var.type;
2725+
var_data.index = var.index;
2726+
var_data.storage = var.storage;
2727+
2728+
BNClearFieldResolutionForVariableAt(m_object, &var_data, &defSite);
2729+
}
2730+
2731+
2732+
Ref<FieldResolutionInfo> Function::GetFieldResolutionForVariableAt(const Variable& var, const ArchAndAddr& location)
2733+
{
2734+
auto defSite = BNArchitectureAndAddress();
2735+
defSite.arch = location.arch->m_object;
2736+
defSite.address = location.address;
2737+
2738+
auto var_data = BNVariable();
2739+
var_data.type = var.type;
2740+
var_data.index = var.index;
2741+
var_data.storage = var.storage;
2742+
2743+
BNFieldResolutionInfo* result = BNGetFieldResolutionForVariableAt(m_object, &var_data, &defSite);
2744+
return result ? new FieldResolutionInfo(result) : nullptr;
2745+
}
2746+
2747+
2748+
std::map<Variable, std::map<ArchAndAddr, Ref<FieldResolutionInfo>>> Function::GetAllFieldResolutions()
2749+
{
2750+
map<Variable, map<ArchAndAddr, Ref<FieldResolutionInfo>>> result;
2751+
2752+
size_t count;
2753+
BNVariableFieldResolutionInfo* info = BNGetAllVariableFieldResolutions(m_object, &count);
2754+
2755+
for (size_t i = 0; i < count; i++)
2756+
{
2757+
Variable var(info[i].var.type, info[i].var.index, info[i].var.storage);
2758+
ArchAndAddr location(new CoreArchitecture(info[i].location.arch), info[i].location.address);
2759+
Ref<FieldResolutionInfo> fieldInfo(new FieldResolutionInfo(BNNewFieldResolutionInfoReference(info[i].info)));
2760+
2761+
result[var][location] = fieldInfo;
2762+
}
2763+
2764+
BNFreeVariableFieldResolutions(info, count);
2765+
return result;
2766+
}
2767+
2768+
27022769
void Function::RequestDebugReport(const string& name)
27032770
{
27042771
BNRequestFunctionDebugReport(m_object, name.c_str());

type.cpp

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,12 @@ void TypeDefinitionLine::FreeTypeDefinitionLineList(BNTypeDefinitionLine* lines,
515515
}
516516

517517

518+
FieldResolutionInfo::FieldResolutionInfo(BNFieldResolutionInfo* info)
519+
{
520+
m_object = info;
521+
}
522+
523+
518524
BaseStructure::BaseStructure(NamedTypeReference* _type, uint64_t _offset, uint64_t _width) :
519525
type(_type), offset(_offset), width(_width)
520526
{}
@@ -1274,16 +1280,16 @@ Ref<Type> Type::WithReplacedNamedTypeReference(NamedTypeReference* from, NamedTy
12741280

12751281

12761282
bool Type::AddTypeMemberTokens(BinaryView* data, vector<InstructionTextToken>& tokens, int64_t offset,
1277-
vector<string>& nameList, size_t size, bool indirect)
1283+
vector<string>& nameList, size_t size, bool indirect, FieldResolutionInfo* info)
12781284
{
12791285
size_t tokenCount;
12801286
BNInstructionTextToken* list;
12811287

12821288
size_t nameCount;
12831289
char** names = nullptr;
12841290

1285-
if (!BNAddTypeMemberTokens(
1286-
m_object, data->GetObject(), &list, &tokenCount, offset, &names, &nameCount, size, indirect))
1291+
if (!BNAddTypeMemberTokens(m_object, data->GetObject(), &list, &tokenCount,
1292+
offset, &names, &nameCount, size, indirect, info ? info->m_object : nullptr))
12871293
return false;
12881294

12891295
vector<InstructionTextToken> newTokens =
@@ -1300,6 +1306,30 @@ bool Type::AddTypeMemberTokens(BinaryView* data, vector<InstructionTextToken>& t
13001306
return true;
13011307
}
13021308

1309+
struct EnumerateTypesForAccessCallbackInfo
1310+
{
1311+
const std::function<void(const Confidence<Ref<Type>>& type, FieldResolutionInfo* path)>* callback;
1312+
};
1313+
1314+
1315+
static void EnumerateTypesForAccessCallback(void* ctxt, BNTypeWithConfidence* tc, BNFieldResolutionInfo* info)
1316+
{
1317+
EnumerateTypesForAccessCallbackInfo* enumerateFunc = (EnumerateTypesForAccessCallbackInfo *) ctxt;
1318+
1319+
Confidence<Ref<Type>> typeRef(tc->type ? new Type(BNNewTypeReference(tc->type)) : nullptr, tc->confidence);
1320+
Ref<FieldResolutionInfo> path = new FieldResolutionInfo(BNNewFieldResolutionInfoReference(info));
1321+
1322+
(*enumerateFunc->callback)(typeRef, path);
1323+
}
1324+
1325+
bool Type::EnumerateTypesForAccess(BinaryView* data, uint64_t offset, size_t size, uint8_t baseConfidence,
1326+
const std::function<void(const Confidence<Ref<Type>>& type, FieldResolutionInfo* path)>& terminal)
1327+
{
1328+
EnumerateTypesForAccessCallbackInfo callbackInfo = { &terminal };
1329+
return BNEnumerateTypesForAccess(m_object, data->GetObject(), offset, size, baseConfidence,
1330+
EnumerateTypesForAccessCallback, &callbackInfo);
1331+
}
1332+
13031333

13041334
std::vector<TypeDefinitionLine> Type::GetLines(const TypeContainer& types, const std::string& name,
13051335
int paddingCols, bool collapsed, BNTokenEscapingType escaping)

ui/commands.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,16 @@ bool BINARYNINJAUIAPI eligibleToForceVariableVersion(View* parent, HighlightToke
4747
bool BINARYNINJAUIAPI clearVariableVersion(View* parent, HighlightTokenState& highlight);
4848
bool BINARYNINJAUIAPI eligibleToClearVariableVersion(View* parent, HighlightTokenState& highlight);
4949

50+
struct BINARYNINJAUIAPI FieldResolutionState
51+
{
52+
std::vector<std::pair<std::string, FieldResolutionInfoRef>> goodFieldResolutions = {};
53+
std::vector<std::pair<std::string, FieldResolutionInfoRef>> badFieldResolutions = {};
54+
55+
size_t registeredGoodFieldResolutions = 0;
56+
size_t registeredBadFieldResolutions = 0;
57+
58+
void bindDynamicActions(View* view, HighlightTokenState& highlight);
59+
};
5060

5161
bool BINARYNINJAUIAPI getEnumSelection(QWidget* parent, BinaryViewRef data, FunctionRef func, uint64_t constValue,
5262
TypeRef& selectedEnum, bool checkValue, bool canTruncate);

ui/flowgraphwidget.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "menus.h"
99
#include "uicontext.h"
1010
#include "commentdialog.h"
11+
#include "commands.h"
1112
#include "instructionedit.h"
1213

1314
/*!
@@ -147,6 +148,8 @@ class BINARYNINJAUIAPI FlowGraphWidget :
147148
FlowGraphRef m_recenterWithGraph;
148149
int m_recenterXofs, m_recenterYofs;
149150

151+
FieldResolutionState m_fieldResolution;
152+
150153
static int m_layoutCompleteEventType;
151154
static int m_updateCompleteEventType;
152155

ui/linearview.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "uicontext.h"
1616
#include "instructionedit.h"
1717
#include "ilchooser.h"
18+
#include "commands.h"
1819
#include <assembledialog.h>
1920

2021
#define LINEAR_VIEW_UPDATE_CHECK_INTERVAL 200
@@ -244,6 +245,8 @@ class BINARYNINJAUIAPI LinearView : public QAbstractScrollArea, public View, pub
244245

245246
std::set<std::string> m_layers;
246247

248+
FieldResolutionState m_fieldResolution;
249+
247250
void setTopToAddress(uint64_t addr);
248251
void setTopToOrderingIndex(uint64_t idx);
249252
void refreshLines(size_t lineOffset = 0, bool refreshUIContext = true);

ui/uitypes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ typedef BinaryNinja::Ref<BinaryNinja::DownloadProvider> DownloadProviderRef;
7777
typedef BinaryNinja::Ref<BinaryNinja::Enumeration> EnumerationRef;
7878
typedef BinaryNinja::Ref<BinaryNinja::ExternalLibrary> ExternalLibraryRef;
7979
typedef BinaryNinja::Ref<BinaryNinja::ExternalLocation> ExternalLocationRef;
80+
typedef BinaryNinja::Ref<BinaryNinja::FieldResolutionInfo> FieldResolutionInfoRef;
8081
typedef BinaryNinja::Ref<BinaryNinja::FileMetadata> FileMetadataRef;
8182
typedef BinaryNinja::Ref<BinaryNinja::FlowGraph> FlowGraphRef;
8283
typedef BinaryNinja::Ref<BinaryNinja::FlowGraphLayoutRequest> FlowGraphLayoutRequestRef;

ui/util.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ std::optional<BinaryNinja::PossibleValueSet> BINARYNINJAUIAPI getPossibleValueSe
3131
std::optional<uint64_t> BINARYNINJAUIAPI getAddressOfILTokenExpr(View* view, HighlightTokenState token);
3232

3333
template <typename T>
34-
std::optional<T> visitILInstructionForToken(View* view, HighlightTokenState token,
34+
std::optional<T> visitILInstructionForToken(View* view, const HighlightTokenState& token,
3535
const std::function<std::optional<T>(BinaryNinja::LowLevelILInstruction&)>& llil,
3636
const std::function<std::optional<T>(BinaryNinja::MediumLevelILInstruction&)>& mlil,
3737
const std::function<std::optional<T>(BinaryNinja::HighLevelILInstruction&)>& hlil)

0 commit comments

Comments
 (0)