Package rekall :: Package plugins :: Package common :: Module scanners
[frames] | no frames]

Source Code for Module rekall.plugins.common.scanners

  1  # Rekall Memory Forensics 
  2  # Copyright 2016 Google Inc. All Rights Reserved. 
  3  # 
  4  # This program is free software; you can redistribute it and/or modify 
  5  # it under the terms of the GNU General Public License as published by 
  6  # the Free Software Foundation; either version 2 of the License, or (at 
  7  # your option) any later version. 
  8  # 
  9  # This program is distributed in the hope that it will be useful, but 
 10  # WITHOUT ANY WARRANTY; without even the implied warranty of 
 11  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
 12  # General Public License for more details. 
 13  # 
 14  # You should have received a copy of the GNU General Public License 
 15  # along with this program; if not, write to the Free Software 
 16  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
 17  # 
 18   
 19   
 20  __author__ = "Michael Cohen <scudette@google.com>" 
 21   
 22  """A Common mixin for implementing plugins based on scanning.""" 
 23   
 24  from rekall import addrspace 
 25   
 26   
27 -class BaseScannerPlugin(object):
28 """A mixin that implements scanner memory region selectors. 29 30 Most scanners are very similar - they search for specific byte patterns over 31 some sections of memory, validate those and present the results. Depending 32 on the type of structures searched for, different regions of memory need to 33 be looked at. 34 35 This mixin attempts to present a common interface to all scanning plugins, 36 where users may select different regions using common selector options, and 37 those will be generated automatically. 38 39 The plugin may select a set of default regions to scan, which are most 40 relevant to the specific data searched for, but the user may override the 41 defaults at all times. 42 43 NOTE: This plugin must be mixed with the specific OS's ProcessFilter 44 implementation in order to bring in standard process selectors. 45 """ 46 47 __args = [ 48 dict(name="scan_physical", default=False, type="Boolean", 49 help="Scan the physical address space only."), 50 51 dict(name="scan_kernel", default=False, type="Boolean", 52 help="Scan the entire kernel address space."), 53 54 # Process Scanning options. 55 dict(name="scan_process_memory", default=False, type="Boolean", 56 help="Scan all of process memory. Uses process selectors to " 57 "narrow down selections."), 58 ] 59 60 scanner_defaults = {} 61
63 """Return True if the user requested any specific regions.""" 64 for k, v in self.plugin_args.items(): 65 if k.startswith("scan_") and v: 66 return True 67 68 return False
69
70 - def generate_memory_ranges(self):
71 """Parse the plugin args and generate memory ranges. 72 73 Yields rekall.addrspace.Run objects. 74 """ 75 if not self.scan_specification_requested(): 76 # Copy the plugin defaults into the args. 77 for k in self.plugin_args: 78 if k.startswith("scan_"): 79 self.plugin_args[k] = self.scanner_defaults.get(k, False) 80 81 # Physical address space requested. 82 if self.plugin_args.scan_physical: 83 yield addrspace.Run( 84 start=0, end=self.session.physical_address_space.end(), 85 address_space=self.session.physical_address_space, 86 data=dict(type="PhysicalAS")) 87 88 # Scan all of the kernel address space. 89 if self.plugin_args.scan_kernel: 90 yield addrspace.Run( 91 start=0, end=self.session.kernel_address_space.end(), 92 address_space=self.session.kernel_address_space, 93 data=dict(type="KernelAS")) 94 95 # Scan the complete process memory, not including the kernel. 96 if self.plugin_args.scan_process_memory: 97 # We use direct inheritance here so we can support process 98 # selectors. 99 for task in self.filter_processes(): 100 cc = self.session.plugins.cc() 101 with cc: 102 # Switch to the process address space. 103 cc.SwitchProcessContext(task) 104 end = self.session.GetParameter("highest_usermode_address") 105 resolver = self.session.address_resolver 106 for module in sorted(resolver.GetAllModules(), 107 key=lambda x: x.start): 108 109 # Skip modules in kernel space. 110 if module.start > end: 111 break 112 113 comment = "%s (%s), %s" % ( 114 task.name, task.pid, module.name) 115 116 self.session.logging.info( 117 "Scanning %s (%s) in: %s [%#x-%#x]", 118 task.name, task.pid, comment, 119 module.start, module.end) 120 121 yield addrspace.Run( 122 start=module.start, end=module.end, 123 address_space=self.session.default_address_space, 124 data=dict(type=comment, module=module, task=task))
125