Package rekall :: Package plugins :: Package tools :: Module live_darwin
[frames] | no frames]

Source Code for Module rekall.plugins.tools.live_darwin

  1  #!/usr/bin/env python2 
  2   
  3  # Rekall Memory Forensics 
  4  # Copyright 2015 Google Inc. All Rights Reserved. 
  5  # 
  6  # Author: Michael Cohen scudette@google.com 
  7  # 
  8  # This program is free software; you can redistribute it and/or modify 
  9  # it under the terms of the GNU General Public License as published by 
 10  # the Free Software Foundation; either version 2 of the License, or (at 
 11  # your option) any later version. 
 12  # 
 13  # This program is distributed in the hope that it will be useful, but 
 14  # WITHOUT ANY WARRANTY; without even the implied warranty of 
 15  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
 16  # General Public License for more details. 
 17  # 
 18  # You should have received a copy of the GNU General Public License 
 19  # along with this program; if not, write to the Free Software 
 20  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
 21  # 
 22   
 23  __author__ = "Michael Cohen <scudette@google.com>" 
 24   
 25  """A plugin to install relevant kernel modules to enable live analysis. 
 26   
 27  The intention is to allow the user to launch: 
 28   
 29  rekall live 
 30   
 31  and have Rekall install the right kernel module and connect to the driver on all 
 32  supported operating systems. 
 33  """ 
 34  import os 
 35  import subprocess 
 36  import tarfile 
 37   
 38  from rekall import plugin 
 39  from rekall import obj 
 40  from rekall import resources 
 41  from rekall import session 
 42  from rekall import utils 
 43   
 44  from rekall.plugins.addrspaces import pmem 
 45   
 46   
47 -class Live(plugin.TypedProfileCommand, 48 plugin.ProfileCommand):
49 """Launch a Rekall shell for live analysis on the current system.""" 50 51 name = "live" 52 53 PROFILE_REQUIRED = False 54 55 __args = [ 56 dict(name="mode", default="Memory", type="Choices", 57 choices=session.LIVE_MODES, 58 help="Mode for live analysis."), 59 60 dict(name="driver_path", 61 help="Driver file to load"), 62 63 dict(name="device", default=r"/dev/pmem", 64 help="Device name to use"), 65 66 dict(name="unload", type="Boolean", 67 help="Just unload the driver and exit."), 68 69 dict(name="load", type="Boolean", 70 help="Just load the driver and exit."), 71 ] 72 73 table_header = [ 74 dict(name="Message") 75 ] 76
77 - def __init__(self, *args, **kw):
78 super(Live, self).__init__(*args, **kw) 79 # It is OK for non privileged sessions to use the default drivers. 80 if not self.session.privileged and self.plugin_args.driver: 81 raise plugin.PluginError( 82 "Installing arbitrary drivers is only available for " 83 "interactive or privileged sessions.") 84 85 self.driver_path = (self.plugin_args.driver_path or 86 resources.get_resource("MacPmem.kext.tgz")) 87 if self.driver_path is None: 88 raise IOError("Driver resource not found.") 89 90 # Did we load the driver? If so we need to clean up. 91 self.we_started_driver = False
92
93 - def load_driver(self):
94 """Unpack and load the driver.""" 95 tarfile_handle = tarfile.open(self.driver_path) 96 97 # Try to extract the resource into a tempdir. 98 with utils.TempDirectory() as tmp_name: 99 self.session.logging.info("Unpacking driver to %s", tmp_name) 100 tarfile_handle.extractall(tmp_name) 101 102 # Change ownership of the extracted files to make sure they are 103 # owned by root otherwise they will not load. 104 for root, files, dirs in os.walk(tmp_name): 105 for f in files: 106 os.chown(os.path.join(root, f), 0, 0) 107 108 for d in dirs: 109 os.chown(os.path.join(root, d), 0, 0) 110 111 for member_name in tarfile_handle.getnames(): 112 if member_name.endswith(".kext"): 113 self.member_name = member_name.lstrip("/") 114 full_driver_path = os.path.join(tmp_name, 115 self.member_name) 116 self.session.logging.info( 117 "Loading driver from %s", full_driver_path) 118 res = subprocess.check_call( 119 ["kextload", full_driver_path]) 120 121 if res != 0: 122 raise plugin.PluginError( 123 "Failed to load driver. Are you root?")
124
125 - def live(self):
126 phys_as = obj.NoneObject("Unable to access physical memory") 127 128 if self.plugin_args.mode == "Memory": 129 try: 130 phys_as = pmem.MacPmemAddressSpace( 131 session=self.session, 132 filename=self.plugin_args.device) 133 except IOError as e: 134 self.session.logging.debug("%s", e) 135 self.load_driver() 136 phys_as = pmem.MacPmemAddressSpace( 137 session=self.session, 138 filename=self.plugin_args.device) 139 140 self.session.physical_address_space = phys_as 141 with self.session: 142 self.session.SetParameter("live_mode", self.plugin_args.mode) 143 self.session.SetParameter("session_name", "Live (%s)" % 144 self.plugin_args.mode)
145
146 - def unload_driver(self):
147 tarfile_handle = tarfile.open(self.driver_path) 148 149 for member_name in tarfile_handle.getnames(): 150 if not member_name.endswith(".kext"): 151 continue 152 153 self.member_name = member_name.lstrip("/") 154 155 # Try to extract the resource into a tempdir. 156 with utils.TempDirectory() as tmp_name: 157 tarfile_handle.extractall(tmp_name) 158 full_driver_path = os.path.join(tmp_name, 159 self.member_name) 160 self.session.logging.info( 161 "Unloading driver from %s", full_driver_path) 162 try: 163 subprocess.check_call( 164 ["kextunload", 165 os.path.join(tmp_name, self.member_name)]) 166 except Exception as e: 167 # There isnt much we can do about it here. 168 self.session.logging.debug( 169 "Unable to unload driver: %s" % e)
170
171 - def close(self):
172 if self.we_started_driver: 173 self.unload_driver()
174
175 - def collect(self):
176 yield ("Launching live memory analysis\n",) 177 try: 178 self.live() 179 180 renderer = self.session.GetRenderer() 181 182 # Launch the shell. 183 shell = self.session.plugins.shell() 184 shell.render(renderer) 185 finally: 186 self.close()
187
188 - def __enter__(self):
189 self.live() 190 return self
191
192 - def __exit__(self, exc_type, exc_value, trace):
193 self.close()
194