summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--binaryninjaapi.h15
-rw-r--r--binaryninjacore.h29
-rw-r--r--function.cpp67
-rw-r--r--type.cpp36
-rw-r--r--ui/commands.h10
-rw-r--r--ui/flowgraphwidget.h3
-rw-r--r--ui/linearview.h3
-rw-r--r--ui/uitypes.h1
-rw-r--r--ui/util.h2
9 files changed, 158 insertions, 8 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index 6b1d268e..15b62e25 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -8764,6 +8764,12 @@ namespace BinaryNinja {
{}
};
+ class FieldResolutionInfo : public CoreRefCountObject<BNFieldResolutionInfo, BNNewFieldResolutionInfoReference, BNFreeFieldResolutionInfo>
+ {
+ public:
+ FieldResolutionInfo(BNFieldResolutionInfo* info);
+ };
+
struct QualifiedNameAndType
{
QualifiedName name;
@@ -9313,7 +9319,9 @@ namespace BinaryNinja {
Ref<Type> WithReplacedNamedTypeReference(NamedTypeReference* from, NamedTypeReference* to);
bool AddTypeMemberTokens(BinaryView* data, std::vector<InstructionTextToken>& tokens, int64_t offset,
- std::vector<std::string>& nameList, size_t size = 0, bool indirect = false);
+ std::vector<std::string>& nameList, size_t size = 0, bool indirect = false, FieldResolutionInfo* info = nullptr);
+ bool EnumerateTypesForAccess(BinaryView* data, uint64_t offset, size_t size, uint8_t baseConfidence,
+ const std::function<void(const Confidence<Ref<Type>>& type, FieldResolutionInfo* path)>& terminal);
std::vector<TypeDefinitionLine> GetLines(const TypeContainer& types, const std::string& name,
int paddingCols = 64, bool collapsed = false, BNTokenEscapingType escaping = NoTokenEscapingType);
@@ -11247,6 +11255,11 @@ namespace BinaryNinja {
void CreateForcedVariableVersion(const Variable& var, const ArchAndAddr& location);
void ClearForcedVariableVersion(const Variable& var, const ArchAndAddr& location);
+ void SetFieldResolutionForVariableAt(const Variable& var, const ArchAndAddr& location, FieldResolutionInfo* info);
+ void ClearFieldResolutionForVariableAt(const Variable& var, const ArchAndAddr& location);
+ Ref<FieldResolutionInfo> GetFieldResolutionForVariableAt(const Variable& var, const ArchAndAddr& location);
+ std::map<Variable, std::map<ArchAndAddr, Ref<FieldResolutionInfo>>> GetAllFieldResolutions();
+
void RequestDebugReport(const std::string& name);
/*! Get the name for a given label ID
diff --git a/binaryninjacore.h b/binaryninjacore.h
index 6104e71a..8dbda6fe 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -37,14 +37,14 @@
// Current ABI version for linking to the core. This is incremented any time
// there are changes to the API that affect linking, including new functions,
// new types, or modifications to existing functions or types.
-#define BN_CURRENT_CORE_ABI_VERSION 99
+#define BN_CURRENT_CORE_ABI_VERSION 100
// Minimum ABI version that is supported for loading of plugins. Plugins that
// are linked to an ABI version less than this will not be able to load and
// will require rebuilding. The minimum version is increased when there are
// incompatible changes that break binary compatibility, such as changes to
// existing types or functions.
-#define BN_MINIMUM_CORE_ABI_VERSION 97
+#define BN_MINIMUM_CORE_ABI_VERSION 100
#ifdef __GNUC__
#ifdef BINARYNINJACORE_LIBRARY
@@ -230,6 +230,7 @@ extern "C"
typedef struct BNTypeBuilder BNTypeBuilder;
typedef struct BNTypeLibrary BNTypeLibrary;
typedef struct BNTypeLibraryMapping BNTypeLibraryMapping;
+ typedef struct BNFieldResolutionInfo BNFieldResolutionInfo;
typedef struct BNStructure BNStructure;
typedef struct BNStructureBuilder BNStructureBuilder;
typedef struct BNTagType BNTagType;
@@ -2627,6 +2628,13 @@ extern "C"
BNPossibleValueSet value;
} BNUserVariableValue;
+ typedef struct BNVariableFieldResolutionInfo
+ {
+ BNArchitectureAndAddress location;
+ BNVariable var;
+ BNFieldResolutionInfo* info;
+ } BNVariableFieldResolutionInfo;
+
typedef enum BNFunctionUpdateType
{
UserFunctionUpdate,
@@ -5422,6 +5430,15 @@ extern "C"
BINARYNINJACOREAPI void BNCreateForcedVariableVersion(BNFunction* func, const BNVariable* var, const BNArchitectureAndAddress* defSite);
BINARYNINJACOREAPI void BNClearForcedVariableVersion(BNFunction* func, const BNVariable* var, const BNArchitectureAndAddress* defSite);
+ BINARYNINJACOREAPI void BNSetFieldResolutionForVariableAt(BNFunction* func, const BNVariable* var,
+ const BNArchitectureAndAddress* defSite, const BNFieldResolutionInfo* info);
+ BINARYNINJACOREAPI BNFieldResolutionInfo* BNGetFieldResolutionForVariableAt(BNFunction* func, const BNVariable* var,
+ const BNArchitectureAndAddress* defSite);
+ BINARYNINJACOREAPI BNVariableFieldResolutionInfo* BNGetAllVariableFieldResolutions(BNFunction* func, size_t* count);
+ BINARYNINJACOREAPI void BNFreeVariableFieldResolutions(BNVariableFieldResolutionInfo* result, size_t count);
+ BINARYNINJACOREAPI void BNClearFieldResolutionForVariableAt(BNFunction* func, const BNVariable* var,
+ const BNArchitectureAndAddress* defSite);
+
BINARYNINJACOREAPI void BNRequestFunctionDebugReport(BNFunction* func, const char* name);
BINARYNINJACOREAPI BNILReferenceSource* BNGetMediumLevelILVariableReferences(
@@ -6290,6 +6307,9 @@ extern "C"
BINARYNINJACOREAPI char* BNGetLanguageRepresentationFunctionAnnotationEndString(
BNLanguageRepresentationFunction* func);
+ BINARYNINJACOREAPI BNFieldResolutionInfo* BNNewFieldResolutionInfoReference(BNFieldResolutionInfo* info);
+ BINARYNINJACOREAPI void BNFreeFieldResolutionInfo(BNFieldResolutionInfo* info);
+
// Types
BINARYNINJACOREAPI bool BNTypesEqual(BNType* a, BNType* b);
BINARYNINJACOREAPI bool BNTypesNotEqual(BNType* a, BNType* b);
@@ -6410,10 +6430,13 @@ extern "C"
BNType* type, BNNamedTypeReference* from, BNNamedTypeReference* to);
BINARYNINJACOREAPI bool BNAddTypeMemberTokens(BNType* type, BNBinaryView* data, BNInstructionTextToken** tokens,
- size_t* tokenCount, int64_t offset, char*** nameList, size_t* nameCount, size_t size, bool indirect);
+ size_t* tokenCount, int64_t offset, char*** nameList, size_t* nameCount, size_t size, bool indirect, BNFieldResolutionInfo* info);
BINARYNINJACOREAPI BNTypeDefinitionLine* BNGetTypeLines(BNType* type, BNTypeContainer* types, const char* name, int paddingCols, bool collapsed, BNTokenEscapingType escaping, size_t* count);
BINARYNINJACOREAPI void BNFreeTypeDefinitionLineList(BNTypeDefinitionLine* list, size_t count);
+ BINARYNINJACOREAPI bool BNEnumerateTypesForAccess(BNType* type, BNBinaryView* data, uint64_t offset, size_t size, uint8_t baseConfidence,
+ void (*terminal)(void*, BNTypeWithConfidence*, BNFieldResolutionInfo*), void* ctxt);
+
BINARYNINJACOREAPI BNQualifiedName BNTypeBuilderGetTypeName(BNTypeBuilder* nt);
BINARYNINJACOREAPI void BNTypeBuilderSetTypeName(BNTypeBuilder* type, BNQualifiedName* name);
BINARYNINJACOREAPI void BNTypeBuilderSetAlternateName(BNTypeBuilder* type, const char* name);
diff --git a/function.cpp b/function.cpp
index c07d8ecb..e4cdeacc 100644
--- a/function.cpp
+++ b/function.cpp
@@ -2699,6 +2699,73 @@ void Function::ClearForcedVariableVersion(const Variable& var, const ArchAndAddr
}
+void Function::SetFieldResolutionForVariableAt(const Variable& var, const ArchAndAddr& location, FieldResolutionInfo* info)
+{
+ auto defSite = BNArchitectureAndAddress();
+ defSite.arch = location.arch->m_object;
+ defSite.address = location.address;
+
+ auto var_data = BNVariable();
+ var_data.type = var.type;
+ var_data.index = var.index;
+ var_data.storage = var.storage;
+
+ BNSetFieldResolutionForVariableAt(m_object, &var_data, &defSite, info->m_object);
+}
+
+
+void Function::ClearFieldResolutionForVariableAt(const Variable& var, const ArchAndAddr& location)
+{
+ auto defSite = BNArchitectureAndAddress();
+ defSite.arch = location.arch->m_object;
+ defSite.address = location.address;
+
+ auto var_data = BNVariable();
+ var_data.type = var.type;
+ var_data.index = var.index;
+ var_data.storage = var.storage;
+
+ BNClearFieldResolutionForVariableAt(m_object, &var_data, &defSite);
+}
+
+
+Ref<FieldResolutionInfo> Function::GetFieldResolutionForVariableAt(const Variable& var, const ArchAndAddr& location)
+{
+ auto defSite = BNArchitectureAndAddress();
+ defSite.arch = location.arch->m_object;
+ defSite.address = location.address;
+
+ auto var_data = BNVariable();
+ var_data.type = var.type;
+ var_data.index = var.index;
+ var_data.storage = var.storage;
+
+ BNFieldResolutionInfo* result = BNGetFieldResolutionForVariableAt(m_object, &var_data, &defSite);
+ return result ? new FieldResolutionInfo(result) : nullptr;
+}
+
+
+std::map<Variable, std::map<ArchAndAddr, Ref<FieldResolutionInfo>>> Function::GetAllFieldResolutions()
+{
+ map<Variable, map<ArchAndAddr, Ref<FieldResolutionInfo>>> result;
+
+ size_t count;
+ BNVariableFieldResolutionInfo* info = BNGetAllVariableFieldResolutions(m_object, &count);
+
+ for (size_t i = 0; i < count; i++)
+ {
+ Variable var(info[i].var.type, info[i].var.index, info[i].var.storage);
+ ArchAndAddr location(new CoreArchitecture(info[i].location.arch), info[i].location.address);
+ Ref<FieldResolutionInfo> fieldInfo(new FieldResolutionInfo(BNNewFieldResolutionInfoReference(info[i].info)));
+
+ result[var][location] = fieldInfo;
+ }
+
+ BNFreeVariableFieldResolutions(info, count);
+ return result;
+}
+
+
void Function::RequestDebugReport(const string& name)
{
BNRequestFunctionDebugReport(m_object, name.c_str());
diff --git a/type.cpp b/type.cpp
index 7afaf5c6..c5fc5e3b 100644
--- a/type.cpp
+++ b/type.cpp
@@ -515,6 +515,12 @@ void TypeDefinitionLine::FreeTypeDefinitionLineList(BNTypeDefinitionLine* lines,
}
+FieldResolutionInfo::FieldResolutionInfo(BNFieldResolutionInfo* info)
+{
+ m_object = info;
+}
+
+
BaseStructure::BaseStructure(NamedTypeReference* _type, uint64_t _offset, uint64_t _width) :
type(_type), offset(_offset), width(_width)
{}
@@ -1274,7 +1280,7 @@ Ref<Type> Type::WithReplacedNamedTypeReference(NamedTypeReference* from, NamedTy
bool Type::AddTypeMemberTokens(BinaryView* data, vector<InstructionTextToken>& tokens, int64_t offset,
- vector<string>& nameList, size_t size, bool indirect)
+ vector<string>& nameList, size_t size, bool indirect, FieldResolutionInfo* info)
{
size_t tokenCount;
BNInstructionTextToken* list;
@@ -1282,8 +1288,8 @@ bool Type::AddTypeMemberTokens(BinaryView* data, vector<InstructionTextToken>& t
size_t nameCount;
char** names = nullptr;
- if (!BNAddTypeMemberTokens(
- m_object, data->GetObject(), &list, &tokenCount, offset, &names, &nameCount, size, indirect))
+ if (!BNAddTypeMemberTokens(m_object, data->GetObject(), &list, &tokenCount,
+ offset, &names, &nameCount, size, indirect, info ? info->m_object : nullptr))
return false;
vector<InstructionTextToken> newTokens =
@@ -1300,6 +1306,30 @@ bool Type::AddTypeMemberTokens(BinaryView* data, vector<InstructionTextToken>& t
return true;
}
+struct EnumerateTypesForAccessCallbackInfo
+{
+ const std::function<void(const Confidence<Ref<Type>>& type, FieldResolutionInfo* path)>* callback;
+};
+
+
+static void EnumerateTypesForAccessCallback(void* ctxt, BNTypeWithConfidence* tc, BNFieldResolutionInfo* info)
+{
+ EnumerateTypesForAccessCallbackInfo* enumerateFunc = (EnumerateTypesForAccessCallbackInfo *) ctxt;
+
+ Confidence<Ref<Type>> typeRef(tc->type ? new Type(BNNewTypeReference(tc->type)) : nullptr, tc->confidence);
+ Ref<FieldResolutionInfo> path = new FieldResolutionInfo(BNNewFieldResolutionInfoReference(info));
+
+ (*enumerateFunc->callback)(typeRef, path);
+}
+
+bool Type::EnumerateTypesForAccess(BinaryView* data, uint64_t offset, size_t size, uint8_t baseConfidence,
+ const std::function<void(const Confidence<Ref<Type>>& type, FieldResolutionInfo* path)>& terminal)
+{
+ EnumerateTypesForAccessCallbackInfo callbackInfo = { &terminal };
+ return BNEnumerateTypesForAccess(m_object, data->GetObject(), offset, size, baseConfidence,
+ EnumerateTypesForAccessCallback, &callbackInfo);
+}
+
std::vector<TypeDefinitionLine> Type::GetLines(const TypeContainer& types, const std::string& name,
int paddingCols, bool collapsed, BNTokenEscapingType escaping)
diff --git a/ui/commands.h b/ui/commands.h
index 662e1d6c..c8634bf7 100644
--- a/ui/commands.h
+++ b/ui/commands.h
@@ -47,6 +47,16 @@ bool BINARYNINJAUIAPI eligibleToForceVariableVersion(View* parent, HighlightToke
bool BINARYNINJAUIAPI clearVariableVersion(View* parent, HighlightTokenState& highlight);
bool BINARYNINJAUIAPI eligibleToClearVariableVersion(View* parent, HighlightTokenState& highlight);
+struct BINARYNINJAUIAPI FieldResolutionState
+{
+ std::vector<std::pair<std::string, FieldResolutionInfoRef>> goodFieldResolutions = {};
+ std::vector<std::pair<std::string, FieldResolutionInfoRef>> badFieldResolutions = {};
+
+ size_t registeredGoodFieldResolutions = 0;
+ size_t registeredBadFieldResolutions = 0;
+
+ void bindDynamicActions(View* view, HighlightTokenState& highlight);
+};
bool BINARYNINJAUIAPI getEnumSelection(QWidget* parent, BinaryViewRef data, FunctionRef func, uint64_t constValue,
TypeRef& selectedEnum, bool checkValue, bool canTruncate);
diff --git a/ui/flowgraphwidget.h b/ui/flowgraphwidget.h
index 3d1434de..52635584 100644
--- a/ui/flowgraphwidget.h
+++ b/ui/flowgraphwidget.h
@@ -8,6 +8,7 @@
#include "menus.h"
#include "uicontext.h"
#include "commentdialog.h"
+#include "commands.h"
#include "instructionedit.h"
/*!
@@ -147,6 +148,8 @@ class BINARYNINJAUIAPI FlowGraphWidget :
FlowGraphRef m_recenterWithGraph;
int m_recenterXofs, m_recenterYofs;
+ FieldResolutionState m_fieldResolution;
+
static int m_layoutCompleteEventType;
static int m_updateCompleteEventType;
diff --git a/ui/linearview.h b/ui/linearview.h
index 727f8634..f7253e3f 100644
--- a/ui/linearview.h
+++ b/ui/linearview.h
@@ -15,6 +15,7 @@
#include "uicontext.h"
#include "instructionedit.h"
#include "ilchooser.h"
+#include "commands.h"
#include <assembledialog.h>
#define LINEAR_VIEW_UPDATE_CHECK_INTERVAL 200
@@ -244,6 +245,8 @@ class BINARYNINJAUIAPI LinearView : public QAbstractScrollArea, public View, pub
std::set<std::string> m_layers;
+ FieldResolutionState m_fieldResolution;
+
void setTopToAddress(uint64_t addr);
void setTopToOrderingIndex(uint64_t idx);
void refreshLines(size_t lineOffset = 0, bool refreshUIContext = true);
diff --git a/ui/uitypes.h b/ui/uitypes.h
index 410dde70..f950268d 100644
--- a/ui/uitypes.h
+++ b/ui/uitypes.h
@@ -77,6 +77,7 @@ typedef BinaryNinja::Ref<BinaryNinja::DownloadProvider> DownloadProviderRef;
typedef BinaryNinja::Ref<BinaryNinja::Enumeration> EnumerationRef;
typedef BinaryNinja::Ref<BinaryNinja::ExternalLibrary> ExternalLibraryRef;
typedef BinaryNinja::Ref<BinaryNinja::ExternalLocation> ExternalLocationRef;
+typedef BinaryNinja::Ref<BinaryNinja::FieldResolutionInfo> FieldResolutionInfoRef;
typedef BinaryNinja::Ref<BinaryNinja::FileMetadata> FileMetadataRef;
typedef BinaryNinja::Ref<BinaryNinja::FlowGraph> FlowGraphRef;
typedef BinaryNinja::Ref<BinaryNinja::FlowGraphLayoutRequest> FlowGraphLayoutRequestRef;
diff --git a/ui/util.h b/ui/util.h
index a7681d2f..1037528e 100644
--- a/ui/util.h
+++ b/ui/util.h
@@ -31,7 +31,7 @@ std::optional<BinaryNinja::PossibleValueSet> BINARYNINJAUIAPI getPossibleValueSe
std::optional<uint64_t> BINARYNINJAUIAPI getAddressOfILTokenExpr(View* view, HighlightTokenState token);
template <typename T>
-std::optional<T> visitILInstructionForToken(View* view, HighlightTokenState token,
+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)