From 409de0f7804a49b6dcc9c8a14307de2be29ecd60 Mon Sep 17 00:00:00 2001 From: Rusty Wagner Date: Mon, 10 Sep 2018 20:31:23 -0400 Subject: 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) --- python/callingconvention.py | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'python/callingconvention.py') 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) @@ -90,6 +92,15 @@ class CallingConvention(object): core.BNFreeRegisterList(regs, count.value) 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 = [] @@ -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 -- cgit v1.3.1