Skip to content

Allow architecture plugins to perform basic block analysis #6792

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions architecture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <inttypes.h>
#include <vector>
#include "binaryninjaapi.h"
#include "lowlevelilinstruction.h"
#include "ffi.h"

using namespace BinaryNinja;
Expand Down Expand Up @@ -307,6 +308,15 @@ bool Architecture::GetInstructionLowLevelILCallback(
}


void Architecture::AnalyzeBasicBlocksCallback(void *ctxt, BNFunction* function,
BNBasicBlockAnalysisContext* context)
{
CallbackRef<Architecture> arch(ctxt);
Ref<Function> func(new Function(BNNewFunctionReference(function)));
arch->AnalyzeBasicBlocks(*func, *context);
}


char* Architecture::GetRegisterNameCallback(void* ctxt, uint32_t reg)
{
CallbackRef<Architecture> arch(ctxt);
Expand Down Expand Up @@ -797,6 +807,7 @@ void Architecture::Register(Architecture* arch)
callbacks.getInstructionText = GetInstructionTextCallback;
callbacks.freeInstructionText = FreeInstructionTextCallback;
callbacks.getInstructionLowLevelIL = GetInstructionLowLevelILCallback;
callbacks.analyzeBasicBlocks = AnalyzeBasicBlocksCallback;
callbacks.getRegisterName = GetRegisterNameCallback;
callbacks.getFlagName = GetFlagNameCallback;
callbacks.getFlagWriteTypeName = GetFlagWriteTypeNameCallback;
Expand Down Expand Up @@ -925,6 +936,12 @@ bool Architecture::GetInstructionLowLevelIL(const uint8_t*, uint64_t, size_t&, L
}


void Architecture::AnalyzeBasicBlocks(Function& function, BasicBlockAnalysisContext& context)
{
DefaultAnalyzeBasicBlocks(function, context);
}


string Architecture::GetRegisterName(uint32_t reg)
{
return fmt::format("r{}", reg);
Expand Down Expand Up @@ -1485,6 +1502,12 @@ bool CoreArchitecture::GetInstructionLowLevelIL(const uint8_t* data, uint64_t ad
}


void CoreArchitecture::AnalyzeBasicBlocks(Function& function, BasicBlockAnalysisContext& context)
{
BNArchitectureAnalyzeBasicBlocks(m_object, function.GetObject(), &context);
}


string CoreArchitecture::GetRegisterName(uint32_t reg)
{
char* name = BNGetArchitectureRegisterName(m_object, reg);
Expand Down
81 changes: 81 additions & 0 deletions basicblock.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,12 @@ uint64_t BasicBlock::GetStart() const
}


void BasicBlock::SetEnd(uint64_t end)
{
BNSetBasicBlockEnd(m_object, end);
}


uint64_t BasicBlock::GetEnd() const
{
return BNGetBasicBlockEnd(m_object);
Expand Down Expand Up @@ -385,6 +391,81 @@ bool BasicBlock::HasUndeterminedOutgoingEdges() const
}


bool BasicBlock::HasInvalidInstructions() const
{
return BNBasicBlockHasInvalidInstructions(m_object);
}


void BasicBlock::SetHasInvalidInstructions(bool value)
{
BNBasicBlockSetHasInvalidInstructions(m_object, value);
}


void BasicBlock::AddPendingOutgoingEdge(BNBranchType type, uint64_t addr, Ref<Architecture> arch, bool fallThrough)
{
BNBasicBlockAddPendingOutgoingEdge(m_object, type, addr, arch ? arch->GetObject() : nullptr, fallThrough);
}


vector<PendingBasicBlockEdge> BasicBlock::GetPendingOutgoingEdges() const
{
size_t count;
BNPendingBasicBlockEdge* edges = BNGetBasicBlockPendingOutgoingEdges(m_object, &count);
vector<PendingBasicBlockEdge> result;
result.reserve(count);
for (size_t i = 0; i < count; i++)
{
PendingBasicBlockEdge edge;
edge.type = edges[i].type;
edge.arch = edges[i].arch ? new CoreArchitecture(edges[i].arch) : nullptr;
edge.target = edges[i].target;
edge.fallThrough = edges[i].fallThrough;
result.push_back(edge);
}

BNFreePendingBasicBlockEdgeList(edges);
return result;
}


void BasicBlock::ClearPendingOutgoingEdges()
{
BNClearBasicBlockPendingOutgoingEdges(m_object);
}


void BasicBlock::SetUndeterminedOutgoingEdges(bool value)
{
BNBasicBlockSetUndeterminedOutgoingEdges(m_object, value);
}


const uint8_t* BasicBlock::GetInstructionData(uint64_t addr, size_t* len) const
{
return BNBasicBlockGetInstructionData(m_object, addr, len);
}


void BasicBlock::AddInstructionData(const void* data, size_t len)
{
BNBasicBlockAddInstructionData(m_object, data, len);
}


void BasicBlock::SetFallThroughToFunction(bool value)
{
BNBasicBlockSetFallThroughToFunction(m_object, value);
}


bool BasicBlock::IsFallThroughToFunction() const
{
return BNBasicBlockIsFallThroughToFunction(m_object);
}


bool BasicBlock::CanExit() const
{
return BNBasicBlockCanExit(m_object);
Expand Down
Loading
Loading