summaryrefslogtreecommitdiff
path: root/python/highlevelil.py
diff options
context:
space:
mode:
authorPeter LaFosse <peter@vector35.com>2021-06-07 09:59:54 -0400
committerPeter LaFosse <peter@vector35.com>2021-09-05 10:08:09 -0400
commit61b4bb24e06aa955484293d35fa926c07887544b (patch)
tree29c6b7fecdac6270681260637439926ec07a259e /python/highlevelil.py
parent75f2463a46cc666e87120f3a30332fa80020b62e (diff)
Add type hints to basicblock.py, lowlevelil.py, architecture.py
Diffstat (limited to 'python/highlevelil.py')
-rw-r--r--python/highlevelil.py429
1 files changed, 235 insertions, 194 deletions
diff --git a/python/highlevelil.py b/python/highlevelil.py
index 45f6def4..71c58920 100644
--- a/python/highlevelil.py
+++ b/python/highlevelil.py
@@ -20,21 +20,28 @@
import ctypes
import struct
-from typing import List
+from typing import Optional, Generator, List, Union, Any, NewType
# Binary Ninja components
-import binaryninja
-from binaryninja import _binaryninjacore as core
-from binaryninja.enums import HighLevelILOperation, FunctionGraphType
-from binaryninja import function
-from binaryninja import lowlevelil
-from binaryninja import mediumlevelil
-from binaryninja import basicblock
-from binaryninja import types
-
-# 2-3 compatibility
-from binaryninja import range
+from . import _binaryninjacore as core
+from .enums import HighLevelILOperation, InstructionTextTokenType, DataFlowQueryOption, FunctionGraphType
+from .variable import Variable
+from . import function
+from . import binaryview
+from . import architecture
+from . import lowlevelil
+from . import mediumlevelil
+from . import basicblock
+from . import types
+from . import highlight
+from . import flowgraph
+from . import variable
+LinesType = Generator['function.DisassemblyTextLine', None, None]
+ExpressionIndex = NewType('ExpressionIndex', int)
+InstructionIndex = NewType('InstructionIndex', int)
+HLILInstructionsType = Generator['HighLevelILInstruction', None, None]
+HLILBasicBlocksType = Generator['HighLevelILBasicBlock', None, None]
class HighLevelILOperationAndSize(object):
def __init__(self, operation, size):
@@ -63,7 +70,6 @@ class HighLevelILOperationAndSize(object):
@property
def operation(self):
- """ """
return self._operation
@operation.setter
@@ -72,7 +78,6 @@ class HighLevelILOperationAndSize(object):
@property
def size(self):
- """ """
return self._size
@size.setter
@@ -241,9 +246,12 @@ class HighLevelILInstruction(object):
HighLevelILOperation.HLIL_FCMP_UO: [("left", "expr"), ("right", "expr")]
}
- def __init__(self, func, expr_index, as_ast = True, instr_index = None):
+ def __init__(self, func:'HighLevelILFunction', expr_index:ExpressionIndex, as_ast:bool = True,
+ instr_index:InstructionIndex = None):
instr = core.BNGetHighLevelILByIndex(func.handle, expr_index, as_ast)
self._function = func
+ if func.arch is None:
+ raise Exception("HighLevelILFunction architecture must not be None")
self._expr_index = expr_index
if instr_index is None:
self._instr_index = core.BNGetHighLevelILInstructionForExpr(func.handle, expr_index)
@@ -260,6 +268,7 @@ class HighLevelILInstruction(object):
i = 0
for operand in operands:
name, operand_type = operand
+ value = None
if operand_type == "int":
value = instr.operands[i]
value = (value & ((1 << 63) - 1)) - (value & (1 << 63))
@@ -275,15 +284,16 @@ class HighLevelILInstruction(object):
elif operand_type == "intrinsic":
value = lowlevelil.ILIntrinsic(func.arch, instr.operands[i])
elif operand_type == "var":
- value = function.Variable.from_identifier(self._function.source_function, instr.operands[i])
+ value = variable.Variable.from_identifier(self._function.source_function, instr.operands[i])
elif operand_type == "var_ssa":
- var = function.Variable.from_identifier(self._function.source_function, instr.operands[i])
+ var = variable.Variable.from_identifier(self._function.source_function, instr.operands[i])
version = instr.operands[i + 1]
i += 1
value = mediumlevelil.SSAVariable(var, version)
elif operand_type == "int_list":
count = ctypes.c_ulonglong()
operand_list = core.BNHighLevelILGetOperandList(func.handle, self._expr_index, i, count)
+ assert operand_list is not None, "core.BNHighLevelILGetOperandList returned None"
value = []
for j in range(count.value):
value.append(operand_list[j])
@@ -291,6 +301,7 @@ class HighLevelILInstruction(object):
elif operand_type == "expr_list":
count = ctypes.c_ulonglong()
operand_list = core.BNHighLevelILGetOperandList(func.handle, self._expr_index, i, count)
+ assert operand_list is not None, "core.BNHighLevelILGetOperandList returned None"
i += 1
value = []
for j in range(count.value):
@@ -299,12 +310,13 @@ class HighLevelILInstruction(object):
elif operand_type == "var_ssa_list":
count = ctypes.c_ulonglong()
operand_list = core.BNHighLevelILGetOperandList(func.handle, self._expr_index, i, count)
+ assert operand_list is not None, "core.BNHighLevelILGetOperandList returned None"
i += 1
value = []
for j in range(count.value // 2):
var_id = operand_list[j * 2]
var_version = operand_list[(j * 2) + 1]
- value.append(mediumlevelil.SSAVariable(function.Variable.from_identifier(self._function.source_function,
+ value.append(mediumlevelil.SSAVariable(variable.Variable.from_identifier(self._function.source_function,
var_id), var_version))
core.BNHighLevelILFreeOperandList(operand_list)
elif operand_type == "member_index":
@@ -336,9 +348,9 @@ class HighLevelILInstruction(object):
first_line = "<invalid>"
else:
first_line = ""
- for token in lines[0].tokens:
+ for token in next(lines).tokens:
first_line += token.text
- if len(lines) > 1:
+ if len(list(lines)) > 1:
continuation = "..."
return "<%s: %s%s>" % (self._operation.name, first_line, continuation)
@@ -376,25 +388,26 @@ class HighLevelILInstruction(object):
return hash((self._function, self._expr_index))
@property
- def lines(self):
+ def lines(self) -> LinesType:
"""HLIL text lines (read-only)"""
count = ctypes.c_ulonglong()
lines = core.BNGetHighLevelILExprText(self._function.handle, self._expr_index, self._as_ast, count, None)
- result = []
- for i in range(0, count.value):
- addr = lines[i].addr
- if lines[i].instrIndex != 0xffffffffffffffff:
- il_instr = self._function[lines[i].instrIndex]
- else:
- il_instr = None
- color = binaryninja.highlight.HighlightColor._from_core_struct(lines[i].highlight)
- tokens = binaryninja.function.InstructionTextToken.get_instruction_lines(lines[i].tokens, lines[i].count)
- result.append(binaryninja.function.DisassemblyTextLine(tokens, addr, il_instr, color))
- core.BNFreeDisassemblyTextLines(lines, count.value)
- return result
+ assert lines is not None, "core.BNGetHighLevelILExprText returned None"
+ try:
+ for i in range(0, count.value):
+ addr = lines[i].addr
+ if lines[i].instrIndex != 0xffffffffffffffff:
+ il_instr = self._function[lines[i].instrIndex]
+ else:
+ il_instr = None
+ color = highlight.HighlightColor._from_core_struct(lines[i].highlight)
+ tokens = function.InstructionTextToken._from_core_struct(lines[i].tokens, lines[i].count)
+ yield function.DisassemblyTextLine(tokens, addr, il_instr, color)
+ finally:
+ core.BNFreeDisassemblyTextLines(lines, count.value)
@property
- def prefix_operands(self):
+ def prefix_operands(self) -> List[Any]:
"""All operands in the expression tree in prefix order"""
result = [HighLevelILOperationAndSize(self._operation, self._size)]
for operand in self._operands:
@@ -405,7 +418,7 @@ class HighLevelILInstruction(object):
return result
@property
- def postfix_operands(self):
+ def postfix_operands(self) -> List[Any]:
"""All operands in the expression tree in postfix order"""
result = []
for operand in self._operands:
@@ -417,141 +430,144 @@ class HighLevelILInstruction(object):
return result
@property
- def function(self):
- """ """
+ def function(self) -> 'HighLevelILFunction':
return self._function
@property
- def expr_index(self):
- """ """
+ def expr_index(self) -> ExpressionIndex:
return self._expr_index
@expr_index.setter
- def expr_index(self, value):
+ def expr_index(self, value:ExpressionIndex) -> None:
self._expr_index = value
@property
- def instr_index(self):
+ def instr_index(self) -> int:
"""Index of the statement that this expression belongs to (read-only)"""
return core.BNGetHighLevelILInstructionForExpr(self._function.handle, self._expr_index)
@property
- def instr(self):
+ def instr(self) -> 'HighLevelILInstruction':
"""The statement that this expression belongs to (read-only)"""
return self._function[self.instr_index]
@property
- def ast(self):
+ def ast(self) -> 'HighLevelILInstruction':
"""This expression with full AST printing (read-only)"""
if self._as_ast:
return self
return HighLevelILInstruction(self._function, self._expr_index, True)
@property
- def non_ast(self):
+ def non_ast(self) -> 'HighLevelILInstruction':
"""This expression without full AST printing (read-only)"""
if not self._as_ast:
return self
return HighLevelILInstruction(self._function, self._expr_index, False)
@property
- def operation(self):
- """ """
+ def operation(self) -> HighLevelILOperation:
return self._operation
@operation.setter
- def operation(self, value):
+ def operation(self, value:HighLevelILOperation) -> None:
self._operation = value
@property
- def size(self):
- """ """
+ def size(self) -> int:
return self._size
@size.setter
- def size(self, value):
+ def size(self, value:int) -> None:
self._size = value
@property
- def address(self):
- """ """
+ def address(self) -> int:
return self._address
@address.setter
- def address(self, value):
+ def address(self, value:int) -> None:
self._address = value
@property
def source_operand(self):
- """ """
- return self._source_operand
+ return self._source_operand
@source_operand.setter
def source_operand(self, value):
self._source_operand = value
@property
- def operands(self):
- """ """
+ def operands(self) -> Any:
return self._operands
@operands.setter
- def operands(self, value):
+ def operands(self, value: Any):
self._operands = value
@property
- def parent(self):
+ def parent(self) -> Optional['HighLevelILInstruction']:
if self._parent >= core.BNGetHighLevelILExprCount(self._function.handle):
return None
return HighLevelILInstruction(self._function, self._parent, self._as_ast)
@property
- def ssa_form(self):
+ def ssa_form(self) -> 'HighLevelILInstruction':
"""SSA form of expression (read-only)"""
+ assert self._function.ssa_form is not None
return HighLevelILInstruction(self._function.ssa_form,
core.BNGetHighLevelILSSAExprIndex(self._function.handle, self._expr_index), self._as_ast)
@property
- def non_ssa_form(self):
+ def non_ssa_form(self) -> Optional['HighLevelILInstruction']:
"""Non-SSA form of expression (read-only)"""
+ if self._function.non_ssa_form is None:
+ return None
return HighLevelILInstruction(self._function.non_ssa_form,
core.BNGetHighLevelILNonSSAExprIndex(self._function.handle, self._expr_index), self._as_ast)
@property
- def medium_level_il(self):
+ def medium_level_il(self) -> Optional['mediumlevelil.MediumLevelILInstruction']:
"""Medium level IL form of this expression"""
expr = self._function.get_medium_level_il_expr_index(self._expr_index)
if expr is None:
return None
- return mediumlevelil.MediumLevelILInstruction(self._function.medium_level_il.ssa_form, expr)
+ mlil = self._function.medium_level_il
+ if mlil is None:
+ return None
+ ssa_func = mlil.ssa_form
+ assert ssa_func is not None, "medium_level_il.ssa_form is None"
+ return mediumlevelil.MediumLevelILInstruction(ssa_func, expr)
@property
- def mlil(self):
+ def mlil(self) -> Optional['mediumlevelil.MediumLevelILInstruction']:
"""Alias for medium_level_il"""
return self.medium_level_il
@property
- def mlils(self):
- exprs = self._function.get_medium_level_il_expr_indexes(self._expr_index)
- result = []
- for expr in exprs:
- result.append(mediumlevelil.MediumLevelILInstruction(self._function.medium_level_il.ssa_form, expr))
- return result
+ def mlils(self) -> Generator['mediumlevelil.MediumLevelILInstruction', None, None]:
+ for expr in self._function.get_medium_level_il_expr_indexes(self._expr_index):
+ mlil = self._function.medium_level_il
+ if mlil is None:
+ return
+ ssa_func = mlil.ssa_form
+ assert ssa_func is not None, "medium_level_il.ssa_form is None"
+ yield mediumlevelil.MediumLevelILInstruction(ssa_func, expr)
@property
- def low_level_il(self):
+ def low_level_il(self) -> Optional['lowlevelil.LowLevelILInstruction']:
"""Low level IL form of this expression"""
if self.mlil is None:
return None
return self.mlil.llil
@property
- def llil(self):
+ def llil(self) -> Optional['lowlevelil.LowLevelILInstruction']:
"""Alias for low_level_il"""
return self.low_level_il
@property
- def llils(self):
+ def llils(self) -> List['lowlevelil.LowLevelILExpr']:
result = set()
for mlil_expr in self.mlils:
for llil_expr in mlil_expr.llils:
@@ -559,34 +575,34 @@ class HighLevelILInstruction(object):
return list(result)
@property
- def il_basic_block(self):
+ def il_basic_block(self) -> Optional['HighLevelILBasicBlock']:
"""
IL basic block object containing this expression (read-only) (only available on finalized functions).
Returns None for HLIL_BLOCK expressions as these can contain multiple basic blocks.
"""
block = core.BNGetHighLevelILBasicBlockForInstruction(self._function.handle, self._instr_index)
- if not block:
+ if not block or self._function.source_function is None:
return None
return HighLevelILBasicBlock(self._function.source_function.view, block, self._function)
@property
- def value(self):
+ def value(self) -> 'variable.RegisterValue':
"""Value of expression if constant or a known value (read-only)"""
mlil = self.mlil
if mlil is None:
- return function.RegisterValue()
+ return variable.RegisterValue()
return mlil.value
@property
- def possible_values(self):
+ def possible_values(self) -> 'variable.PossibleValueSet':
"""Possible values of expression using path-sensitive static data flow analysis (read-only)"""
mlil = self.mlil
if mlil is None:
- return function.PossibleValueSet()
+ return variable.PossibleValueSet()
return mlil.possible_values
@property
- def expr_type(self):
+ def expr_type(self) -> Optional['types.Type']:
"""Type of expression"""
result = core.BNGetHighLevelILExprType(self._function.handle, self._expr_index)
if result.type:
@@ -596,18 +612,18 @@ class HighLevelILInstruction(object):
return types.Type(result.type, platform = platform, confidence = result.confidence)
return None
- def get_possible_values(self, options = []):
+ def get_possible_values(self, options:List[DataFlowQueryOption]=[]) -> 'variable.PossibleValueSet':
mlil = self.mlil
if mlil is None:
- return function.RegisterValue()
+ return variable.PossibleValueSet()
return mlil.get_possible_values(options)
@property
- def ssa_memory_version(self):
+ def ssa_memory_version(self) -> int:
"""Version of active memory contents in SSA form for this instruction"""
return core.BNGetHighLevelILSSAMemoryVersionAtILInstruction(self._function.handle, self._instr_index)
- def get_ssa_var_version(self, var):
+ def get_ssa_var_version(self, var:'variable.Variable') -> int:
var_data = core.BNVariable()
var_data.type = var.source_type
var_data.index = var.index
@@ -622,31 +638,28 @@ class HighLevelILExpr(object):
.. note:: This class shouldn't be instantiated directly. Rather the helper members of HighLevelILFunction should be \
used instead.
"""
- def __init__(self, index):
+ def __init__(self, index:ExpressionIndex):
self._index = index
@property
- def index(self):
- """ """
+ def index(self) -> ExpressionIndex:
return self._index
- @index.setter
- def index(self, value):
- self._index = value
class HighLevelILFunction(object):
"""
``class HighLevelILFunction`` contains the a HighLevelILInstruction object that makes up the abstract syntax tree of
- a binaryninja.function.
+ a function.
"""
- def __init__(self, arch = None, handle = None, source_func = None):
+ def __init__(self, arch:Optional['architecture.Architecture']=None, handle:core.BNHighLevelILFunction=None,
+ source_func:'function.Function'=None):
self._arch = arch
self._source_function = source_func
if handle is not None:
self.handle = core.handle_of_type(handle, core.BNHighLevelILFunction)
if self._source_function is None:
- self._source_function = binaryninja.function.Function(handle = core.BNGetHighLevelILOwnerFunction(self.handle))
+ self._source_function = function.Function(handle = core.BNGetHighLevelILOwnerFunction(self.handle))
if self._arch is None:
self._arch = self._source_function.arch
else:
@@ -655,8 +668,12 @@ class HighLevelILFunction(object):
raise ValueError("IL functions must be created with an associated function")
if self._arch is None:
self._arch = self._source_function.arch
+ if self._arch is None:
+ raise ValueError("IL functions must be created with an associated Architecture")
func_handle = self._source_function.handle
- self.handle = core.BNCreateHighLevelILFunction(arch.handle, func_handle)
+ self.handle = core.BNCreateHighLevelILFunction(self._arch.handle, func_handle)
+ assert self._source_function is not None
+ assert self._arch is not None
def __del__(self):
if self.handle is not None:
@@ -672,6 +689,8 @@ class HighLevelILFunction(object):
def __eq__(self, other):
if not isinstance(other, self.__class__):
return NotImplemented
+ assert self.handle is not None
+ assert other.handle is not None
return ctypes.addressof(self.handle.contents) == ctypes.addressof(other.handle.contents)
def __ne__(self, other):
@@ -682,22 +701,61 @@ class HighLevelILFunction(object):
def __hash__(self):
return hash(('HLIL', self._source_function))
+ def __len__(self):
+ return int(core.BNGetHighLevelILInstructionCount(self.handle))
+
+ def __getitem__(self, i:Union[HighLevelILExpr, HighLevelILInstruction, int]) -> HighLevelILInstruction:
+ if isinstance(i, slice) or isinstance(i, tuple):
+ raise IndexError("expected integer instruction index")
+ if isinstance(i, HighLevelILExpr):
+ return HighLevelILInstruction(self, i.index)
+ # for backwards compatibility
+ if isinstance(i, HighLevelILInstruction):
+ return i
+ if i < -len(self) or i >= len(self):
+ raise IndexError("index out of range")
+ if i < 0:
+ i = len(self) + i
+ return HighLevelILInstruction(self, core.BNGetHighLevelILIndexForInstruction(self.handle, i), False,
+ InstructionIndex(i))
+
+ def __setitem__(self, i, j):
+ raise IndexError("instruction modification not implemented")
+
+ def __iter__(self) -> Generator['HighLevelILBasicBlock', None, None]:
+ count = ctypes.c_ulonglong()
+ blocks = core.BNGetHighLevelILBasicBlockList(self.handle, count)
+ assert blocks is not None, "core.BNGetHighLevelILBasicBlockList returned None"
+ view = None
+ if self._source_function is not None:
+ view = self._source_function.view
+ try:
+ for i in range(0, count.value):
+ core_block = core.BNNewBasicBlockReference(blocks[i])
+ assert core_block is not None
+ yield HighLevelILBasicBlock(view, core_block, self)
+ finally:
+ core.BNFreeBasicBlockList(blocks, count.value)
+
+ def __str__(self) -> str:
+ return str(self.root)
+
@property
- def current_address(self):
+ def current_address(self) -> int:
"""Current IL Address (read/write)"""
return core.BNHighLevelILGetCurrentAddress(self.handle)
@current_address.setter
- def current_address(self, value):
- core.BNHighLevelILSetCurrentAddress(self.handle, self._arch.handle, value)
+ def current_address(self, value:int) -> None:
+ core.BNHighLevelILSetCurrentAddress(self.handle, self.arch.handle, value)
- def set_current_address(self, value, arch = None):
+ def set_current_address(self, value:int, arch:Optional['architecture.Architecture'] = None) -> None:
if arch is None:
- arch = self._arch
+ arch = self.arch
core.BNHighLevelILSetCurrentAddress(self.handle, arch.handle, value)
@property
- def root(self):
+ def root(self) -> Optional[HighLevelILInstruction]:
"""Root of the abstract syntax tree"""
expr_index = core.BNGetHighLevelILRootExpr(self.handle)
if expr_index >= core.BNGetHighLevelILExprCount(self.handle):
@@ -705,53 +763,80 @@ class HighLevelILFunction(object):
return HighLevelILInstruction(self, expr_index)
@root.setter
- def root(self, value):
+ def root(self, value:HighLevelILInstruction) -> None:
core.BNSetHighLevelILRootExpr(value.expr_index)
@property
- def basic_blocks(self):
+ def basic_blocks(self) -> Generator['HighLevelILBasicBlock', None, None]:
"""list of HighLevelILBasicBlock objects (read-only)"""
count = ctypes.c_ulonglong()
blocks = core.BNGetHighLevelILBasicBlockList(self.handle, count)
- result = []
+ assert blocks is not None, "core.BNGetHighLevelILBasicBlockList returned None"
+
view = None
if self._source_function is not None:
view = self._source_function.view
- for i in range(0, count.value):
- result.append(HighLevelILBasicBlock(view, core.BNNewBasicBlockReference(blocks[i]), self))
- core.BNFreeBasicBlockList(blocks, count.value)
- return result
+
+ try:
+ for i in range(0, count.value):
+ core_block = core.BNNewBasicBlockReference(blocks[i])
+ assert core_block is not None
+ yield HighLevelILBasicBlock(view, core_block, self)
+ finally:
+ core.BNFreeBasicBlockList(blocks, count.value)
@property
- def instructions(self):
+ def instructions(self) -> Generator[HighLevelILInstruction, None, None]:
"""A generator of hlil instructions of the current function"""
for block in self.basic_blocks:
for i in block:
yield i
@property
- def ssa_form(self):
+ def ssa_form(self) -> 'HighLevelILFunction':
"""High level IL in SSA form (read-only)"""
result = core.BNGetHighLevelILSSAForm(self.handle)
- if not result:
- return None
+ assert result is not None
return HighLevelILFunction(self._arch, result, self._source_function)
@property
- def non_ssa_form(self):
+ def non_ssa_form(self) -> Optional['HighLevelILFunction']:
"""High level IL in non-SSA (default) form (read-only)"""
result = core.BNGetHighLevelILNonSSAForm(self.handle)
if not result:
return None
return HighLevelILFunction(self._arch, result, self._source_function)
- def get_ssa_instruction_index(self, instr):
+ @property
+ def arch(self) -> 'architecture.Architecture':
+ assert self._arch is not None
+ return self._arch
+
+ @property
+ def source_function(self) -> 'function.Function':
+ assert self._source_function is not None
+ return self._source_function
+
+ @property
+ def medium_level_il(self) -> Optional['mediumlevelil.MediumLevelILFunction']:
+ """Medium level IL for this function"""
+ result = core.BNGetMediumLevelILForHighLevelILFunction(self.handle)
+ if not result:
+ return None
+ return mediumlevelil.MediumLevelILFunction(self._arch, result, self._source_function)
+
+ @property
+ def mlil(self) -> Optional['mediumlevelil.MediumLevelILFunction']:
+ """Alias for medium_level_il"""
+ return self.medium_level_il
+
+ def get_ssa_instruction_index(self, instr:int) -> int:
return core.BNGetHighLevelILSSAInstructionIndex(self.handle, instr)
- def get_non_ssa_instruction_index(self, instr):
+ def get_non_ssa_instruction_index(self, instr:int) -> int:
return core.BNGetHighLevelILNonSSAInstructionIndex(self.handle, instr)
- def get_ssa_var_definition(self, ssa_var):
+ def get_ssa_var_definition(self, ssa_var:'mediumlevelil.SSAVariable') -> Optional[HighLevelILInstruction]:
var_data = core.BNVariable()
var_data.type = ssa_var.var.source_type
var_data.index = ssa_var.var.index
@@ -761,35 +846,37 @@ class HighLevelILFunction(object):
return None
return HighLevelILInstruction(self, result)
- def get_ssa_memory_definition(self, version):
+ def get_ssa_memory_definition(self, version:int) -> Optional[HighLevelILInstruction]:
result = core.BNGetHighLevelILSSAMemoryDefinition(self.handle, version)
if result >= core.BNGetHighLevelILExprCount(self.handle):
return None
return HighLevelILInstruction(self, result)
- def get_ssa_var_uses(self, ssa_var):
+ def get_ssa_var_uses(self, ssa_var:'mediumlevelil.SSAVariable') -> List[HighLevelILInstruction]:
count = ctypes.c_ulonglong()
var_data = core.BNVariable()
var_data.type = ssa_var.var.source_type
var_data.index = ssa_var.var.index
var_data.storage = ssa_var.var.storage
instrs = core.BNGetHighLevelILSSAVarUses(self.handle, var_data, ssa_var.version, count)
+ assert instrs is not None, "core.BNGetHighLevelILSSAVarUses returned None"
result = []
for i in range(0, count.value):
result.append(HighLevelILInstruction(self, instrs[i]))
core.BNFreeILInstructionList(instrs)
return result
- def get_ssa_memory_uses(self, version):
+ def get_ssa_memory_uses(self, version:int) -> List[HighLevelILInstruction]:
count = ctypes.c_ulonglong()
instrs = core.BNGetHighLevelILSSAMemoryUses(self.handle, version, count)
+ assert instrs is not None, "core.BNGetHighLevelILSSAMemoryUses returned None"
result = []
for i in range(0, count.value):
result.append(HighLevelILInstruction(self, instrs[i]))
core.BNFreeILInstructionList(instrs)
return result
- def is_ssa_var_live(self, ssa_var):
+ def is_ssa_var_live(self, ssa_var:'mediumlevelil.SSAVariable') -> bool:
"""
``is_ssa_var_live`` determines if ``ssa_var`` is live at any point in the function
@@ -803,81 +890,43 @@ class HighLevelILFunction(object):
var_data.storage = ssa_var.var.storage
return core.BNIsHighLevelILSSAVarLive(self.handle, var_data, ssa_var.version)
- def get_var_definitions(self, var):
+ def get_var_definitions(self, var:'variable.Variable') -> List[HighLevelILInstruction]:
count = ctypes.c_ulonglong()
var_data = core.BNVariable()
var_data.type = var.source_type
var_data.index = var.index
var_data.storage = var.storage
instrs = core.BNGetHighLevelILVariableDefinitions(self.handle, var_data, count)
+ assert instrs is not None, "core.BNGetHighLevelILVariableDefinitions returned None"
result = []
for i in range(0, count.value):
result.append(HighLevelILInstruction(self, instrs[i]))
core.BNFreeILInstructionList(instrs)
return result
- def get_var_uses(self, var):
+ def get_var_uses(self, var:'variable.Variable') -> List[HighLevelILInstruction]:
count = ctypes.c_ulonglong()
var_data = core.BNVariable()
var_data.type = var.source_type
var_data.index = var.index
var_data.storage = var.storage
instrs = core.BNGetHighLevelILVariableUses(self.handle, var_data, count)
+ assert instrs is not None, "core.BNGetHighLevelILVariableUses returned None"
result = []
for i in range(0, count.value):
result.append(HighLevelILInstruction(self, instrs[i]))
core.BNFreeILInstructionList(instrs)
return result
- def __setattr__(self, name, value):
- try:
- object.__setattr__(self, name, value)
- except AttributeError:
- raise AttributeError("attribute '%s' is read only" % name)
-
- def __len__(self):
- return int(core.BNGetHighLevelILInstructionCount(self.handle))
-
- def __getitem__(self, i):
- if isinstance(i, slice) or isinstance(i, tuple):
- raise IndexError("expected integer instruction index")
- if isinstance(i, HighLevelILExpr):
- return HighLevelILInstruction(self, i.index)
- # for backwards compatibility
- if isinstance(i, HighLevelILInstruction):
- return i
- if i < -len(self) or i >= len(self):
- raise IndexError("index out of range")
- if i < 0:
- i = len(self) + i
- return HighLevelILInstruction(self, core.BNGetHighLevelILIndexForInstruction(self.handle, i), False, i)
-
- def __setitem__(self, i, j):
- raise IndexError("instruction modification not implemented")
-
- def __iter__(self):
- count = ctypes.c_ulonglong()
- blocks = core.BNGetHighLevelILBasicBlockList(self.handle, count)
- view = None
- if self._source_function is not None:
- view = self._source_function.view
- try:
- for i in range(0, count.value):
- yield HighLevelILBasicBlock(view, core.BNNewBasicBlockReference(blocks[i]), self)
- finally:
- core.BNFreeBasicBlockList(blocks, count.value)
-
- def __str__(self):
- return str(self.root)
-
- def expr(self, operation, a = 0, b = 0, c = 0, d = 0, e = 0, size = 0):
+ def expr(self, operation:Union[str, HighLevelILOperation], a:int = 0, b:int = 0, c:int = 0,
+ d:int = 0, e:int = 0, size:int = 0) -> HighLevelILExpr:
if isinstance(operation, str):
- operation = HighLevelILOperation[operation]
+ operation_value = HighLevelILOperation[operation]
elif isinstance(operation, HighLevelILOperation):
- operation = operation.value
- return HighLevelILExpr(core.BNHighLevelILAddExpr(self.handle, operation, size, a, b, c, d, e))
+ operation_value = operation.value
+ return HighLevelILExpr(core.BNHighLevelILAddExpr(self.handle, operation_value, size, a, b, c, d, e))
- def add_operand_list(self, operands):
+ def add_operand_list(self, operands:List[int]) -> HighLevelILExpr:
"""
``add_operand_list`` returns an operand list expression for the given list of integer operands.
@@ -890,7 +939,7 @@ class HighLevelILFunction(object):
operand_list[i] = operands[i]
return HighLevelILExpr(core.BNHighLevelILAddOperandList(self.handle, operand_list, len(operands)))
- def finalize(self):
+ def finalize(self) -> None:
"""
``finalize`` ends the function and computes the list of basic blocks.
@@ -898,21 +947,12 @@ class HighLevelILFunction(object):
"""
core.BNFinalizeHighLevelILFunction(self.handle)
- def create_graph(self, settings = None):
+ def create_graph(self, settings:'function.DisassemblySettings'=None) -> 'flowgraph.CoreFlowGraph':
if settings is not None:
settings_obj = settings.handle
else:
settings_obj = None
- return binaryninja.flowgraph.CoreFlowGraph(core.BNCreateHighLevelILFunctionGraph(self.handle, settings_obj))
-
- @property
- def arch(self):
- """ """
- return self._arch
-
- @arch.setter
- def arch(self, value):
- self._arch = value
+ return flowgraph.CoreFlowGraph(core.BNCreateHighLevelILFunctionGraph(self.handle, settings_obj))
@property
def source_function(self):
@@ -981,7 +1021,7 @@ class HighLevelILFunction(object):
"""Alias for medium_level_il"""
return self.medium_level_il
- def get_medium_level_il_expr_index(self, expr):
+ def get_medium_level_il_expr_index(self, expr:ExpressionIndex) -> Optional['mediumlevelil.ExpressionIndex']:
medium_il = self.medium_level_il
if medium_il is None:
return None
@@ -993,24 +1033,26 @@ class HighLevelILFunction(object):
return None
return result
- def get_medium_level_il_expr_indexes(self, expr):
+ def get_medium_level_il_expr_indexes(self, expr:ExpressionIndex) -> List['mediumlevelil.ExpressionIndex']:
count = ctypes.c_ulonglong()
exprs = core.BNGetMediumLevelILExprIndexesFromHighLevelIL(self.handle, expr, count)
+ assert exprs is not None, "core.BNGetMediumLevelILExprIndexesFromHighLevelIL returned None"
result = []
for i in range(0, count.value):
result.append(exprs[i])
core.BNFreeILInstructionList(exprs)
return result
- def get_label(self, label_idx):
+ def get_label(self, label_idx:int) -> Optional[HighLevelILInstruction]:
result = core.BNGetHighLevelILExprIndexForLabel(self.handle, label_idx)
if result >= core.BNGetHighLevelILExprCount(self.handle):
return None
return HighLevelILInstruction(self, result)
- def get_label_uses(self, label_idx):
+ def get_label_uses(self, label_idx:int) -> List[HighLevelILInstruction]:
count = ctypes.c_ulonglong()
uses = core.BNGetHighLevelILUsesForLabel(self.handle, label_idx, count)
+ assert uses is not None, "core.BNGetHighLevelILUsesForLabel returned None"
result = []
for i in range(0, count.value):
result.append(HighLevelILInstruction(self, uses[i]))
@@ -1019,15 +1061,15 @@ class HighLevelILFunction(object):
class HighLevelILBasicBlock(basicblock.BasicBlock):
- def __init__(self, view, handle, owner):
+ def __init__(self, view:Optional['binaryview.BinaryView'], handle:core.BNBasicBlock, owner:HighLevelILFunction):
super(HighLevelILBasicBlock, self).__init__(handle, view)
- self.il_function = owner
+ self._il_function = owner
- def __iter__(self):
+ def __iter__(self) -> Generator[HighLevelILInstruction, None, None]:
for idx in range(self.start, self.end):
yield self.il_function[idx]
- def __getitem__(self, idx):
+ def __getitem__(self, idx) -> HighLevelILInstruction:
size = self.end - self.start
if isinstance(idx, slice):
return [self[index] for index in range(*idx.indices(size))]
@@ -1038,7 +1080,7 @@ class HighLevelILBasicBlock(basicblock.BasicBlock):
else:
return self.il_function[self.end + idx]
- def _create_instance(self, handle, view):
+ def _create_instance(self, handle:core.BNBasicBlock, view:'binaryview.BinaryView'):
"""Internal method by super to instantiate child instances"""
return HighLevelILBasicBlock(view, handle, self.il_function)
@@ -1054,10 +1096,9 @@ class HighLevelILBasicBlock(basicblock.BasicBlock):
return False
@property
- def il_function(self):
- """ """
- return self._il_function
+ def instruction_count(self) -> int:
+ return self.end - self.start
- @il_function.setter
- def il_function(self, value):
- self._il_function = value
+ @property
+ def il_function(self) -> HighLevelILFunction:
+ return self._il_function