Skip to content

Commit b079d1a

Browse files
zznoprssor
authored andcommitted
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
1 parent 76215b8 commit b079d1a

File tree

14 files changed

+1617
-12
lines changed

14 files changed

+1617
-12
lines changed

architecture.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include <inttypes.h>
2525
#include <vector>
2626
#include "binaryninjaapi.h"
27+
#include "lowlevelilinstruction.h"
2728
#include "ffi.h"
2829

2930
using namespace BinaryNinja;
@@ -327,6 +328,15 @@ bool Architecture::GetInstructionLowLevelILCallback(
327328
}
328329

329330

331+
void Architecture::AnalyzeBasicBlocksCallback(void *ctxt, BNFunction* function,
332+
BNBasicBlockAnalysisContext* context)
333+
{
334+
CallbackRef<Architecture> arch(ctxt);
335+
Ref<Function> func(new Function(BNNewFunctionReference(function)));
336+
arch->AnalyzeBasicBlocks(*func, *context);
337+
}
338+
339+
330340
char* Architecture::GetRegisterNameCallback(void* ctxt, uint32_t reg)
331341
{
332342
CallbackRef<Architecture> arch(ctxt);
@@ -817,6 +827,7 @@ void Architecture::Register(Architecture* arch)
817827
callbacks.getInstructionText = GetInstructionTextCallback;
818828
callbacks.freeInstructionText = FreeInstructionTextCallback;
819829
callbacks.getInstructionLowLevelIL = GetInstructionLowLevelILCallback;
830+
callbacks.analyzeBasicBlocks = AnalyzeBasicBlocksCallback;
820831
callbacks.getRegisterName = GetRegisterNameCallback;
821832
callbacks.getFlagName = GetFlagNameCallback;
822833
callbacks.getFlagWriteTypeName = GetFlagWriteTypeNameCallback;
@@ -945,6 +956,12 @@ bool Architecture::GetInstructionLowLevelIL(const uint8_t*, uint64_t, size_t&, L
945956
}
946957

947958

959+
void Architecture::AnalyzeBasicBlocks(Function& function, BasicBlockAnalysisContext& context)
960+
{
961+
DefaultAnalyzeBasicBlocks(function, context);
962+
}
963+
964+
948965
string Architecture::GetRegisterName(uint32_t reg)
949966
{
950967
return fmt::format("r{}", reg);
@@ -1505,6 +1522,12 @@ bool CoreArchitecture::GetInstructionLowLevelIL(const uint8_t* data, uint64_t ad
15051522
}
15061523

15071524

1525+
void CoreArchitecture::AnalyzeBasicBlocks(Function& function, BasicBlockAnalysisContext& context)
1526+
{
1527+
BNArchitectureAnalyzeBasicBlocks(m_object, function.GetObject(), &context);
1528+
}
1529+
1530+
15081531
string CoreArchitecture::GetRegisterName(uint32_t reg)
15091532
{
15101533
char* name = BNGetArchitectureRegisterName(m_object, reg);

basicblock.cpp

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,12 @@ uint64_t BasicBlock::GetStart() const
317317
}
318318

319319

320+
void BasicBlock::SetEnd(uint64_t end)
321+
{
322+
BNSetBasicBlockEnd(m_object, end);
323+
}
324+
325+
320326
uint64_t BasicBlock::GetEnd() const
321327
{
322328
return BNGetBasicBlockEnd(m_object);
@@ -385,6 +391,81 @@ bool BasicBlock::HasUndeterminedOutgoingEdges() const
385391
}
386392

387393

394+
bool BasicBlock::HasInvalidInstructions() const
395+
{
396+
return BNBasicBlockHasInvalidInstructions(m_object);
397+
}
398+
399+
400+
void BasicBlock::SetHasInvalidInstructions(bool value)
401+
{
402+
BNBasicBlockSetHasInvalidInstructions(m_object, value);
403+
}
404+
405+
406+
void BasicBlock::AddPendingOutgoingEdge(BNBranchType type, uint64_t addr, Ref<Architecture> arch, bool fallThrough)
407+
{
408+
BNBasicBlockAddPendingOutgoingEdge(m_object, type, addr, arch ? arch->GetObject() : nullptr, fallThrough);
409+
}
410+
411+
412+
vector<PendingBasicBlockEdge> BasicBlock::GetPendingOutgoingEdges() const
413+
{
414+
size_t count;
415+
BNPendingBasicBlockEdge* edges = BNGetBasicBlockPendingOutgoingEdges(m_object, &count);
416+
vector<PendingBasicBlockEdge> result;
417+
result.reserve(count);
418+
for (size_t i = 0; i < count; i++)
419+
{
420+
PendingBasicBlockEdge edge;
421+
edge.type = edges[i].type;
422+
edge.arch = edges[i].arch ? new CoreArchitecture(edges[i].arch) : nullptr;
423+
edge.target = edges[i].target;
424+
edge.fallThrough = edges[i].fallThrough;
425+
result.push_back(edge);
426+
}
427+
428+
BNFreePendingBasicBlockEdgeList(edges);
429+
return result;
430+
}
431+
432+
433+
void BasicBlock::ClearPendingOutgoingEdges()
434+
{
435+
BNClearBasicBlockPendingOutgoingEdges(m_object);
436+
}
437+
438+
439+
void BasicBlock::SetUndeterminedOutgoingEdges(bool value)
440+
{
441+
BNBasicBlockSetUndeterminedOutgoingEdges(m_object, value);
442+
}
443+
444+
445+
const uint8_t* BasicBlock::GetInstructionData(uint64_t addr, size_t* len) const
446+
{
447+
return BNBasicBlockGetInstructionData(m_object, addr, len);
448+
}
449+
450+
451+
void BasicBlock::AddInstructionData(const void* data, size_t len)
452+
{
453+
BNBasicBlockAddInstructionData(m_object, data, len);
454+
}
455+
456+
457+
void BasicBlock::SetFallThroughToFunction(bool value)
458+
{
459+
BNBasicBlockSetFallThroughToFunction(m_object, value);
460+
}
461+
462+
463+
bool BasicBlock::IsFallThroughToFunction() const
464+
{
465+
return BNBasicBlockIsFallThroughToFunction(m_object);
466+
}
467+
468+
388469
bool BasicBlock::CanExit() const
389470
{
390471
return BNBasicBlockCanExit(m_object);

0 commit comments

Comments
 (0)