summaryrefslogtreecommitdiff
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
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.
-rw-r--r--binaryninjaapi.h1
-rw-r--r--binaryninjacore.h23
-rw-r--r--function.cpp21
-rw-r--r--python/function.py21
-rw-r--r--python/highlevelil.py57
-rw-r--r--python/lowlevelil.py142
-rw-r--r--python/mediumlevelil.py48
7 files changed, 266 insertions, 47 deletions
diff --git a/binaryninjaapi.h b/binaryninjaapi.h
index 5a0773ef..f415f82c 100644
--- a/binaryninjaapi.h
+++ b/binaryninjaapi.h
@@ -3381,7 +3381,6 @@ __attribute__ ((format (printf, 1, 2)))
bool GetStackVariableAtFrameOffset(Architecture* arch, uint64_t addr, int64_t offset, VariableNameAndType& var);
std::map<Variable, VariableNameAndType> GetVariables();
- std::set<Variable> GetILVariables(BNFunctionGraphType ilType);
void CreateAutoVariable(const Variable& var, const Confidence<Ref<Type>>& type, const std::string& name,
bool ignoreDisjointUses = false);
void CreateUserVariable(const Variable& var, const Confidence<Ref<Type>>& type, const std::string& name,
diff --git a/binaryninjacore.h b/binaryninjacore.h
index 35b26d2a..f8ded517 100644
--- a/binaryninjacore.h
+++ b/binaryninjacore.h
@@ -970,7 +970,7 @@ extern "C"
MLIL_STORE_STRUCT, // Not valid in SSA form (see MLIL_STORE_STRUCT_SSA)
MLIL_VAR, // Not valid in SSA form (see MLIL_VAR_SSA)
MLIL_VAR_FIELD, // Not valid in SSA form (see MLIL_VAR_SSA_FIELD)
- MLIL_VAR_SPLIT, // Not valid in SSA form (see MLIL_VAR_SSA)
+ MLIL_VAR_SPLIT, // Not valid in SSA form (see MLIL_VAR_SPLIT_SSA)
MLIL_ADDRESS_OF,
MLIL_ADDRESS_OF_FIELD,
MLIL_CONST,
@@ -3453,6 +3453,7 @@ __attribute__ ((format (printf, 1, 2)))
BINARYNINJACOREAPI bool BNIsILBasicBlock(BNBasicBlock* block);
BINARYNINJACOREAPI bool BNIsLowLevelILBasicBlock(BNBasicBlock* block);
BINARYNINJACOREAPI bool BNIsMediumLevelILBasicBlock(BNBasicBlock* block);
+ BINARYNINJACOREAPI BNFunctionGraphType BNGetBasicBlockFunctionGraphType(BNBasicBlock* block);
BINARYNINJACOREAPI BNLowLevelILFunction* BNGetBasicBlockLowLevelILFunction(BNBasicBlock* block);
BINARYNINJACOREAPI BNMediumLevelILFunction* BNGetBasicBlockMediumLevelILFunction(BNBasicBlock* block);
BINARYNINJACOREAPI bool BNGetBasicBlockInstructionContainingAddress(BNBasicBlock* block,
@@ -3584,7 +3585,6 @@ __attribute__ ((format (printf, 1, 2)))
BINARYNINJACOREAPI void BNFreeVariableNameAndType(BNVariableNameAndType* var);
BINARYNINJACOREAPI BNVariableNameAndType* BNGetFunctionVariables(BNFunction* func, size_t* count);
- BINARYNINJACOREAPI BNVariable* BNGetFunctionILVariables(BNFunction* func, BNFunctionGraphType ilType, size_t* count);
BINARYNINJACOREAPI void BNCreateAutoVariable(BNFunction* func, const BNVariable* var, BNTypeWithConfidence* type,
const char* name, bool ignoreDisjointUses);
BINARYNINJACOREAPI void BNCreateUserVariable(BNFunction* func, const BNVariable* var, BNTypeWithConfidence* type,
@@ -4207,6 +4207,19 @@ __attribute__ ((format (printf, 1, 2)))
BINARYNINJACOREAPI BNPossibleValueSet BNGetLowLevelILPossibleStackContentsAfterInstruction(BNLowLevelILFunction* func,
int64_t offset, size_t len, size_t instr, BNDataFlowQueryOption* options, size_t optionCount);
+ BINARYNINJACOREAPI uint32_t* BNGetLowLevelRegisters(BNLowLevelILFunction* func, size_t* count);
+ BINARYNINJACOREAPI uint32_t* BNGetLowLevelRegisterStacks(BNLowLevelILFunction* func, size_t* count);
+ BINARYNINJACOREAPI uint32_t* BNGetLowLevelFlags(BNLowLevelILFunction* func, size_t* count);
+
+ BINARYNINJACOREAPI size_t* BNGetLowLevelRegisterSSAVersions(BNLowLevelILFunction* func, const uint32_t var, size_t* count);
+ BINARYNINJACOREAPI size_t* BNGetLowLevelRegisterStackSSAVersions(BNLowLevelILFunction* func, const uint32_t var, size_t* count);
+ BINARYNINJACOREAPI size_t* BNGetLowLevelFlagSSAVersions(BNLowLevelILFunction* func, const uint32_t var, size_t* count);
+
+ BINARYNINJACOREAPI size_t* BNGetLowLevelMemoryVersions(BNLowLevelILFunction* func, size_t* count);
+
+ BINARYNINJACOREAPI void BNFreeLLILVariablesList(uint32_t* vars);
+ BINARYNINJACOREAPI void BNFreeLLILVariableVersionList(size_t* versions);
+
BINARYNINJACOREAPI BNMediumLevelILFunction* BNGetMediumLevelILForLowLevelIL(BNLowLevelILFunction* func);
BINARYNINJACOREAPI BNMediumLevelILFunction* BNGetMappedMediumLevelIL(BNLowLevelILFunction* func);
BINARYNINJACOREAPI size_t BNGetMediumLevelILInstructionIndex(BNLowLevelILFunction* func, size_t instr);
@@ -4297,6 +4310,9 @@ __attribute__ ((format (printf, 1, 2)))
BINARYNINJACOREAPI bool BNIsMediumLevelILSSAVarLive(BNMediumLevelILFunction* func,
const BNVariable* var, size_t version);
+ BINARYNINJACOREAPI BNVariable* BNGetMediumLevelILVariables(BNMediumLevelILFunction* func, size_t * count);
+ BINARYNINJACOREAPI size_t* BNGetMediumLevelILVariableSSAVersions(BNMediumLevelILFunction* func, const BNVariable* var, size_t * count);
+
BINARYNINJACOREAPI size_t* BNGetMediumLevelILVariableDefinitions(BNMediumLevelILFunction* func,
const BNVariable* var, size_t* count);
BINARYNINJACOREAPI size_t* BNGetMediumLevelILVariableUses(BNMediumLevelILFunction* func,
@@ -4422,6 +4438,9 @@ __attribute__ ((format (printf, 1, 2)))
BINARYNINJACOREAPI bool BNIsHighLevelILSSAVarLive(BNHighLevelILFunction* func,
const BNVariable* var, size_t version);
+ BINARYNINJACOREAPI BNVariable* BNGetHighLevelILVariables(BNHighLevelILFunction* func, size_t* count);
+ BINARYNINJACOREAPI size_t* BNGetHighLevelILVariableSSAVersions(BNHighLevelILFunction* func, const BNVariable* var, size_t * count);
+
BINARYNINJACOREAPI size_t* BNGetHighLevelILVariableDefinitions(BNHighLevelILFunction* func,
const BNVariable* var, size_t* count);
BINARYNINJACOREAPI size_t* BNGetHighLevelILVariableUses(BNHighLevelILFunction* func,
diff --git a/function.cpp b/function.cpp
index 70985d64..9c9e5e68 100644
--- a/function.cpp
+++ b/function.cpp
@@ -1107,23 +1107,6 @@ map<Variable, VariableNameAndType> Function::GetVariables()
}
-set<Variable> Function::GetILVariables(BNFunctionGraphType ilType)
-{
- size_t count;
- auto* vars = BNGetFunctionILVariables(m_object, ilType, &count);
-
- set<Variable> result;
- for (size_t i = 0; i < count; i++)
- {
- Variable v(vars[i]);
- result.insert(v);
- }
-
- BNFreeVariableList(vars);
- return result;
-}
-
-
void Function::CreateAutoVariable(const Variable& var, const Confidence<Ref<Type>>& type,
const string& name, bool ignoreDisjointUses)
{
@@ -2183,7 +2166,7 @@ vector<ILReferenceSource> Function::GetMediumLevelILVariableReferences(const Var
varData.type = var.type;
varData.index = var.index;
varData.storage = var.storage;
-
+
BNILReferenceSource* refs = BNGetMediumLevelILVariableReferences(m_object, &varData, &count);
vector<ILReferenceSource> result;
@@ -2268,7 +2251,7 @@ vector<ILReferenceSource> Function::GetHighLevelILVariableReferences(const Varia
varData.type = var.type;
varData.index = var.index;
varData.storage = var.storage;
-
+
BNILReferenceSource* refs = BNGetHighLevelILVariableReferences(m_object, &varData, &count);
vector<ILReferenceSource> result;
diff --git a/python/function.py b/python/function.py
index 64aacb05..e3d0521c 100644
--- a/python/function.py
+++ b/python/function.py
@@ -828,7 +828,9 @@ class Variable(object):
self._type = var_type
def __repr__(self):
- return "<var %s %s%s>" % (self.type.get_string_before_name(), self.name, self.type.get_string_after_name())
+ if self.type is None:
+ return f"<var unknown-type {self.name}>"
+ return f"<var {self.type.get_string_before_name()} {self.name}{self.type.get_string_after_name()}>"
def __str__(self):
return self.name
@@ -2264,23 +2266,6 @@ class Function(object):
core.BNFreeVariableNameAndTypeList(v, count.value)
return result
- def get_il_vars(self, il_type: FunctionGraphType) -> List[Variable]:
- """
- Get a (read-only) list of the variables used in the given IL. Only
- accepts ``MediumLevelILFunctionGraph`` or ``HighLevelILFunctionGraph``
- for ``il_type``, otherwise nothing will be returned.
- """
-
- count = ctypes.c_ulonglong()
- v = core.BNGetFunctionILVariables(self.handle, il_type, count)
-
- result = []
- for i in range(0, count.value):
- result.append(Variable(self, v[i].type, v[i].index, v[i].storage))
-
- core.BNFreeVariableList(v, count.value)
- return result
-
@property
def indirect_branches(self):
"""List of indirect branches (read-only)"""
diff --git a/python/highlevelil.py b/python/highlevelil.py
index 55d979f8..45f6def4 100644
--- a/python/highlevelil.py
+++ b/python/highlevelil.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2019 Vector 35 Inc
+# Copyright (c) 2019-2021 Vector 35 Inc
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
@@ -20,11 +20,12 @@
import ctypes
import struct
+from typing import List
# Binary Ninja components
import binaryninja
from binaryninja import _binaryninjacore as core
-from binaryninja.enums import HighLevelILOperation, InstructionTextTokenType
+from binaryninja.enums import HighLevelILOperation, FunctionGraphType
from binaryninja import function
from binaryninja import lowlevelil
from binaryninja import mediumlevelil
@@ -661,6 +662,13 @@ class HighLevelILFunction(object):
if self.handle is not None:
core.BNFreeHighLevelILFunction(self.handle)
+ def __repr__(self):
+ arch = self.source_function.arch
+ if arch:
+ return "<hlil func: %s@%#x>" % (arch.name, self.source_function.start)
+ else:
+ return "<hlil func: %#x>" % self.source_function.start
+
def __eq__(self, other):
if not isinstance(other, self.__class__):
return NotImplemented
@@ -916,6 +924,51 @@ class HighLevelILFunction(object):
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 vars(self) -> List["binaryninja.function.Variable"]:
+ """This gets just the HLIL variables - you may be interested in the union of `HighLevelIlFunction.source_function.param_vars` for all the variables used in the function"""
+ if self.source_function is None:
+ return []
+
+ if self.il_form == FunctionGraphType.HighLevelILFunctionGraph or self.il_form == FunctionGraphType.HighLevelILSSAFormFunctionGraph:
+ count = ctypes.c_ulonglong()
+ core_variables = core.BNGetHighLevelILVariables(self.handle, count)
+ result = []
+ for var_i in range(count.value):
+ result.append(function.Variable(self.source_function, core_variables[var_i].type, core_variables[var_i].index, core_variables[var_i].storage))
+ core.BNFreeVariableList(core_variables)
+ return result
+ return []
+
+ @property
+ def ssa_vars(self) -> List["binaryninja.mediumlevelil.SSAVariable"]:
+ """This gets just the HLIL SSA variables - you may be interested in the union of `HighLevelIlFunction.source_function.param_vars` for all the variables used in the function"""
+ if self.source_function is None:
+ return []
+
+ if self.il_form == FunctionGraphType.HighLevelILSSAFormFunctionGraph:
+ variable_count = ctypes.c_ulonglong()
+ core_variables = core.BNGetHighLevelILVariables(self.handle, variable_count)
+ result = []
+ for var_i in range(variable_count.value):
+ version_count = ctypes.c_ulonglong()
+ versions = core.BNGetHighLevelILVariableSSAVersions(self.handle, core_variables[var_i], version_count)
+
+ for version_i in range(version_count.value):
+ result.append(mediumlevelil.SSAVariable(function.Variable(self.source_function, core_variables[var_i].type, core_variables[var_i].index, core_variables[var_i].storage), versions[version_i]))
+ core.BNFreeILInstructionList(versions)
+
+ core.BNFreeVariableList(core_variables)
+ return result
+
+ return []
+
+ @property
def medium_level_il(self):
"""Medium level IL for this function"""
result = core.BNGetMediumLevelILForHighLevelILFunction(self.handle)
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
diff --git a/python/mediumlevelil.py b/python/mediumlevelil.py
index 93f83d1b..c2e9a5eb 100644
--- a/python/mediumlevelil.py
+++ b/python/mediumlevelil.py
@@ -20,11 +20,12 @@
import ctypes
import struct
+from typing import List
# Binary Ninja components
import binaryninja
from binaryninja import _binaryninjacore as core
-from binaryninja.enums import MediumLevelILOperation, InstructionTextTokenType, ILBranchDependence, DataFlowQueryOption
+from binaryninja.enums import MediumLevelILOperation, FunctionGraphType, ILBranchDependence
from binaryninja import basicblock #required for MediumLevelILBasicBlock argument
from binaryninja import function
from binaryninja import types
@@ -1239,6 +1240,51 @@ class MediumLevelILFunction(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 vars(self) -> List["binaryninja.function.Variable"]:
+ """This gets just the MLIL variables - you may be interested in the union of `MediumLevelIlFunction.source_function.param_vars` for all the variables used in the function"""
+ if self.source_function is None:
+ return []
+
+ if self.il_form in [FunctionGraphType.MediumLevelILFunctionGraph, FunctionGraphType.MediumLevelILSSAFormFunctionGraph, FunctionGraphType.MappedMediumLevelILFunctionGraph, FunctionGraphType.MappedMediumLevelILSSAFormFunctionGraph]:
+ count = ctypes.c_ulonglong()
+ core_variables = core.BNGetMediumLevelILVariables(self.handle, count)
+ result = []
+ for var_i in range(count.value):
+ result.append(function.Variable(self.source_function, core_variables[var_i].type, core_variables[var_i].index, core_variables[var_i].storage))
+ core.BNFreeVariableList(core_variables)
+ return result
+ return []
+
+ @property
+ def ssa_vars(self) -> List["binaryninja.mediumlevelil.SSAVariable"]:
+ """This gets just the MLIL SSA variables - you may be interested in the union of `MediumLevelIlFunction.source_function.param_vars` for all the variables used in the function"""
+ if self.source_function is None:
+ return []
+
+ if self.il_form in [FunctionGraphType.MediumLevelILSSAFormFunctionGraph, FunctionGraphType.MappedMediumLevelILSSAFormFunctionGraph]:
+ variable_count = ctypes.c_ulonglong()
+ core_variables = core.BNGetMediumLevelILVariables(self.handle, variable_count)
+ result = []
+ for var_i in range(variable_count.value):
+ version_count = ctypes.c_ulonglong()
+ versions = core.BNGetMediumLevelILVariableSSAVersions(self.handle, core_variables[var_i], version_count)
+
+ for version_i in range(version_count.value):
+ result.append(SSAVariable(function.Variable(self.source_function, core_variables[var_i].type, core_variables[var_i].index, core_variables[var_i].storage), versions[version_i]))
+ core.BNFreeILInstructionList(versions)
+
+ core.BNFreeVariableList(core_variables)
+ return result
+
+ return []
+
class MediumLevelILBasicBlock(basicblock.BasicBlock):
def __init__(self, view, handle, owner):