summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--basicblock.cpp37
-rw-r--r--binaryninjaapi.h7
-rw-r--r--binaryninjacore.h6
-rw-r--r--functiongraphblock.cpp3
-rw-r--r--python/basicblock.py30
-rw-r--r--python/function.py21
6 files changed, 89 insertions, 15 deletions
diff --git a/basicblock.cpp b/basicblock.cpp
index 153a7768..58fcb4aa 100644
--- a/basicblock.cpp
+++ b/basicblock.cpp
@@ -158,6 +158,43 @@ bool BasicBlock::HasUndeterminedOutgoingEdges() const
}
+set<Ref<BasicBlock>> BasicBlock::GetDominators() const
+{
+ size_t count;
+ BNBasicBlock** blocks = BNGetBasicBlockDominators(m_object, &count);
+
+ set<Ref<BasicBlock>> result;
+ for (size_t i = 0; i < count; i++)
+ result.insert(new BasicBlock(BNNewBasicBlockReference(blocks[i])));
+
+ BNFreeBasicBlockList(blocks, count);
+ return result;
+}
+
+
+set<Ref<BasicBlock>> BasicBlock::GetStrictDominators() const
+{
+ size_t count;
+ BNBasicBlock** blocks = BNGetBasicBlockStrictDominators(m_object, &count);
+
+ set<Ref<BasicBlock>> result;
+ for (size_t i = 0; i < count; i++)
+ result.insert(new BasicBlock(BNNewBasicBlockReference(blocks[i])));
+
+ BNFreeBasicBlockList(blocks, count);
+ return result;
+}
+
+
+Ref<BasicBlock> BasicBlock::GetImmediateDominator() const
+{
+ BNBasicBlock* result = BNGetBasicBlockImmediateDominator(m_object);
+ if (!result)
+ return nullptr;
+ return new BasicBlock(result);
+}
+
+
void BasicBlock::MarkRecentUse()
{
BNMarkBasicBlockAsRecentlyUsed(m_object);
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index 7004501c..ea9d3972 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -1781,6 +1781,10 @@ namespace BinaryNinja
std::vector<BasicBlockEdge> GetIncomingEdges() const;
bool HasUndeterminedOutgoingEdges() const;
+ std::set<Ref<BasicBlock>> GetDominators() const;
+ std::set<Ref<BasicBlock>> GetStrictDominators() const;
+ Ref<BasicBlock> GetImmediateDominator() const;
+
void MarkRecentUse();
std::vector<std::vector<InstructionTextToken>> GetAnnotations();
@@ -1970,8 +1974,7 @@ namespace BinaryNinja
struct FunctionGraphEdge
{
BNBranchType type;
- uint64_t target;
- Ref<Architecture> arch;
+ Ref<BasicBlock> target;
std::vector<BNPoint> points;
};
diff --git a/binaryninjacore.h b/binaryninjacore.h
index 2d22bb3f..239d1002 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -805,8 +805,7 @@ extern "C"
struct BNFunctionGraphEdge
{
BNBranchType type;
- uint64_t target;
- BNArchitecture* arch;
+ BNBasicBlock* target;
BNPoint* points;
size_t pointCount;
};
@@ -1729,6 +1728,9 @@ extern "C"
BINARYNINJACOREAPI void BNFreeBasicBlockEdgeList(BNBasicBlockEdge* edges, size_t count);
BINARYNINJACOREAPI bool BNBasicBlockHasUndeterminedOutgoingEdges(BNBasicBlock* block);
BINARYNINJACOREAPI size_t BNGetBasicBlockIndex(BNBasicBlock* block);
+ BINARYNINJACOREAPI BNBasicBlock** BNGetBasicBlockDominators(BNBasicBlock* block, size_t* count);
+ BINARYNINJACOREAPI BNBasicBlock** BNGetBasicBlockStrictDominators(BNBasicBlock* block, size_t* count);
+ BINARYNINJACOREAPI BNBasicBlock* BNGetBasicBlockImmediateDominator(BNBasicBlock* block);
BINARYNINJACOREAPI BNDisassemblyTextLine* BNGetBasicBlockDisassemblyText(BNBasicBlock* block,
BNDisassemblySettings* settings, size_t* count);
diff --git a/functiongraphblock.cpp b/functiongraphblock.cpp
index db69c25a..a37c0b49 100644
--- a/functiongraphblock.cpp
+++ b/functiongraphblock.cpp
@@ -128,8 +128,7 @@ const vector<FunctionGraphEdge>& FunctionGraphBlock::GetOutgoingEdges()
{
FunctionGraphEdge edge;
edge.type = edges[i].type;
- edge.target = edges[i].target;
- edge.arch = edges[i].arch ? new CoreArchitecture(edges[i].arch) : nullptr;
+ edge.target = edges[i].target ? new BasicBlock(BNNewBasicBlockReference(edges[i].target)) : nullptr;
edge.points.insert(edge.points.begin(), &edges[i].points[0], &edges[i].points[edges[i].pointCount]);
result.push_back(edge);
}
diff --git a/python/basicblock.py b/python/basicblock.py
index ebacb311..9d48d3cb 100644
--- a/python/basicblock.py
+++ b/python/basicblock.py
@@ -134,6 +134,36 @@ class BasicBlock(object):
return core.BNBasicBlockHasUndeterminedOutgoingEdges(self.handle)
@property
+ def dominators(self):
+ """List of dominators for this basic block (read-only)"""
+ count = ctypes.c_ulonglong()
+ blocks = core.BNGetBasicBlockDominators(self.handle, count)
+ result = []
+ for i in xrange(0, count.value):
+ result.append(BasicBlock(self.view, core.BNNewBasicBlockReference(blocks[i])))
+ core.BNFreeBasicBlockList(blocks, count.value)
+ return result
+
+ @property
+ def strict_dominators(self):
+ """List of strict dominators for this basic block (read-only)"""
+ count = ctypes.c_ulonglong()
+ blocks = core.BNGetBasicBlockStrictDominators(self.handle, count)
+ result = []
+ for i in xrange(0, count.value):
+ result.append(BasicBlock(self.view, core.BNNewBasicBlockReference(blocks[i])))
+ core.BNFreeBasicBlockList(blocks, count.value)
+ return result
+
+ @property
+ def immediate_dominator(self):
+ """Immediate dominator of this basic block (read-only)"""
+ result = core.BNGetBasicBlockImmediateDominator(self.handle)
+ if not result:
+ return None
+ return BasicBlock(self.view, result)
+
+ @property
def annotations(self):
"""List of automatic annotations for the start of this block (read-only)"""
return self.function.get_block_annotations(self.arch, self.start)
diff --git a/python/function.py b/python/function.py
index 4cdd6cc9..2f6788f6 100644
--- a/python/function.py
+++ b/python/function.py
@@ -847,16 +847,13 @@ class DisassemblyTextLine(object):
class FunctionGraphEdge(object):
- def __init__(self, branch_type, arch, target, points):
+ def __init__(self, branch_type, target, points):
self.type = BranchType(branch_type)
- self.arch = arch
self.target = target
self.points = points
def __repr__(self):
- if self.arch:
- return "<%s: %s@%#x>" % (self.type.name, self.arch.name, self.target)
- return "<%s: %#x>" % (self.type, self.target)
+ return "<%s: %s>" % (self.type.name, repr(self.target))
class FunctionGraphBlock(object):
@@ -958,13 +955,19 @@ class FunctionGraphBlock(object):
for i in xrange(0, count.value):
branch_type = BranchType(edges[i].type)
target = edges[i].target
- arch = None
- if edges[i].arch is not None:
- arch = architecture.Architecture(edges[i].arch)
+ if target:
+ func = core.BNGetBasicBlockFunction(target)
+ if func is None:
+ core.BNFreeBasicBlock(target)
+ target = None
+ else:
+ target = basicblock.BasicBlock(binaryview.BinaryView(handle = core.BNGetFunctionData(func)),
+ core.BNNewBasicBlockReference(target))
+ core.BNFreeFunction(func)
points = []
for j in xrange(0, edges[i].pointCount):
points.append((edges[i].points[j].x, edges[i].points[j].y))
- result.append(FunctionGraphEdge(branch_type, arch, target, points))
+ result.append(FunctionGraphEdge(branch_type, target, points))
core.BNFreeFunctionGraphBlockOutgoingEdgeList(edges, count.value)
return result