diff options
| -rw-r--r-- | binaryninjaapi.h | 15 | ||||
| -rw-r--r-- | binaryninjacore.h | 29 | ||||
| -rw-r--r-- | function.cpp | 67 | ||||
| -rw-r--r-- | type.cpp | 36 | ||||
| -rw-r--r-- | ui/commands.h | 10 | ||||
| -rw-r--r-- | ui/flowgraphwidget.h | 3 | ||||
| -rw-r--r-- | ui/linearview.h | 3 | ||||
| -rw-r--r-- | ui/uitypes.h | 1 | ||||
| -rw-r--r-- | ui/util.h | 2 |
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()); @@ -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; @@ -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) |
