summaryrefslogtreecommitdiff
path: root/binaryninjaapi.h
diff options
context:
space:
mode:
authorBrandon Miller <brandon@vector35.com>2025-04-25 13:30:45 -0400
committerRyan Snyder <ryan@vector35.com>2025-06-23 13:44:12 -0400
commitb079d1a1e19151f5c39de84c2e1e6cc6a91abc74 (patch)
tree8cf27224630b690fcfdfd490ee43ec1cd56fc9b6 /binaryninjaapi.h
parent76215b86ff629da58aa94d4cf4093d2e67017412 (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.h162
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();