Source code for revenge.plugins.decompiler.decompiler


import logging
from .. import Plugin
from revenge.exceptions import *
from revenge import common

[docs]class Decompiler(Plugin): def __init__(self, process): """Use this to decompile things. Examples: .. code-block:: python3 # Attempt to get corresponding source code from address 0x12345 process.decompiler[0x12345] This is really just a light wrapper to lookup and call the correct decompiler. """ self._process = process # priority: decompiler self._decompilers = {} @common.validate_argument_types(priority=int) def _register_decompiler(self, decompiler, priority): """Registers a decompiler to this plugin's stack. Args: decompiler (revenge.plugins.decompiler.DecompilerBase): The decompiler to register priority (int): What priority should this decompiler be used? 0 is lowest 100 is highest Note: Only register your decompiler if it is valid in the CURRENT INSTANCE of revenge. I.e.: Check for needed dependencies prior to registering. Registering a decompiler will place it in the list of available decompilers. """ if not issubclass(type(decompiler), DecompilerBase): raise RevengeInvalidArgumentType("decompiler must be a subclass of DecompilerBase.") if priority in self._decompilers: raise RevengeDecompilerAlreadyRegisteredError("Cannot register {}. Priority is already in use by: {}".format(decompiler, self._decompilers[priority])) self._decompilers[priority] = decompiler def _select_decompiler(self): # Need to postpone selecting decompiler until all plugins are loaded... for priority in sorted(self._decompilers.keys(), reverse=True): self.imp = self._decompilers[priority] break else: self.imp = None LOGGER.warning("No decompiler discovered. Consider installing radare2 with ghidra (r2pm install r2ghidra-dec)") @property def imp(self): """revenge.plugins.decompiler.DecompilerBase: The underlying implementation. This will be guessed automatically based on what decompilers are discovered. You can also instantiate your own and assign it directly to imp. """ try: return self.__imp except AttributeError: pass # Time to check what decompilers we have access to self._select_decompiler() return self.__imp @imp.setter def imp(self, imp): if imp is not None and not issubclass(type(imp), DecompilerBase): raise RevengeInvalidArgumentType("imp must be a subclass of DecompilerBase.") self.__imp = imp @property def _is_valid(self): return True ############### # imp methods # ############### @common.require_imp() def __getitem__(self, item): return self.imp.__getitem__(item)
[docs] @common.require_imp() def decompile_address(self, address): return self.imp.decompile_address(address)
[docs] @common.require_imp() def decompile_function(self, address): return self.imp.decompile_function(address)
from revenge.plugins.decompiler.base import DecompilerBase # Docs fixup Decompiler.__init__.__doc__ = DecompilerBase.__init__.__doc__ Decompiler.__doc__ = Decompiler.__init__.__doc__ Decompiler.decompile_address.__doc__ = DecompilerBase.decompile_address.__doc__ Decompiler.decompile_function.__doc__ = DecompilerBase.decompile_function.__doc__ LOGGER = logging.getLogger(__name__)