Skip to content

Commit

Permalink
Add review changes
Browse files Browse the repository at this point in the history
  • Loading branch information
mari-mari committed Aug 28, 2023
1 parent e680e3f commit c3c790a
Show file tree
Hide file tree
Showing 6 changed files with 24 additions and 19 deletions.
6 changes: 3 additions & 3 deletions decompiler/backend/cexpressiongenerator.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class CExpressionGenerator(DataflowObjectVisitorInterface):
OperationType.greater_or_equal_us: ">=",
OperationType.dereference: "*",
OperationType.address: "&",
OperationType.member_access: ".",
# Handled in code
# OperationType.cast: "cast",
# OperationType.pointer: "point",
Expand Down Expand Up @@ -182,9 +183,8 @@ def visit_list_operation(self, op: operations.ListOperation) -> str:
def visit_unary_operation(self, op: operations.UnaryOperation) -> str:
"""Return a string representation of the given unary operation (e.g. !a or &a)."""
if isinstance(op, MemberAccess):
if isinstance(op.struct_variable.type, Pointer):
return f"{self.visit(op.struct_variable)}->{op.member_name}"
return f"{self.visit(op.struct_variable)}.{op.member_name}"
operator_str = "->" if isinstance(op.struct_variable.type, Pointer) else self.C_SYNTAX[op.operation]
return f"{self.visit(op.struct_variable)}{operator_str}{op.member_name}"
operand = self._visit_bracketed(op.operand) if self._has_lower_precedence(op.operand, op) else self.visit(op.operand)
if op.operation == OperationType.cast and op.contraction:
return f"({int(op.type.size / 8)}: ){operand}"
Expand Down
4 changes: 2 additions & 2 deletions decompiler/frontend/binaryninja/frontend.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
from decompiler.task import DecompilerTask
from decompiler.util.options import Options

from ...structures.pseudo.complextypes import ComplexTypeMap
from decompiler.structures.pseudo.complextypes import ComplexTypeMap
from ..frontend import Frontend
from .lifter import BinaryninjaLifter
from .parser import BinaryninjaParser
Expand Down Expand Up @@ -160,4 +160,4 @@ def _extract_cfg(self, function: Function, options: Options) -> Tuple[ControlFlo
report_threshold = options.getint("lifter.report_threshold", fallback=3)
no_masks = options.getboolean("lifter.no_bit_masks", fallback=True)
parser = BinaryninjaParser(BinaryninjaLifter(no_masks, bv=function.view), report_threshold)
return parser.parse(function)
return parser.parse(function), parser.complex_types
7 changes: 3 additions & 4 deletions decompiler/frontend/binaryninja/handlers/assignments.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
"""Module implementing the AssignmentHandler for binaryninja."""
import logging
from functools import partial
from typing import Union

import binaryninja
from binaryninja import mediumlevelil
Expand All @@ -20,7 +19,7 @@
UnaryOperation,
)
from decompiler.structures.pseudo.complextypes import Struct
from decompiler.structures.pseudo.complextypes import Union as _Union
from decompiler.structures.pseudo.complextypes import Union
from decompiler.structures.pseudo.operations import MemberAccess


