diff options
| -rw-r--r-- | basicblock.cpp | 37 | ||||
| -rw-r--r-- | binaryninjaapi.h | 7 | ||||
| -rw-r--r-- | binaryninjacore.h | 6 | ||||
| -rw-r--r-- | functiongraphblock.cpp | 3 | ||||
| -rw-r--r-- | python/basicblock.py | 30 | ||||
| -rw-r--r-- | python/function.py | 21 |
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 |
