diff options
| author | Rusty Wagner <rusty@vector35.com> | 2018-09-10 20:31:23 -0400 |
|---|---|---|
| committer | Rusty Wagner <rusty@vector35.com> | 2018-09-13 15:35:12 -0400 |
| commit | 409de0f7804a49b6dcc9c8a14307de2be29ecd60 (patch) | |
| tree | 92b04e17f71473ef39d87c62440b6e72b72ed9fb /python/callingconvention.py | |
| parent | 59a2824b1ad36ea5d0520919e86ad779cd97cc8f (diff) | |
Add callee saved registers on calling conventions to specify which registers are assumed to be preserved (used in heuristics to avoid incomplete data flow cloberring these registers)
Diffstat (limited to 'python/callingconvention.py')
| -rw-r--r-- | python/callingconvention.py | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/python/callingconvention.py b/python/callingconvention.py index 6b906184..f4349816 100644 --- a/python/callingconvention.py +++ b/python/callingconvention.py @@ -34,6 +34,7 @@ from binaryninja import range class CallingConvention(object): name = None caller_saved_regs = [] + callee_saved_regs = [] int_arg_regs = [] float_arg_regs = [] arg_regs_share_index = False @@ -56,6 +57,7 @@ class CallingConvention(object): self._cb = core.BNCustomCallingConvention() self._cb.context = 0 self._cb.getCallerSavedRegisters = self._cb.getCallerSavedRegisters.__class__(self._get_caller_saved_regs) + self._cb.getCalleeSavedRegisters = self._cb.getCalleeSavedRegisters.__class__(self._get_callee_saved_regs) self._cb.getIntegerArgumentRegisters = self._cb.getIntegerArgumentRegisters.__class__(self._get_int_arg_regs) self._cb.getFloatArgumentRegisters = self._cb.getFloatArgumentRegisters.__class__(self._get_float_arg_regs) self._cb.freeRegisterList = self._cb.freeRegisterList.__class__(self._free_register_list) @@ -91,6 +93,15 @@ class CallingConvention(object): self.__dict__["caller_saved_regs"] = result count = ctypes.c_ulonglong() + regs = core.BNGetCalleeSavedRegisters(self.handle, count) + result = [] + arch = self.arch + for i in range(0, count.value): + result.append(arch.get_reg_name(regs[i])) + core.BNFreeRegisterList(regs, count.value) + self.__dict__["callee_saved_regs"] = result + + count = ctypes.c_ulonglong() regs = core.BNGetIntegerArgumentRegisters(self.handle, count) result = [] arch = self.arch @@ -171,6 +182,21 @@ class CallingConvention(object): count[0] = 0 return None + def _get_callee_saved_regs(self, ctxt, count): + try: + regs = self.__class__.callee_saved_regs + count[0] = len(regs) + reg_buf = (ctypes.c_uint * len(regs))() + for i in range(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_int_arg_regs(self, ctxt, count): try: regs = self.__class__.int_arg_regs |