Expand Down Expand Up @@ -101,7 +100,7 @@ def lift_get_field(self, instruction: mediumlevelil.MediumLevelILVarField, is_al
(x = ) <- for the sake of example, only rhs expression is lifted here.
"""
source = self._lifter.lift(instruction.src, is_aliased=is_aliased, parent=instruction)
if isinstance(source.type, Struct) or isinstance(source.type, _Union):
if isinstance(source.type, Struct) or isinstance(source.type, Union):
return self._get_field_as_member_access(instruction, source, **kwargs)
cast_type = source.type.resize(instruction.size * self.BYTE_SIZE)
if instruction.offset:
Expand Down Expand Up @@ -134,7 +133,7 @@ def lift_store(self, assignment: mediumlevelil.MediumLevelILStoreSsa, **kwargs)
self._lifter.lift(assignment.src),
)

def _lift_store_destination(self, store_assignment: mediumlevelil.MediumLevelILStoreSsa) -> Union[UnaryOperation, GlobalVariable]:
def _lift_store_destination(self, store_assignment: mediumlevelil.MediumLevelILStoreSsa) -> UnaryOperation | GlobalVariable:
"""
Lift destination operand of store operation which is used for modelling both assignments of dereferences and global variables.
"""
Expand Down
14 changes: 10 additions & 4 deletions decompiler/frontend/binaryninja/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,25 @@ def __init__(self, lifter: Lifter, report_threshold: int = 3):
self._lifter = lifter
self._unlifted_instructions: List[MediumLevelILInstruction] = []
self._report_threshold = int(report_threshold)
self._complex_types = None

def parse(self, function: Function) -> Tuple[ControlFlowGraph, ComplexTypeMap]:
"""Generate a cfg and complex types from the given function."""
def parse(self, function: Function) -> ControlFlowGraph:
"""Generate a cfg from the given function."""
cfg = ControlFlowGraph()
index_to_BasicBlock = dict()
for basic_block in function.medium_level_il.ssa_form:
index_to_BasicBlock[basic_block.index] = BasicBlock(basic_block.index, instructions=list(self._lift_instructions(basic_block)))
cfg.add_node(index_to_BasicBlock[basic_block.index])
for basic_block in function.medium_level_il.ssa_form:
self._add_basic_block_edges(cfg, index_to_BasicBlock, basic_block)
complex_types = self._lifter.complex_types
self._complex_types = self._lifter.complex_types
self._report_lifter_errors()
return cfg, complex_types
return cfg

@property
def complex_types(self) -> ComplexTypeMap:
"""Return complex type map for the given function."""
return self._complex_types

def _add_basic_block_edges(self, cfg: ControlFlowGraph, vertices: dict, basic_block: MediumLevelILBasicBlock) -> None:
"""Add all outgoing edges of the given basic block to the given cfg."""
Expand Down
2 changes: 1 addition & 1 deletion decompiler/task.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,5 +97,5 @@ def failure_message(self) -> str:

@property
def complex_types(self) -> ComplexTypeMap:
"""Returns complex types present in the function (structs, unions, enums, etc.)."""
"""Return complex types present in the function (structs, unions, enums, etc.)."""
return self._complex_types
10 changes: 5 additions & 5 deletions tests/frontend/test_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ def parser():
def test_trivial(parser):
"""Function with a single empty basic block."""
function = MockFunction([MockBlock(0, [])])
cfg, _ = parser.parse(function)
cfg = parser.parse(function)
assert len(cfg.nodes) == 1
assert len(list(cfg.instructions)) == 0
assert len(cfg.edges) == 0
Expand All @@ -140,7 +140,7 @@ def test_chain(parser):
MockBlock(2, []),
]
)
cfg, _ = parser.parse(function)
cfg = parser.parse(function)
assert [v.name for v in cfg.nodes] == [0, 1, 2]
assert [(edge.source.name, edge.sink.name) for edge in cfg.edges] == [(0, 1), (1, 2)]
assert len(list(cfg.instructions)) == 0
Expand All @@ -157,7 +157,7 @@ def test_branch(parser):
MockBlock(3, []),
]
)
cfg, _ = parser.parse(function)
cfg = parser.parse(function)
assert [v.name for v in cfg.nodes] == [0, 1, 2, 3]
assert [(edge.source.address, edge.sink.address) for edge in cfg.edges] == [(0, 1), (0, 2), (1, 3), (2, 3)]
assert len(list(cfg.instructions)) == 0
Expand Down Expand Up @@ -186,7 +186,7 @@ def test_switch(parser):
MockBlock(4, []),
]
)
cfg, _ = parser.parse(function)
cfg = parser.parse(function)
assert [v.name for v in cfg.nodes] == [0, 1, 2, 3, 4]
assert [(edge.source.name, edge.sink.name) for edge in cfg.edges] == [(0, 1), (0, 2), (0, 3), (1, 4), (2, 4), (3, 4)]
assert [getattr(edge, "cases", None) for edge in cfg.edges] == [
Expand All @@ -210,7 +210,7 @@ def test_loop(parser):
MockBlock(3, []),
]
)
cfg, _ = parser.parse(function)
cfg = parser.parse(function)
assert [v.name for v in cfg.nodes] == [0, 1, 2, 3]
assert [(edge.source.address, edge.sink.address) for edge in cfg.edges] == [(0, 1), (1, 2), (2, 1), (2, 3)]
assert len(list(cfg.instructions)) == 0

0 comments on commit c3c790a

Please sign in to comment.