summaryrefslogtreecommitdiff
path: root/python/lowlevelil.py
diff options
context:
space:
mode:
authorKyleMiles <krm504@nyu.edu>2021-07-20 16:28:33 -0400
committerKyleMiles <krm504@nyu.edu>2021-07-26 16:09:18 -0400
commitd999ff47c7c81030e5c592f93d8a1415de058882 (patch)
tree1f8fa0df54d4a3324ebc713179e128b0a662e9d8 /python/lowlevelil.py
parent661d7c953e7a81e82f3eb6a70c03041354d73bfd (diff)
Python API : Fix copyright year, add .vars to IL functions, remove BNGetFunctionILVariables, prevent variables without types (from Mapped MLIL) from erroring out in function.Variable's __repr__, added BNGetLowLevel-Registers, RegisterStacks, Flags, MemoryVersions, and their respective SSA versions, added `LowLevelILFunction`- `.vars`, `.ssa_vars`, `.registers`, `.register_stacks`, `.flags`, `.memory_versions` and ssa versions.
Diffstat (limited to 'python/lowlevelil.py')
-rw-r--r--python/lowlevelil.py142
1 files changed, 138 insertions, 4 deletions
diff --git a/python/lowlevelil.py b/python/lowlevelil.py
index 11600924..a8814d8e 100644
--- a/python/lowlevelil.py
+++ b/python/lowlevelil.py
@@ -24,9 +24,11 @@ import struct
# Binary Ninja components
import binaryninja
from binaryninja import _binaryninjacore as core
-from binaryninja.enums import LowLevelILOperation, LowLevelILFlagCondition, InstructionTextTokenType
+from binaryninja.enums import LowLevelILOperation, LowLevelILFlagCondition, FunctionGraphType, VariableSourceType
from binaryninja import basicblock #required for LowLevelILBasicBlock
+from typing import List, Union
+
# 2-3 compatibility
from binaryninja import range
@@ -40,6 +42,7 @@ class LowLevelILLabel(object):
self.handle = handle
+# TODO : It would be nice to add a `.versions` to IL vars (regs, stack regs, flags) to see all the SSA versions of the given variable. Would need to associate the source function
class ILRegister(object):
def __init__(self, arch, reg):
self._arch = arch
@@ -55,7 +58,7 @@ class ILRegister(object):
return self._arch.regs[self._name]
def __repr__(self):
- return self._name
+ return f"<reg {self._name}>"
def __str__(self):
return self._name
@@ -123,7 +126,7 @@ class ILRegisterStack(object):
return self._arch.reg_stacks[self._name]
def __repr__(self):
- return self._name
+ return f"<reg-stack {self._name}>"
def __str__(self):
return self._name
@@ -180,7 +183,7 @@ class ILFlag(object):
self._name = self._arch.get_flag_name(self._index)
def __repr__(self):
- return self._name
+ return f"<flag {self._name}>"
def __str__(self):
return self._name
@@ -1496,6 +1499,137 @@ class LowLevelILFunction(object):
def source_function(self, value):
self._source_function = value
+ @property
+ def il_form(self) -> "binaryninja.enums.FunctionGraphType":
+ if len(self.basic_blocks) < 1:
+ return FunctionGraphType.InvalidILViewType
+ return FunctionGraphType(core.BNGetBasicBlockFunctionGraphType(self.basic_blocks[0].handle))
+
+ @property
+ def registers(self) -> List[ILRegister]:
+ """ List of registers used in this IL """
+ count = ctypes.c_ulonglong()
+ registers = core.BNGetLowLevelRegisters(self.handle, count)
+
+ result = []
+ for var_i in range(count.value):
+ result.append(ILRegister(self.arch, registers[var_i]))
+ core.BNFreeLLILVariablesList(registers)
+ return result
+
+ @property
+ def register_stacks(self) -> List[ILRegisterStack]:
+ """ List of register stacks used in this IL """
+ count = ctypes.c_ulonglong()
+ registerStacks = core.BNGetLowLevelRegisterStacks(self.handle, count)
+
+ result = []
+ for var_i in range(count.value):
+ result.append(ILRegisterStack(self.arch, registerStacks[var_i]))
+ core.BNFreeLLILVariablesList(registerStacks)
+ return result
+
+ @property
+ def flags(self) -> List[ILFlag]:
+ """ List of flags used in this IL """
+ count = ctypes.c_ulonglong()
+ flags = core.BNGetLowLevelFlags(self.handle, count)
+
+ result = []
+ for var_i in range(count.value):
+ result.append(ILFlag(self.arch, flags[var_i]))
+ core.BNFreeLLILVariablesList(flags)
+ return result
+
+ @property
+ def ssa_registers(self) -> List[SSARegister]:
+ """ List of SSA registers used in this IL """
+ if self.il_form != FunctionGraphType.LowLevelILSSAFormFunctionGraph:
+ return []
+
+ register_count = ctypes.c_ulonglong()
+ registers = core.BNGetLowLevelRegisters(self.handle, register_count)
+ result = []
+ for var_i in range(register_count.value):
+ version_count = ctypes.c_ulonglong()
+ versions = core.BNGetLowLevelRegisterSSAVersions(self.handle, registers[var_i], version_count)
+
+ for version_i in range(version_count.value):
+ result.append(SSARegister(ILRegister(self.arch, registers[var_i]), versions[version_i]))
+ core.BNFreeLLILVariableVersionList(versions)
+
+ core.BNFreeLLILVariablesList(registers)
+ return result
+
+ @property
+ def ssa_register_stacks(self) -> List[SSARegisterStack]:
+ """ List of SSA register stacks used in this IL """
+ if self.il_form != FunctionGraphType.LowLevelILSSAFormFunctionGraph:
+ return []
+
+ register_stack_count = ctypes.c_ulonglong()
+ register_stacks = core.BNGetLowLevelRegisterStacks(self.handle, register_stack_count)
+ result = []
+ for var_i in range(register_stack_count.value):
+ version_count = ctypes.c_ulonglong()
+ versions = core.BNGetLowLevelRegisterStackSSAVersions(self.handle, register_stacks[var_i], version_count)
+
+ for version_i in range(version_count.value):
+ result.append(SSARegisterStack(ILRegisterStack(self.arch, register_stacks[var_i]), versions[version_i]))
+ core.BNFreeLLILVariableVersionList(versions)
+
+ core.BNFreeLLILVariablesList(register_stacks)
+ return result
+
+ @property
+ def ssa_flags(self) -> List[SSAFlag]:
+ """ List of SSA flags used in this IL """
+ if self.il_form != FunctionGraphType.LowLevelILSSAFormFunctionGraph:
+ return []
+
+ flag_count = ctypes.c_ulonglong()
+ flags = core.BNGetLowLevelFlags(self.handle, flag_count)
+ result = []
+ for var_i in range(flag_count.value):
+ version_count = ctypes.c_ulonglong()
+ versions = core.BNGetLowLevelFlagSSAVersions(self.handle, flags[var_i], version_count)
+
+ for version_i in range(version_count.value):
+ result.append(SSAFlag(ILFlag(self.arch, flags[var_i]), versions[version_i]))
+ core.BNFreeLLILVariableVersionList(versions)
+
+ core.BNFreeLLILVariablesList(flags)
+ return result
+
+ @property
+ def memory_versions(self) -> List[int]:
+ """ List of memory versions used in this IL """
+ count = ctypes.c_ulonglong()
+ memory_versions = core.BNGetLowLevelMemoryVersions(self.handle, count)
+
+ result = []
+ for version_i in range(count.value):
+ result.append(memory_versions[version_i])
+ core.BNFreeLLILVariableVersionList(memory_versions)
+ return result
+
+ @property
+ def vars(self) -> List[Union[ILRegister, ILRegisterStack, ILFlag]]:
+ """This is the union `LowLevelILFunction.registers`, `LowLevelILFunction.register_stacks`, and `LowLevelILFunction.flags`"""
+ if self._source_function is None:
+ return []
+
+ if self.il_form in [FunctionGraphType.LiftedILFunctionGraph, FunctionGraphType.LowLevelILFunctionGraph, FunctionGraphType.LowLevelILSSAFormFunctionGraph]:
+ return self.registers + self.register_stacks + self.flags
+ return []
+
+ @property
+ def ssa_vars(self) -> List["binaryninja.mediumlevelil.SSAVariable"]:
+ """This is the union `LowLevelILFunction.ssa_registers`, `LowLevelILFunction.ssa_register_stacks`, and `LowLevelILFunction.ssa_flags`"""
+ if self.il_form == FunctionGraphType.LowLevelILSSAFormFunctionGraph:
+ return self.ssa_registers + self.ssa_register_stacks + self.ssa_flags
+ return []
+
def get_instruction_start(self, addr, arch = None):
if arch is None:
arch = self._arch