diff options
| author | Brandon Miller <brandon@vector35.com> | 2025-04-25 13:30:45 -0400 |
|---|---|---|
| committer | Ryan Snyder <ryan@vector35.com> | 2025-06-23 13:44:12 -0400 |
| commit | b079d1a1e19151f5c39de84c2e1e6cc6a91abc74 (patch) | |
| tree | 8cf27224630b690fcfdfd490ee43ec1cd56fc9b6 /binaryninjaapi.h | |
| parent | 76215b86ff629da58aa94d4cf4093d2e67017412 (diff) | |
Perform BB analysis from Architecture C++ API
This commit moves AnalyzeBasicBlocks from the binary ninja core to the
API and allows architecture plugins to optionally override
AnalyzeBasicBlocks for a custom implementation
Supply ABB inputs in BNBasicBlockAnalysisContext
Register default analyze basic blocks callback
This allows the nanomips and rust core architecture plugins to work
again while using the C++ API DefaultAnalyzeBasicBlocks
Use default ABB from Python plugins
Fix bug in API ArchAndAddr operator overload
Python APIs for basic block analysis
Diffstat (limited to 'binaryninjaapi.h')
| -rw-r--r-- | binaryninjaapi.h | 162 |
1 files changed, 159 insertions, 3 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h index 920d2eb0..74d30d92 100644 --- a/binaryninjaapi.h +++ b/binaryninjaapi.h @@ -359,6 +359,10 @@ namespace BinaryNinja { bool operator<(const Ref<T>& obj) const { return T::GetObject(m_obj) < T::GetObject(obj.m_obj); } + bool operator>(const T* obj) const { return T::GetObject(m_obj) > T::GetObject(obj); } + + bool operator>(const Ref<T>& obj) const { return T::GetObject(m_obj) > T::GetObject(obj.m_obj); } + T* GetPtr() const { return m_obj; } }; @@ -579,6 +583,7 @@ namespace BinaryNinja { class FlowGraph; class ReportCollection; struct FormInputField; + struct ArchAndAddr; /*! Logs to the error console with the given BNLogLevel. @@ -5303,6 +5308,13 @@ namespace BinaryNinja { */ void AbortAnalysis(); + + /*! Check whether analysis is currently running + + \return true if analysis is aborted, false otherwise + */ + bool AnalysisIsAborted() const; + /*! Define a DataVariable at a given address with a set type \param addr virtual address to define the DataVariable at @@ -6899,6 +6911,17 @@ namespace BinaryNinja { bool GetNewAutoFunctionAnalysisSuppressed(); void SetNewAutoFunctionAnalysisSuppressed(bool suppress); + /*! Determine whether the target analysis should be skipped for a given source function and target address + + \param source Source function and address + \param sourceFunc Function at the source address + \param sourceEnd End address of the source function + \param target Target address to analyze + \return Whether the target analysis should be skipped + */ + bool ShouldSkipTargetAnalysis(const ArchAndAddr& source, Ref<Function> sourceFunc, + uint64_t sourceEnd, const ArchAndAddr& target); + /*! Returns a list of namespaces for the current BinaryView \return A list of namespaces for the current BinaryView @@ -8050,6 +8073,7 @@ namespace BinaryNinja { class RelocationHandler; typedef size_t ExprId; + typedef BNBasicBlockAnalysisContext BasicBlockAnalysisContext; /*! The Architecture class is the base class for all CPU architectures. This provides disassembly, assembly, patching, and IL translation lifting for a given architecture. @@ -8078,6 +8102,7 @@ namespace BinaryNinja { static void FreeInstructionTextCallback(BNInstructionTextToken* tokens, size_t count); static bool GetInstructionLowLevelILCallback( void* ctxt, const uint8_t* data, uint64_t addr, size_t* len, BNLowLevelILFunction* il); + static void AnalyzeBasicBlocksCallback(void *ctxt, BNFunction* function, BNBasicBlockAnalysisContext* context); static char* GetRegisterNameCallback(void* ctxt, uint32_t reg); static char* GetFlagNameCallback(void* ctxt, uint32_t flag); static char* GetFlagWriteTypeNameCallback(void* ctxt, uint32_t flags); @@ -8150,6 +8175,15 @@ namespace BinaryNinja { */ static void Register(Architecture* arch); + static void DefaultAnalyzeBasicBlocksCallback(BNFunction* function, BNBasicBlockAnalysisContext* context); + + /*! Default implementation of AnalyzeBasicBlocks + + \param function Function to analyze + \param context Context for the analysis + */ + static void DefaultAnalyzeBasicBlocks(Function& function, BasicBlockAnalysisContext& context); + /*! Get an Architecture by name \param name Name of the architecture @@ -8248,6 +8282,13 @@ namespace BinaryNinja { */ virtual bool GetInstructionLowLevelIL(const uint8_t* data, uint64_t addr, size_t& len, LowLevelILFunction& il); + /*! Analyze the basic blocks of a function + + \param function Function to analyze + \param context Context for the analysis + */ + virtual void AnalyzeBasicBlocks(Function& function, BasicBlockAnalysisContext& context); + /*! Gets a register name from a register index. \param reg Register index @@ -8526,7 +8567,6 @@ namespace BinaryNinja { \return Whether the conversion was successful */ virtual bool SkipAndReturnValue(uint8_t* data, uint64_t addr, size_t len, uint64_t value); - void RegisterFunctionRecognizer(FunctionRecognizer* recog); void RegisterRelocationHandler(const std::string& viewName, RelocationHandler* handler); Ref<RelocationHandler> GetRelocationHandler(const std::string& viewName); @@ -8642,6 +8682,7 @@ namespace BinaryNinja { const uint8_t* data, uint64_t addr, size_t& len, std::vector<InstructionTextToken>& result) override; virtual bool GetInstructionLowLevelIL( const uint8_t* data, uint64_t addr, size_t& len, LowLevelILFunction& il) override; + virtual void AnalyzeBasicBlocks(Function& function, BasicBlockAnalysisContext& context) override; virtual std::string GetRegisterName(uint32_t reg) override; virtual std::string GetFlagName(uint32_t flag) override; virtual std::string GetFlagWriteTypeName(uint32_t flags) override; @@ -10486,6 +10527,17 @@ namespace BinaryNinja { /*! \ingroup basicblocks */ + struct PendingBasicBlockEdge + { + BNBranchType type; + Ref<Architecture> arch; + uint64_t target; + bool fallThrough; + }; + + /*! + \ingroup basicblocks + */ class BasicBlock : public CoreRefCountObject<BNBasicBlock, BNNewBasicBlockReference, BNFreeBasicBlock> { public: @@ -10509,6 +10561,13 @@ namespace BinaryNinja { */ uint64_t GetStart() const; + + /*! Set the end of a basic block + + \param end Ending address of the basic block + */ + void SetEnd(uint64_t end); + /*! Ending address of the basic block \return Ending address of the basic block @@ -10545,6 +10604,72 @@ namespace BinaryNinja { */ bool HasUndeterminedOutgoingEdges() const; + + /*! Whether the basic block has invalid instructions + + \return true if the basic block has invalid instructions, false otherwise + */ + bool HasInvalidInstructions() const; + + /*! Set whether the basic block has invalid instructions + + \param value true if the basic block has invalid instructions, false otherwise + */ + void SetHasInvalidInstructions(bool value); + + /*! Add a pending outgoing edge to this basic block + + \param type Type of the branch + \param addr Address of the target basic block + \param arch Optional architecture for the target basic block, default is nullptr + \param fallThrough Whether this is a fall-through edge, default false + */ + void AddPendingOutgoingEdge(BNBranchType type, uint64_t addr, Ref<Architecture> arch = nullptr, + bool fallThrough = false); + + /*! Get a list of pending outgoing edges for this basic block + + \return List of pending outgoing edges + */ + std::vector<PendingBasicBlockEdge> GetPendingOutgoingEdges() const; + + /*! Clear the pending outgoing edges for this basic block + */ + void ClearPendingOutgoingEdges(); + + /*! Set whether basic block has undetermined outgoing edges + + \param value Whether basic block has undetermined outgoing edges + */ + void SetUndeterminedOutgoingEdges(bool value); + + /*! Get the instruction data for a specific address in this basic block + + \param addr Address of the instruction + \param len Pointer to a size_t variable to store the length of the instruction data + \return Pointer to the instruction data + */ + const uint8_t* GetInstructionData(uint64_t addr, size_t* len) const; + + /*! Add instruction data to the basic block + + \param data Pointer to the instruction data + \param len Length of the instruction data + */ + void AddInstructionData(const void* data, size_t len); + + /*! Set whether the basic blocks falls through to a function + + \param value Whether the basic block falls through to a function + */ + void SetFallThroughToFunction(bool value); + + /*! Determine whether the basic block falls through to a function + + \return Whether basic block falls through to a function + */ + bool IsFallThroughToFunction() const; + /*! Whether basic block can return or is tagged as 'No Return' \return Whether basic block can return or is tagged as 'No Return' @@ -10791,12 +10916,14 @@ namespace BinaryNinja { address = a.address; return *this; } - bool operator==(const ArchAndAddr& a) const { return (arch == a.arch) && (address == a.address); } + bool operator==(const ArchAndAddr& a) const { + return (arch == a.arch) && (address == a.address); + } bool operator<(const ArchAndAddr& a) const { if (arch < a.arch) return true; - if (arch > a.arch) + if (a.arch < arch) return false; return address < a.address; } @@ -10936,6 +11063,24 @@ namespace BinaryNinja { */ std::vector<Ref<BasicBlock>> GetBasicBlocks() const; + /*! Create a new basic block for this function + + \param arch Architecture for the basic block + \param addr Address of the basic block + \return The new BasicBlock + */ + Ref<BasicBlock> CreateBasicBlock(Architecture* arch, uint64_t addr); + + /*! Add a basic block to the function analysis basic block list + + \param block The BasicBlock to add + */ + void AddBasicBlock(Ref<BasicBlock> block); + + /*! Finalize basic block list for this function + */ + void FinalizeBasicBlocks(); + /*! Get the basic block an address is located in \param arch Architecture for the basic block @@ -11266,6 +11411,17 @@ namespace BinaryNinja { std::vector<IndirectBranchInfo> GetIndirectBranches(); std::vector<IndirectBranchInfo> GetIndirectBranchesAt(Architecture* arch, uint64_t addr); + void AddDirectCodeReference(const ArchAndAddr& source, uint64_t target); + void AddDirectNoReturnCall(const ArchAndAddr& location); + bool LocationHasNoReturnCalls(const ArchAndAddr& location) const; + Ref<Function> GetCalleeForAnalysis(Ref<Platform> platform, uint64_t addr, bool exact); + void AddTempOutgoingReference(Ref<Function> target); + bool HasTempOutgoingReference(Ref<Function> target) const; + void AddTempIncomingReference(Ref<Function> source); + + bool GetContextualFunctionReturn(const ArchAndAddr& location, bool& value) const; + void SetContextualFunctionReturn(const ArchAndAddr& location, bool value); + std::vector<uint64_t> GetUnresolvedIndirectBranches(); bool HasUnresolvedIndirectBranches(); |
