diff options
| author | Peter LaFosse <peter@vector35.com> | 2021-10-27 07:33:08 -0400 |
|---|---|---|
| committer | Peter LaFosse <peter@vector35.com> | 2021-11-05 10:30:12 -0400 |
| commit | 64797d7c23824a991fe6285a6a3bb0dcee2dd495 (patch) | |
| tree | dd974f93a349a8486533f91c817f51ab9d8d8909 | |
| parent | 2386158d10d402b7783ab6f1253f548d230896c8 (diff) | |
Add IL class heirarchy graph report
| -rw-r--r-- | python/binaryview.py | 2 | ||||
| -rw-r--r-- | python/commonil.py | 60 | ||||
| -rw-r--r-- | python/highlevelil.py | 9 | ||||
| -rw-r--r-- | python/lowlevelil.py | 17 | ||||
| -rw-r--r-- | python/mediumlevelil.py | 11 |
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 |
