from builtins import object import pickle import io import os import six import time from rekall import config from rekall import io_manager from rekall import obj from rekall.ui import json_renderer from rekall_lib import utils config.DeclareOption("--cache", default="file", type="String", choices=["file", "memory", "timed"], help="Type of cache to use. ") config.DeclareOption("--cache_expiry_time", default=600, type="Float", help="Expiry times for timed caches. ") class RestrictedUnpickler(pickle.Unpickler): def find_class(self, module, name): # Only allow safe classes from builtins. if module == "builtins" and name in safe_builtins: return getattr(builtins, name) # Forbid everything else.
import socket import struct import arrow from rekall import config from rekall import obj from rekall.plugins.overlays import native_types from rekall_lib import utils if six.PY3: long = int config.DeclareOption( "--timezone", default="UTC", group="Interface", help="Timezone to output all times (e.g. Australia/Sydney).") class String(obj.StringProxyMixIn, obj.NativeType): """Class for dealing with Null terminated C Strings. Note that these strings are _not_ text strings - they are effectively bytes arrays and therefore are not encoded in any particular unicode encoding. """ def __init__(self, length=1024, max_length=1024000, term=b"\x00", **kwargs):
from rekall import addrspace from rekall import config from rekall import obj from rekall import plugin from rekall import testlib from rekall import utils from rekall.plugins.common import address_resolver from rekall.plugins.windows import common from rekall.plugins.overlays.windows import pe_vtypes from rekall.plugins.overlays.windows import windows config.DeclareOption( "autodetect_build_local_tracked", group="Autodetection Overrides", default=["nt", "win32k", "tcpip", "ntdll"], type="ArrayStringParser", help="When autodetect_build_local is set to 'basic' we fetch these " "modules directly from the symbol server.") # In windows there are two types of mapped PE files - kernel modules and Dlls. class PEModule(address_resolver.Module): """Windows overlays PE files in memory.""" _profile = None def detect_profile_from_session(self): """Get the module guid from the session cache.
""" This is based on Jesse Kornblum's patch to clean up the standard AS's. """ # pylint: disable=protected-access import struct from rekall import addrspace from rekall import config from rekall import obj from rekall import utils from rekall.plugins.addrspaces import intel from rekall.plugins.addrspaces import standard config.DeclareOption("ept", group="Virtualization support", type="ArrayIntParser", help="The EPT physical address.") class AMD64PagedMemory(intel.IA32PagedMemoryPae): """Standard AMD 64-bit address space. Provides an address space for AMD64 paged memory, aka the x86_64 architecture, which is laid out similarly to Physical Address Extensions (PAE). Allows callers to map virtual address to offsets in physical memory. Create a new AMD64 address space to sit on top of the base address space and a Directory Table Base (CR3 value) of 'dtb'. Comments in this class mostly come from the Intel(R) 64 and IA-32
volatile=False) session.SetCache("dtb", address_space.dtb, volatile=False) return profile def DetectFromHit(self, hit, file_offset, address_space): """Gets called for each hit. If a profile matches, return it, otherwise None. """ # By default use all detection modules. config.DeclareOption("autodetect", group="Autodetection Overrides", type="ChoiceArray", required=True, choices=utils.JITIterator(DetectionMethod), default=utils.JITIterator(DetectionMethod), help="Autodetection method.") config.DeclareOption("autodetect_threshold", default=1.0, group="Autodetection Overrides", help="Worst acceptable match for profile autodetection." + " (Default 1.0)", type="Float") config.DeclareOption("autodetect_build_local", default="basic", group="Autodetection Overrides", choices=["full", "basic", "none"], help="Attempts to fetch and build profile locally.", type="Choices")
from rekall import config from rekall import constants from rekall import plugin from rekall import session from rekall import quotas from pkg_resources import iter_entry_points for entry_point in iter_entry_points(group='rekall.plugins', name=None): entry_point.load() # Load all the plugins. from rekall import plugins # pylint: disable=unused-import config.DeclareOption( "--version", default=False, type="Boolean", help="Prints the Rekall version and exits.") class Run(plugin.PrivilegedMixIn, plugin.Command): """A plugin which runs its argument (using eval). Note: This plugin is only defined and available when using the main entry point. It is not available when Rekall is used as a library since it allows arbitrary code execution. """ name = "run" @classmethod def args(cls, parser):
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # __author__ = "Michael Cohen <*****@*****.**>" import logging from multiprocessing.pool import ThreadPool from rekall import config from rekall import plugin config.DeclareOption("agent_configuration", group="Rekall Agent", help="The Rekall Agent configuration file. When " "specified Rekall switches to Agent mode.") class Interpolator(dict): """A commonly used format interpolator for locations. The below supports path temple interpolations allowing various expansions to be made dynamically. For example a file path template may include "/path{client_id}/foo" to expand the client_id into the path. """ def __init__(self, session, **kwargs): super(Interpolator, self).__init__(**kwargs) self.session = session self._config = session.GetParameter("agent_config_obj")
# General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ This is Jesse Kornblum's patch to clean up the standard AS's. """ import struct from rekall import addrspace from rekall import config from rekall import obj config.DeclareOption(name="dtb", group="Autodetection Overrides", action=config.IntParser, help="The DTB physical address.") class IA32PagedMemory(addrspace.PagedReader): """ Standard x86 32 bit non PAE address space. Provides an address space for IA32 paged memory, aka the x86 architecture, without Physical Address Extensions (PAE). Allows callers to map virtual address to offsets in physical memory. Create a new IA32 address space without PAE to sit on top of the base address space and a Directory Table Base (CR3 value) of 'dtb'. Comments in this class mostly come from the Intel(R) 64 and IA-32
The code works by wrapping a session object with progress handlers which check for the CPU quota. Note that when Rekall is used as a library, the caller must deliberately wrap its own session with this module. """ import time import psutil from rekall import config from rekall import plugin config.DeclareOption( "--cpu_quota", type="IntParser", group="Quotas", help="Number of allocated CPU seconds Rekall is allowed to consume. " "If not set, unlimited CPU time can be used.") config.DeclareOption( "--load_quota", type="IntParser", group="Quotas", help="The target maximal process load level (in percent).") def wrap_session(session, cpu_quota=None, load_quota=None): """Wraps the session limiting cpu quota.""" if load_quota is None: load_quota = session.GetParameter("load_quota") if cpu_quota is None: cpu_quota = session.GetParameter("cpu_quota")
they support. """ import collections import gc import inspect import logging import time from rekall import config from rekall import constants from rekall import registry from rekall import utils config.DeclareOption("-v", "--verbose", default=False, type="Boolean", help="Set logging to debug level.", group="Output control") config.DeclareOption("-q", "--quiet", default=False, type="Boolean", help="Turn off logging to stderr.", group="Output control") config.DeclareOption( "--debug", default=False, type="Boolean", help="If set we break into the debugger on error conditions.")
"""This module manages the command line parsing logic.""" __author__ = "Michael Cohen <*****@*****.**>" import argparse import logging import os import sys import zipfile from rekall import config from rekall import constants from rekall import plugin config.DeclareOption("--plugin", default=[], nargs="+", help="Load user provided plugin bundle.") config.DeclareOption( "-h", "--help", default=False, action="store_true", help="Show help about global paramters.") class MockArgParser(object): def add_argument(self, short_flag="", long_flag="", dest="", **_): if short_flag.startswith("--"): flag = short_flag elif long_flag.startswith("--"): flag = long_flag elif dest: flag = dest else:
import logging import pdb import sys from rekall import args from rekall import config from rekall import session # Import and register the core plugins from rekall import plugins # pylint: disable=unused-import from rekall.ui import text config.DeclareOption( "-r", "--run", default=None, help="Run this script before dropping into the interactive shell.") def main(argv=None): # New user interactive session (with extra bells and whistles). user_session = session.InteractiveSession() user_session.session_list.append(user_session) text_renderer = text.TextRenderer(session=user_session) with text_renderer.start(): plugin_cls, flags = args.parse_args(argv=argv, user_session=user_session) # Determine if an external script needs to be run first.
from IPython.terminal import embed from IPython.terminal import prompts try: from traitlets.config.loader import Config except ImportError: from IPython.config.loader import Config from rekall import constants from rekall import config from rekall import session as session_module from rekall import utils config.DeclareOption("--highlighting_style", default="monokai", type="Choices", choices=list(styles.get_all_styles()), help="Highlighting style for interactive console.") def RekallCompleter(self, text): """Sophisticated command line completer for Rekall.""" try: command_parts = self.line_buffer.split(" ") command = command_parts[0] if command.startswith("plugins."): command = command[len("plugins."):] global_matches = set(self.global_matches(command))
from rekall import config from rekall import constants from rekall import obj from rekall import session # Import and register the core plugins from rekall import plugins # pylint: disable=unused-import try: from rekall import ipython_support except ImportError: ipython_support = None config.DeclareOption( "-r", "--run", default=None, help="Run this script before dropping into the interactive shell.") config.DeclareOption( "-s", "--session_filename", default=None, help="If specified we save and restore the session from this filename.") def IPython012Support(user_session): """Launch the ipython session for post 0.12 versions. Returns: False if we failed to use IPython. True if the session was run and exited.
__author__ = "Michael Cohen <*****@*****.**>" import argparse import logging import re import os import sys import zipfile from rekall import config from rekall import constants from rekall import plugin from rekall import utils config.DeclareOption("--plugin", default=[], type="ArrayStringParser", help="Load user provided plugin bundle.") config.DeclareOption( "-h", "--help", default=False, type="Boolean", help="Show help about global paramters.") class RekallHelpFormatter(argparse.RawDescriptionHelpFormatter): def add_argument(self, action): # Allow us to suppress an arg from the --help output for those options # which do not make sense on the command line. if action.dest != "SUPPRESS": super(RekallHelpFormatter, self).add_argument(action) class RekallArgParser(argparse.ArgumentParser):
# Found in every OS X image. See documentation for DarwinFindKASLR for # details. OSX_NEEDLE, # The Linux kernels we care about contain this. "Linux version ", ] class ProfileScanner(scan.BaseScanner): checks = [("MultiStringFinderCheck", dict(needles=PROFILE_STRINGS))] config.DeclareOption("--no_autodetect", default=False, action="store_true", help="Should profiles be autodetected.") config.DeclareOption("--autodetect_threshold", default=1.0, action="store", help="Worst acceptable match for profile autodetection." + " (Default 1.0)", type=float) class KernelASHook(kb.ParameterHook): """A ParameterHook for default_address_space. This will only be called if default_address_space is not set. We load the kernel address space, or load it if needed.
used within the renderer they only need to cooperate with the renderer class they support. """ import collections import gc import inspect import logging import time from rekall import config from rekall import registry from rekall import utils config.DeclareOption("-v", "--verbose", default=False, type="Boolean", help="Set logging to debug level.", group="Output control") config.DeclareOption("-q", "--quiet", default=False, type="Boolean", help="Turn off logging to stderr.", group="Output control") config.DeclareOption( "--debug", default=False, type="Boolean", help="If set we break into the debugger on error conditions.")
from rekall import constants from rekall import entity from rekall import io_manager from rekall import kb from rekall import obj from rekall import plugin from rekall import utils from rekall.ui import renderer from rekall.ui import text # Top level args. config.DeclareOption("-p", "--profile", group="Autodetection Overrides", help="Name of the profile to load. This is the " "filename of the profile found in the profiles " "directory. Profiles are searched in the profile " "path order.") config.DeclareOption("--profile_path", default=[], action="append", help="Path to search for profiles. This can take " "any form supported by the IO Manager (e.g. zip files, " "directories, URLs etc)") config.DeclareOption("-f", "--filename", help="The raw image to load.") config.DeclareOption( "--buffer_size",
from builtins import str from past.builtins import basestring from past.utils import old_div from builtins import object __author__ = "Michael Cohen <*****@*****.**>" import re from rekall import config from rekall import obj from rekall_lib import utils config.DeclareOption("--name_resolution_strategies", default=["Module", "Symbol", "Export"], group="Interface", type="ChoiceArray", choices=["Module", "Symbol", "Export"]) class Module(object): """A range in the virtual address space which maps an executable. Each binary in the address space has its own profile, which knows about symbols within it. This simple class is just a container to facilitate access to the profile that represents this module. Within Rekall, each module has a name. Rekall uses a simple syntax to refer to an address in the address space by name (see below). """ def __init__(self,
# # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ These are standard address spaces supported by Rekall Memory Forensics """ import StringIO import struct import os import weakref from rekall import addrspace from rekall import config config.DeclareOption("-o", "--file_offset", type="IntParser", help="A Relative offset for image file.") class FDAddressSpace(addrspace.BaseAddressSpace): """An address space which operated on a file like object.""" __name = "filelike" # We should be first. order = 0 def __init__(self, base=None, fhandle=None, **kwargs): self.as_assert(base == None, "Base passed to FDAddressSpace.") self.as_assert(fhandle is not None, 'file handle must be provided')
the required performance vtop() simply looks for the PhysicalAddressDescriptor() and returns it. This is essentially a noop for any of the other descriptors and therefore maintains the same speed benefits. """ import StringIO import struct from rekall import addrspace from rekall import config from rekall import obj from rekall.ui import text as text_renderer from rekall_lib import utils config.DeclareOption("dtb", group="Autodetection Overrides", type="IntParser", help="The DTB physical address.") PAGE_SHIFT = 12 PAGE_MASK = ~0xFFF class AddressTranslationDescriptor(object): """A descriptor of a step in the translation process. This is a class because there may be OS specific steps in the address translation. """ object_name = None def __init__(self,
from rekall import config from rekall import io_manager from rekall import kb from rekall import obj from rekall import plugin from rekall import registry from rekall import utils from rekall.entities import manager as entity_manager from rekall.ui import renderer from rekall.ui import json_renderer config.DeclareOption("--repository_path", default=[], type="ArrayStringParser", help="Path to search for profiles. This can take " "any form supported by the IO Manager (e.g. zip files, " "directories, URLs etc)") config.DeclareOption("-f", "--filename", help="The raw image to load.") config.DeclareOption( "--buffer_size", default=20 * 1024 * 1024, type="IntParser", help="The maximum size of buffers we are allowed to read. " "This is used to control Rekall memory usage.") config.DeclareOption("--output", default=None, help="If specified we write output to this file.")
this file handle compressed pages and return the decompressed data when a compressed page is read. """ from rekall import addrspace from rekall import config from rekall.plugins.windows import pagefile from rekall.plugins.addrspaces import xpress from rekall.plugins.addrspaces import intel PAGE_SIZE = 0x1000 XPRESS_ALGO = 3 config.DeclareOption("--vspagefilenumber", type="int", default=2, group="Windows 10 Memory Compression", help=('Specify the page file number corresponding' ' to the Virtual Store (default is 2)')) class WindowsCompressedMemoryDescriptor(intel.AddressTranslationDescriptor): """A descriptor for compressed memory pages (Windows 10).""" def __init__(self, address=0, pagefile_number=0, pte_value=0, session=None): super().__init__(session=session) self.address = address self.pagefile_number = pagefile_number
from rekall import config from rekall import constants try: from IPython.terminal import embed except ImportError: try: from IPython.frontend.terminal import embed except ImportError: embed = None from IPython.config.loader import Config config.DeclareOption("--ipython_engine", help="IPython engine, e.g. notebook.") def RekallCompleter(self, text): """Sophisticated command line completer for Rekall.""" try: command_parts = self.line_buffer.split(" ") command = command_parts[0] if command.startswith("plugins."): command = command[len("plugins."):] global_matches = set(self.global_matches(command)) # Complete strings which look like symbol names. m = re.match("\"([^!]+![^\"]*)$", command_parts[-1])
from builtins import object import pickle import io import os import six import time from rekall import config from rekall import io_manager from rekall import obj from rekall.ui import json_renderer from rekall_lib import utils config.DeclareOption("--cache", default="file", type="String", choices=["file", "memory", "timed"], help="Type of cache to use. ") class RestrictedUnpickler(pickle.Unpickler): def find_class(self, module, name): # Only allow safe classes from builtins. if module == "builtins" and name in safe_builtins: return getattr(builtins, name) # Forbid everything else. raise pickle.UnpicklingError("global '%s.%s' is forbidden" % (module, name)) def RestrictedPickler(raw):
# """This address space overlays a pagefile into the physical address space. This essentially implements the --pagefile parameter. Note that for images taken with winpmem there is no need to specify the pagefile specifically since it is already detected by the Elf64CoreDump class. """ __author__ = "Michael Cohen <*****@*****.**>" from rekall import addrspace from rekall import config from rekall import session config.DeclareOption("--pagefile", type="ArrayStringParser", default=[], help="A pagefile to load into the image.") class PagefilePhysicalAddressSpace(addrspace.RunBasedAddressSpace): __image = True name = "pagefile" order = 200 def __init__(self, **kwargs): super(PagefilePhysicalAddressSpace, self).__init__(**kwargs) pagefile_names = self.session.GetParameter("pagefile") self.as_assert(pagefile_names, "Pagefile not specified") self.as_assert(self.base.__class__ is not self.__class__)
from rekall import cache from rekall import config from rekall import constants from rekall import io_manager from rekall import kb from rekall import obj from rekall import plugin from rekall import registry from rekall import utils from rekall.ui import renderer config.DeclareOption("--repository_path", default=[], type="ArrayStringParser", help="Path to search for profiles. This can take " "any form supported by the IO Manager (e.g. zip files, " "directories, URLs etc)") config.DeclareOption("-f", "--filename", help="The raw image to load.") config.DeclareOption( "--buffer_size", default=20 * 1024 * 1024, type="IntParser", help="The maximum size of buffers we are allowed to read. " "This is used to control Rekall memory usage.") config.DeclareOption("--output", default=None, help="If specified we write output to this file.")
# General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # """ This is based on Jesse Kornblum's patch to clean up the standard AS's. """ import struct from rekall import config from rekall.plugins.addrspaces import intel config.DeclareOption(name="ept", group="Virtualization support", action=config.ArrayIntParser, help="The EPT physical address.") class AMD64PagedMemory(intel.IA32PagedMemoryPae): """Standard AMD 64-bit address space. Provides an address space for AMD64 paged memory, aka the x86_64 architecture, which is laid out similarly to Physical Address Extensions (PAE). Allows callers to map virtual address to offsets in physical memory. Create a new AMD64 address space to sit on top of the base address space and a Directory Table Base (CR3 value) of 'dtb'. Comments in this class mostly come from the Intel(R) 64 and IA-32
We locally cache selected files from the remote profile repository. If a profile is not found in the local cache, we retrieve it from the remote repository, and add it to the cache. We check the remote repository for staleness and update the local cache in the background. """ __author__ = "Michael Cohen <*****@*****.**>" import os from rekall import config from rekall import io_manager config.DeclareOption("cache_dir", default=None, help="Location of the profile cache directory.") class CachingManager(io_manager.IOManager): # We wrap this io manager class DELEGATE = io_manager.URLManager # If the cache is available we should be selected before the regular # manager. order = DELEGATE.order - 10 def __init__(self, session=None, **kwargs): cache_dir = session.GetParameter("cache_dir")
"1486.2.11": "10.6.2", "1456.1.26": "10.6.1", # The signature of an RSDS record. "RSDS": "PDB", "Linux version ": "Linux", } class ProfileScanner(scan.BaseScanner): checks = [("MultiStringFinderCheck", dict(needles=PROFILE_STRINGS))] config.DeclareOption("--no_autodetect", default=False, action="store_true", help="Should profiles be autodetected.") class KernelASHook(kb.ParameterHook): """A ParameterHook for default_address_space. This will only be called if default_address_space is not set. We load the kernel address space, or load it if needed. """ name = "default_address_space" def calculate(self): if not self.session.profile: self.session.GetParameter("profile") if self.session.kernel_address_space: