summaryrefslogtreecommitdiff
path: root/python
diff options
context:
space:
mode:
Diffstat (limited to 'python')
-rw-r--r--python/binaryview.py6
-rw-r--r--python/callingconvention.py10
-rw-r--r--python/function.py79
-rw-r--r--python/types.py37
4 files changed, 131 insertions, 1 deletions
diff --git a/python/binaryview.py b/python/binaryview.py
index d977de50..bf8a87e0 100644
--- a/python/binaryview.py
+++ b/python/binaryview.py
@@ -927,6 +927,12 @@ class BinaryView(object):
else:
return BinaryView._associated_data[handle.value]
+ @property
+ def global_pointer_value(self):
+ """Discovered value of the global pointer register, if the binary uses one (read-only)"""
+ result = core.BNGetGlobalPointerValue(self.handle)
+ return function.RegisterValue(self.arch, result.value, confidence = result.confidence)
+
def __len__(self):
return int(core.BNGetViewLength(self.handle))
diff --git a/python/callingconvention.py b/python/callingconvention.py
index bd8bbeee..e72475c9 100644
--- a/python/callingconvention.py
+++ b/python/callingconvention.py
@@ -37,6 +37,7 @@ class CallingConvention(object):
float_arg_regs = []
arg_regs_share_index = False
stack_reserved_for_arg_regs = False
+ stack_adjusted_on_return = False
int_return_reg = None
high_int_return_reg = None
float_return_reg = None
@@ -59,6 +60,7 @@ class CallingConvention(object):
self._cb.freeRegisterList = self._cb.freeRegisterList.__class__(self._free_register_list)
self._cb.areArgumentRegistersSharedIndex = self._cb.areArgumentRegistersSharedIndex.__class__(self._arg_regs_share_index)
self._cb.isStackReservedForArgumentRegisters = self._cb.isStackReservedForArgumentRegisters.__class__(self._stack_reserved_for_arg_regs)
+ self._cb.isStackAdjustedOnReturn = self._cb.isStackAdjustedOnReturn.__class__(self._stack_adjusted_on_return)
self._cb.getIntegerReturnValueRegister = self._cb.getIntegerReturnValueRegister.__class__(self._get_int_return_reg)
self._cb.getHighIntegerReturnValueRegister = self._cb.getHighIntegerReturnValueRegister.__class__(self._get_high_int_return_reg)
self._cb.getFloatReturnValueRegister = self._cb.getFloatReturnValueRegister.__class__(self._get_float_return_reg)
@@ -74,6 +76,7 @@ class CallingConvention(object):
self.__dict__["name"] = core.BNGetCallingConventionName(self.handle)
self.__dict__["arg_regs_share_index"] = core.BNAreArgumentRegistersSharedIndex(self.handle)
self.__dict__["stack_reserved_for_arg_regs"] = core.BNIsStackReservedForArgumentRegisters(self.handle)
+ self.__dict__["stack_adjusted_on_return"] = core.BNIsStackAdjustedOnReturn(self.handle)
count = ctypes.c_ulonglong()
regs = core.BNGetCallerSavedRegisters(self.handle, count)
@@ -218,6 +221,13 @@ class CallingConvention(object):
log.log_error(traceback.format_exc())
return False
+ def _stack_adjusted_on_return(self, ctxt):
+ try:
+ return self.__class__.stack_adjusted_on_return
+ except:
+ log.log_error(traceback.format_exc())
+ return False
+
def _get_int_return_reg(self, ctxt):
try:
return self.arch.regs[self.__class__.int_return_reg].index
diff --git a/python/function.py b/python/function.py
index 55151e16..553b156f 100644
--- a/python/function.py
+++ b/python/function.py
@@ -50,11 +50,12 @@ class LookupTableEntry(object):
class RegisterValue(object):
- def __init__(self, arch = None, value = None):
+ def __init__(self, arch = None, value = None, confidence = types.max_confidence):
if value is None:
self.type = RegisterValueType.UndeterminedValue
else:
self.type = RegisterValueType(value.state)
+ self.is_constant = False
if value.state == RegisterValueType.EntryValue:
self.arch = arch
if arch is not None:
@@ -63,8 +64,10 @@ class RegisterValue(object):
self.reg = value.value
elif (value.state == RegisterValueType.ConstantValue) or (value.state == RegisterValueType.ConstantPointerValue):
self.value = value.value
+ self.is_constant = True
elif value.state == RegisterValueType.StackFrameOffset:
self.offset = value.value
+ self.confidence = confidence
def __repr__(self):
if self.type == RegisterValueType.EntryValue:
@@ -280,6 +283,9 @@ class ParameterVariables(object):
def __getitem__(self, idx):
return self.vars[idx]
+ def __len__(self):
+ return len(self.vars)
+
def with_confidence(self, confidence):
return ParameterVariables(list(self.vars), confidence = confidence)
@@ -598,6 +604,52 @@ class Function(object):
bc.confidence = types.max_confidence
core.BNSetUserFunctionHasVariableArguments(self.handle, bc)
+ @property
+ def stack_adjustment(self):
+ """Number of bytes removed from the stack after return"""
+ result = core.BNGetFunctionStackAdjustment(self.handle)
+ return types.SizeWithConfidence(result.value, confidence = result.confidence)
+
+ @stack_adjustment.setter
+ def stack_adjustment(self, value):
+ sc = core.BNSizeWithConfidence()
+ sc.value = int(value)
+ if hasattr(value, 'confidence'):
+ sc.confidence = value.confidence
+ else:
+ sc.confidence = types.max_confidence
+ core.BNSetUserFunctionStackAdjustment(self.handle, sc)
+
+ @property
+ def clobbered_regs(self):
+ """Registers that are modified by this function"""
+ result = core.BNGetFunctionClobberedRegisters(self.handle)
+ reg_set = []
+ for i in xrange(0, result.count):
+ reg_set.append(self.arch.get_reg_name(result.regs[i]))
+ regs = types.RegisterSet(reg_set, confidence = result.confidence)
+ core.BNFreeClobberedRegisters(result)
+ return regs
+
+ @clobbered_regs.setter
+ def clobbered_regs(self, value):
+ regs = core.BNRegisterSetWithConfidence()
+ regs.regs = (ctypes.c_uint * len(value))()
+ regs.count = len(value)
+ for i in xrange(0, len(value)):
+ regs.regs[i] = self.arch.get_reg_index(value[i])
+ if hasattr(value, 'confidence'):
+ regs.confidence = value.confidence
+ else:
+ regs.confidence = types.max_confidence
+ core.BNSetUserFunctionClobberedRegisters(self.handle, regs)
+
+ @property
+ def global_pointer_value(self):
+ """Discovered value of the global pointer register, if the function uses one (read-only)"""
+ result = core.BNGetFunctionGlobalPointerValue(self.handle)
+ return RegisterValue(self.arch, result.value, confidence = result.confidence)
+
def __iter__(self):
count = ctypes.c_ulonglong()
blocks = core.BNGetFunctionBasicBlockList(self.handle, count)
@@ -963,6 +1015,27 @@ class Function(object):
bc.confidence = types.max_confidence
core.BNSetAutoFunctionCanReturn(self.handle, bc)
+ def set_auto_stack_adjustment(self, value):
+ sc = core.BNSizeWithConfidence()
+ sc.value = int(value)
+ if hasattr(value, 'confidence'):
+ sc.confidence = value.confidence
+ else:
+ sc.confidence = types.max_confidence
+ core.BNSetAutoFunctionStackAdjustment(self.handle, sc)
+
+ def set_auto_clobbered_regs(self, value):
+ regs = core.BNRegisterSetWithConfidence()
+ regs.regs = (ctypes.c_uint * len(value))()
+ regs.count = len(value)
+ for i in xrange(0, len(value)):
+ regs.regs[i] = self.arch.get_reg_index(value[i])
+ if hasattr(value, 'confidence'):
+ regs.confidence = value.confidence
+ else:
+ regs.confidence = types.max_confidence
+ core.BNSetAutoFunctionClobberedRegisters(self.handle, regs)
+
def get_int_display_type(self, instr_addr, value, operand, arch=None):
if arch is None:
arch = self.arch
@@ -1160,6 +1233,10 @@ class Function(object):
core.BNFreeDisassemblyTextLines(lines, count.value)
return result
+ def get_reg_value_at_exit(self, reg):
+ result = core.BNGetFunctionRegisterValueAtExit(self.handle, self.arch.get_reg_index(reg))
+ return RegisterValue(self.arch, result.value, confidence = result.confidence)
+
class AdvancedFunctionAnalysisDataRequestor(object):
def __init__(self, func = None):
diff --git a/python/types.py b/python/types.py
index fd2ee27e..bf4a7b74 100644
--- a/python/types.py
+++ b/python/types.py
@@ -650,6 +650,43 @@ class BoolWithConfidence(object):
return self.value
+class SizeWithConfidence(object):
+ def __init__(self, value, confidence = max_confidence):
+ self.value = value
+ self.confidence = confidence
+
+ def __str__(self):
+ return str(self.value)
+
+ def __repr__(self):
+ return repr(self.value)
+
+ def __int__(self):
+ return self.value
+
+
+class RegisterSet(object):
+ def __init__(self, reg_list, confidence = max_confidence):
+ self.regs = reg_list
+ self.confidence = confidence
+
+ def __repr__(self):
+ return repr(self.regs)
+
+ def __iter__(self):
+ for reg in self.regs:
+ yield reg
+
+ def __getitem__(self, idx):
+ return self.regs[idx]
+
+ def __len__(self):
+ return len(self.regs)
+
+ def with_confidence(self, confidence):
+ return RegisterSet(list(self.regs), confidence = confidence)
+
+
class ReferenceTypeWithConfidence(object):
def __init__(self, value, confidence = max_confidence):
self.value = value