diff options
| author | Rusty Wagner <rusty@vector35.com> | 2017-08-15 00:24:03 -0400 |
|---|---|---|
| committer | Rusty Wagner <rusty@vector35.com> | 2017-08-15 18:30:13 -0400 |
| commit | ec2d882e1a165b703e8fedaa81246dcdd91f50f3 (patch) | |
| tree | a6d9f2aebca1618db3aea5faf14ea6ddb60b7002 /python/callingconvention.py | |
| parent | 6bcb7bd30e5e6a8e69c875841f04245b8c3a0d7a (diff) | |
Add APIs to access and update portions of the function type, and added new APIs for global registers and implicit incoming state in calling conventions
Diffstat (limited to 'python/callingconvention.py')
| -rw-r--r-- | python/callingconvention.py | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/python/callingconvention.py b/python/callingconvention.py index 21c8c95a..609c71b0 100644 --- a/python/callingconvention.py +++ b/python/callingconvention.py @@ -26,6 +26,8 @@ import _binaryninjacore as core import architecture import log import types +import function +import binaryview class CallingConvention(object): @@ -38,6 +40,8 @@ class CallingConvention(object): int_return_reg = None high_int_return_reg = None float_return_reg = None + global_pointer_reg = None + implicitly_defined_regs = [] _registered_calling_conventions = [] @@ -58,6 +62,10 @@ class CallingConvention(object): 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) + self._cb.getGlobalPointerRegister = self._cb.getGlobalPointerRegister.__class__(self._get_global_pointer_reg) + self._cb.getImplicitlyDefinedRegisters = self._cb.getImplicitlyDefinedRegisters.__class__(self._get_implicitly_defined_regs) + self._cb.getIncomingRegisterValue = self._cb.getIncomingRegisterValue.__class__(self._get_incoming_reg_value) + self._cb.getIncomingFlagValue = self._cb.getIncomingFlagValue.__class__(self._get_incoming_flag_value) self.handle = core.BNCreateCallingConvention(arch.handle, name, self._cb) self.__class__._registered_calling_conventions.append(self) else: @@ -112,6 +120,21 @@ class CallingConvention(object): else: self.__dict__["float_return_reg"] = self.arch.get_reg_name(reg) + reg = core.BNGetGlobalPointerRegister(self.handle) + if reg == 0xffffffff: + self.__dict__["global_pointer_reg"] = None + else: + self.__dict__["global_pointer_reg"] = self.arch.get_reg_name(reg) + + count = ctypes.c_ulonglong() + regs = core.BNGetImplicitlyDefinedRegisters(self.handle, count) + result = [] + arch = self.arch + for i in xrange(0, count.value): + result.append(arch.get_reg_name(regs[i])) + core.BNFreeRegisterList(regs, count.value) + self.__dict__["implicitly_defined_regs"] = result + self.confidence = confidence def __del__(self): @@ -220,12 +243,76 @@ class CallingConvention(object): log.log_error(traceback.format_exc()) return False + def _get_global_pointer_reg(self, ctxt): + try: + if self.__class__.global_pointer_reg is None: + return 0xffffffff + return self.arch.regs[self.__class__.global_pointer_reg].index + except: + log.log_error(traceback.format_exc()) + return False + + def _get_implicitly_defined_regs(self, ctxt, count): + try: + regs = self.__class__.implicitly_defined_regs + count[0] = len(regs) + reg_buf = (ctypes.c_uint * len(regs))() + for i in xrange(0, len(regs)): + reg_buf[i] = self.arch.regs[regs[i]].index + result = ctypes.cast(reg_buf, ctypes.c_void_p) + self._pending_reg_lists[result.value] = (result, reg_buf) + return result.value + except: + log.log_error(traceback.format_exc()) + count[0] = 0 + return None + + def _get_incoming_reg_value(self, ctxt, reg, func): + try: + func_obj = function.Function(binaryview.BinaryView(handle = core.BNGetFunctionData(func)), + core.BNNewFunctionReference(func)) + reg_name = self.arch.get_reg_name(reg) + return self.perform_get_incoming_reg_value(reg_name, func_obj)._to_api_object() + except: + log.log_error(traceback.format_exc()) + return function.RegisterValue()._to_api_object() + + def _get_incoming_flag_value(self, ctxt, reg, func): + try: + func_obj = function.Function(binaryview.BinaryView(handle = core.BNGetFunctionData(func)), + core.BNNewFunctionReference(func)) + reg_name = self.arch.get_reg_name(reg) + return self.perform_get_incoming_flag_value(reg_name, func_obj)._to_api_object() + except: + log.log_error(traceback.format_exc()) + return function.RegisterValue()._to_api_object() + def __repr__(self): return "<calling convention: %s %s>" % (self.arch.name, self.name) def __str__(self): return self.name + def perform_get_incoming_reg_value(self, reg, func): + return function.RegisterValue() + + def perform_get_incoming_flag_value(self, reg, func): + return function.RegisterValue() + def with_confidence(self, confidence): return CallingConvention(self.arch, handle = core.BNNewCallingConventionReference(self.handle), confidence = confidence) + + def get_incoming_reg_value(self, reg, func): + reg_num = self.arch.get_reg_index(reg) + func_handle = None + if func is not None: + func_handle = func.handle + return function.RegisterValue(self.arch, core.BNGetIncomingRegisterValue(self.handle, reg_num, func_handle)) + + def get_incoming_flag_value(self, flag, func): + reg_num = self.arch.get_flag_index(flag) + func_handle = None + if func is not None: + func_handle = func.handle + return function.RegisterValue(self.arch, core.BNGetIncomingFlagValue(self.handle, reg_num, func_handle)) |
