summaryrefslogtreecommitdiff
path: root/python/function.py
diff options
context:
space:
mode:
Diffstat (limited to 'python/function.py')
-rw-r--r--python/function.py86
1 files changed, 74 insertions, 12 deletions
diff --git a/python/function.py b/python/function.py
index db4ca0f5..10583b58 100644
--- a/python/function.py
+++ b/python/function.py
@@ -171,6 +171,8 @@ class PossibleValueSet(object):
self.reg = arch.get_reg_name(value.value)
elif value.state == RegisterValueType.ConstantValue:
self.value = value.value
+ elif value.state == RegisterValueType.ConstantPointerValue:
+ self.value = value.value
elif value.state == RegisterValueType.StackFrameOffset:
self.offset = value.value
elif value.state == RegisterValueType.SignedRangeValue:
@@ -212,6 +214,8 @@ class PossibleValueSet(object):
return "<entry %s>" % self.reg
if self.type == RegisterValueType.ConstantValue:
return "<const %#x>" % self.value
+ if self.type == RegisterValueType.ConstantPointerValue:
+ return "<const ptr %#x>" % self.value
if self.type == RegisterValueType.StackFrameOffset:
return "<stack frame offset %#x>" % self.offset
if self.type == RegisterValueType.SignedRangeValue:
@@ -290,10 +294,10 @@ class Variable(object):
return self.name
def __eq__(self, other):
- return self.identifier == other.identifier
+ return (self.identifier, self.function) == (other.identifier, other.function)
def __hash__(self):
- return hash(self.identifier)
+ return hash((self.identifier, self.function))
class ConstantReference(object):
@@ -356,6 +360,8 @@ class Function(object):
self._view = view
self.handle = core.handle_of_type(handle, core.BNFunction)
self._advanced_analysis_requests = 0
+ self._arch = None
+ self._platform = None
def __del__(self):
if self._advanced_analysis_requests > 0:
@@ -407,18 +413,26 @@ class Function(object):
@property
def arch(self):
"""Function architecture (read-only)"""
- arch = core.BNGetFunctionArchitecture(self.handle)
- if arch is None:
- return None
- return architecture.Architecture(arch)
+ if self._arch:
+ return self._arch
+ else:
+ arch = core.BNGetFunctionArchitecture(self.handle)
+ if arch is None:
+ return None
+ self._arch = architecture.Architecture(arch)
+ return self._arch
@property
def platform(self):
"""Function platform (read-only)"""
- plat = core.BNGetFunctionPlatform(self.handle)
- if plat is None:
- return None
- return platform.Platform(None, handle = plat)
+ if self._platform:
+ return self._platform
+ else:
+ plat = core.BNGetFunctionPlatform(self.handle)
+ if plat is None:
+ return None
+ self._platform = platform.Platform(None, handle = plat)
+ return self._platform
@property
def start(self):
@@ -768,6 +782,41 @@ class Function(object):
"""Sets a comment for the current function"""
return core.BNSetFunctionComment(self.handle, comment)
+ @property
+ def llil_basic_blocks(self):
+ """A generator of all LowLevelILBasicBlock objects in the current function"""
+ for block in self.low_level_il:
+ yield block
+
+ @property
+ def mlil_basic_blocks(self):
+ """A generator of all MediumLevelILBasicBlock objects in the current function"""
+ for block in self.medium_level_il:
+ yield block
+
+ @property
+ def instructions(self):
+ """A generator of instruction tokens and their start addresses for the current function"""
+ for block in self.basic_blocks:
+ start = block.start
+ for i in block:
+ yield (i[0], start)
+ start += i[1]
+
+ @property
+ def llil_instructions(self):
+ """A generator of llil instructions of the current function"""
+ for block in self.llil_basic_blocks:
+ for i in block:
+ yield i
+
+ @property
+ def mlil_instructions(self):
+ """A generator of mlil instructions of the current function"""
+ for block in self.mlil_basic_blocks:
+ for i in block:
+ yield i
+
def __iter__(self):
count = ctypes.c_ulonglong()
blocks = core.BNGetFunctionBasicBlockList(self.handle, count)
@@ -829,7 +878,13 @@ class Function(object):
"""
if arch is None:
arch = self.arch
- return self.low_level_il[core.BNGetLowLevelILForInstruction(self.handle, arch.handle, addr)]
+
+ idx = core.BNGetLowLevelILForInstruction(self.handle, arch.handle, addr)
+
+ if idx == len(self.low_level_il):
+ return None
+
+ return self.low_level_il[idx]
def get_low_level_il_exits_at(self, addr, arch=None):
if arch is None:
@@ -980,7 +1035,13 @@ class Function(object):
def get_lifted_il_at(self, addr, arch=None):
if arch is None:
arch = self.arch
- return self.lifted_il[core.BNGetLiftedILForInstruction(self.handle, arch.handle, addr)]
+
+ idx = core.BNGetLiftedILForInstruction(self.handle, arch.handle, addr)
+
+ if idx == len(self.lifted_il):
+ return None
+
+ return self.lifted_il[idx]
def get_lifted_il_flag_uses_for_definition(self, i, flag):
flag = self.arch.get_flag_index(flag)
@@ -1833,6 +1894,7 @@ class InstructionBranch(object):
class InstructionInfo(object):
def __init__(self):
self.length = 0
+ self.arch_transition_by_target_addr = False
self.branch_delay = False
self.branches = []