summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
authorPeter LaFosse <peter@vector35.com>2021-10-27 07:33:08 -0400
committerPeter LaFosse <peter@vector35.com>2021-11-05 10:30:12 -0400
commit64797d7c23824a991fe6285a6a3bb0dcee2dd495 (patch)
treedd974f93a349a8486533f91c817f51ab9d8d8909 /python
parent2386158d10d402b7783ab6f1253f548d230896c8 (diff)
Add IL class heirarchy graph report
Diffstat (limited to 'python')
-rw-r--r--python/binaryview.py2
-rw-r--r--python/commonil.py60
-rw-r--r--python/highlevelil.py9
-rw-r--r--python/lowlevelil.py17
-rw-r--r--python/mediumlevelil.py11
5 files changed, 77 insertions, 22 deletions
diff --git a/python/binaryview.py b/python/binaryview.py
index c1bfde83..f049ae28 100644
--- a/python/binaryview.py
+++ b/python/binaryview.py
@@ -4443,6 +4443,8 @@ class BinaryView:
syms = core.BNGetSymbols(self.handle, count, _namespace)
assert syms is not None, "core.BNGetSymbols returned None"
else:
+ if length is None:
+ length = 1
syms = core.BNGetSymbolsInRange(self.handle, start, length, count, namespace)
assert syms is not None, "core.BNGetSymbolsInRange returned None"
result = []
diff --git a/python/commonil.py b/python/commonil.py
index fdb6540e..4f0eb7f2 100644
--- a/python/commonil.py
+++ b/python/commonil.py
@@ -19,27 +19,53 @@
# IN THE SOFTWARE.
from dataclasses import dataclass
-
+from .flowgraph import FlowGraph, FlowGraphNode
+from .enums import BranchType
+from .interaction import show_graph_report
+from .log import log_warn
# This file contains a list of top level abstract classes for implementing BNIL instructions
-
@dataclass(frozen=True, repr=False)
class ILInstruction:
- pass
+ @classmethod
+ def prepend_parent(cls, graph:FlowGraph, node:FlowGraphNode, nodes={}):
+ for parent in cls.__bases__:
+ if not issubclass(parent, ILInstruction):
+ continue
+ if parent.__name__ in nodes:
+ nodes[parent.__name__].add_outgoing_edge(BranchType.UnconditionalBranch, node)
+ else:
+ parent_node = FlowGraphNode(graph)
+ parent_node.lines = [f"{parent.__name__}"]
+ parent_node.add_outgoing_edge(BranchType.UnconditionalBranch, node)
+ graph.append(parent_node)
+ nodes[parent.__name__] = parent_node
+ parent.prepend_parent(graph, parent_node, nodes)
+
+ @classmethod
+ def add_subgraph(cls, graph, nodes):
+ node = FlowGraphNode(graph)
+ node.lines = [f"{cls.__name__}"]
+ graph.append(node)
+ cls.prepend_parent(graph, node, nodes)
+ return graph
+ @classmethod
+ def show_hierarchy_graph(cls):
+ show_graph_report(f"{cls.__name__}", cls.add_subgraph(FlowGraph(), {}))
@dataclass(frozen=True, repr=False)
-class Constant:
+class Constant(ILInstruction):
pass
@dataclass(frozen=True, repr=False)
-class BinaryOperation:
+class BinaryOperation(ILInstruction):
pass
@dataclass(frozen=True, repr=False)
-class UnaryOperation:
+class UnaryOperation(ILInstruction):
pass
@@ -49,7 +75,7 @@ class Comparison(BinaryOperation):
@dataclass(frozen=True, repr=False)
-class SSA:
+class SSA(ILInstruction):
pass
@@ -59,12 +85,12 @@ class Phi(SSA):
@dataclass(frozen=True, repr=False)
-class FloatingPoint:
+class FloatingPoint(ILInstruction):
pass
@dataclass(frozen=True, repr=False)
-class ControlFlow:
+class ControlFlow(ILInstruction):
pass
@@ -98,12 +124,12 @@ class Return(Terminal):
@dataclass(frozen=True, repr=False)
-class Signed:
+class Signed(ILInstruction):
pass
@dataclass(frozen=True, repr=False)
-class Arithmetic:
+class Arithmetic(ILInstruction):
pass
@@ -118,32 +144,32 @@ class DoublePrecision(Arithmetic):
@dataclass(frozen=True, repr=False)
-class Memory:
+class Memory(ILInstruction):
pass
@dataclass(frozen=True, repr=False)
-class Load:
+class Load(ILInstruction):
pass
@dataclass(frozen=True, repr=False)
-class Store:
+class Store(ILInstruction):
pass
@dataclass(frozen=True, repr=False)
-class RegisterStack:
+class RegisterStack(ILInstruction):
pass
@dataclass(frozen=True, repr=False)
-class SetVar:
+class SetVar(ILInstruction):
pass
@dataclass(frozen=True, repr=False)
-class StackOperation:
+class StackOperation(ILInstruction):
pass
diff --git a/python/highlevelil.py b/python/highlevelil.py
index 0ae927e4..c8751c8f 100644
--- a/python/highlevelil.py
+++ b/python/highlevelil.py
@@ -37,6 +37,7 @@ from . import types
from . import highlight
from . import flowgraph
from . import variable
+from .interaction import show_graph_report
from .commonil import (ILInstruction, Call, Tailcall, Syscall, Comparison, Signed, UnaryOperation, BinaryOperation,
SSA, Phi, Loop, ControlFlow, Memory, Constant, Arithmetic, DoublePrecision, Terminal,
FloatingPoint)
@@ -261,6 +262,14 @@ class HighLevelILInstruction(ILInstruction):
HighLevelILOperation.HLIL_FCMP_UO: [("left", "expr"), ("right", "expr")]
}
+ @staticmethod
+ def show_hlil_hierarchy():
+ graph = flowgraph.FlowGraph()
+ nodes = {}
+ for instruction in ILInstruction.values():
+ instruction.add_subgraph(graph, nodes)
+ show_graph_report("HLIL Class Hierarchy Graph", graph)
+
@classmethod
def create(cls, func:'HighLevelILFunction', expr_index:ExpressionIndex, as_ast:bool=True, instr_index:Optional[InstructionIndex]=None) -> 'HighLevelILInstruction':
assert func.arch is not None, "Attempted to create IL instruction with function missing an Architecture"
diff --git a/python/lowlevelil.py b/python/lowlevelil.py
index 80349987..a301dc2a 100644
--- a/python/lowlevelil.py
+++ b/python/lowlevelil.py
@@ -35,6 +35,7 @@ from . import variable
from . import binaryview
from . import architecture
from . import types
+from .interaction import show_graph_report
from .commonil import (ILInstruction, Constant, BinaryOperation, UnaryOperation, Comparison, SSA,
Phi, FloatingPoint, ControlFlow, Terminal, Call, StackOperation, Return,
Signed, Arithmetic, Carry, DoublePrecision, Memory, Load, Store, RegisterStack, SetReg)
@@ -448,6 +449,14 @@ class LowLevelILInstruction(ILInstruction):
LowLevelILOperation.LLIL_MEM_PHI: [("dest_memory", "int"), ("src_memory", "int_list")]
}
+ @staticmethod
+ def show_llil_hierarchy():
+ graph = flowgraph.FlowGraph()
+ nodes = {}
+ for instruction in ILInstruction.values():
+ instruction.add_subgraph(graph, nodes)
+ show_graph_report("LLIL Class Hierarchy Graph", graph)
+
@classmethod
def create(cls, func:'LowLevelILFunction', expr_index:ExpressionIndex, instr_index:Optional[InstructionIndex]=None) -> 'LowLevelILInstruction':
assert func.arch is not None, "Attempted to create IL instruction with function missing an Architecture"
@@ -1514,7 +1523,7 @@ class LowLevelILCall_param(LowLevelILInstruction, SSA):
@dataclass(frozen=True, repr=False)
-class LowLevelILMem_phi(LowLevelILInstruction, Memory, SSA):
+class LowLevelILMem_phi(LowLevelILInstruction, Memory, Phi):
@property
def dest_memory(self) -> int:
@@ -2102,7 +2111,7 @@ class LowLevelILLoad_ssa(LowLevelILInstruction, Load, SSA):
@dataclass(frozen=True, repr=False)
-class LowLevelILReg_phi(LowLevelILInstruction, SSA):
+class LowLevelILReg_phi(LowLevelILInstruction, Phi):
@property
def dest(self) -> SSARegister:
@@ -2118,7 +2127,7 @@ class LowLevelILReg_phi(LowLevelILInstruction, SSA):
@dataclass(frozen=True, repr=False)
-class LowLevelILReg_stack_phi(LowLevelILInstruction, RegisterStack, SSA):
+class LowLevelILReg_stack_phi(LowLevelILInstruction, RegisterStack, Phi):
@property
def dest(self) -> SSARegisterStack:
@@ -2134,7 +2143,7 @@ class LowLevelILReg_stack_phi(LowLevelILInstruction, RegisterStack, SSA):
@dataclass(frozen=True, repr=False)
-class LowLevelILFlag_phi(LowLevelILInstruction, SSA):
+class LowLevelILFlag_phi(LowLevelILInstruction, Phi):
@property
def dest(self) -> SSAFlag:
diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py
index 3a37bb6a..3ee5fc99 100644
--- a/python/mediumlevelil.py
+++ b/python/mediumlevelil.py
@@ -35,6 +35,7 @@ from . import flowgraph
from . import variable
from . import architecture
from . import binaryview
+from .interaction import show_graph_report
from .commonil import (ILInstruction, Constant, BinaryOperation, UnaryOperation, Comparison, SSA,
Phi, FloatingPoint, ControlFlow, Terminal, Call, Syscall, Tailcall, Return,
Signed, Arithmetic, Carry, DoublePrecision, Memory, Load, Store, RegisterStack, SetVar)
@@ -250,6 +251,14 @@ class MediumLevelILInstruction(ILInstruction):
MediumLevelILOperation.MLIL_MEM_PHI: [("dest_memory", "int"), ("src_memory", "int_list")]
}
+ @staticmethod
+ def show_mlil_hierarchy():
+ graph = flowgraph.FlowGraph()
+ nodes = {}
+ for instruction in ILOperations.values():
+ instruction.add_subgraph(graph, nodes)
+ show_graph_report("MLIL Class Hierarchy Graph", graph)
+
@classmethod
def create(cls, func:'MediumLevelILFunction', expr_index:ExpressionIndex, instr_index:Optional[InstructionIndex]=None) -> 'MediumLevelILInstruction':
assert func.arch is not None, "Attempted to create IL instruction with function missing an Architecture"
@@ -816,7 +825,7 @@ class MediumLevelILBinaryBase(MediumLevelILInstruction, BinaryOperation):
@dataclass(frozen=True, repr=False)
-class MediumLevelILComparisonBase(MediumLevelILBinaryBase):
+class MediumLevelILComparisonBase(MediumLevelILBinaryBase, Comparison):
pass