1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9   
 10   
 11   
 12   
 13   
 14   
 15   
 16   
 17   
 18   
 19  """This module implements profile indexing. 
 20   
 21  Rekall relies on accurate profiles for reliable analysis of memory artifacts. We 
 22  depend on selecting the correct profile from the profile repository, but 
 23  sometimes its hard to determine the exact profile to use. For windows, the 
 24  profile must match exactly the GUID in the driver. 
 25   
 26  However, sometimes, the GUID is unavailable or it could be manipulated. In that 
 27  case we would like to determine the profile version by applying the index. 
 28   
 29  The profile repository has an index for each kernel module stored. We can use 
 30  this index to determine the exact version of the profile very quickly - even if 
 31  the RSDS GUID is not available or incorrect. 
 32  """ 
 33   
 34  __author__ = "Michael Cohen <scudette@google.com>" 
 35   
 36  from rekall import obj 
 37  from rekall import testlib 
 38  from rekall.plugins.windows import common 
 39  from rekall.plugins.overlays import basic 
 40   
 41   
 42 -class GuessGUID(common.WindowsCommandPlugin): 
  43      """Try to guess the exact version of a kernel module by using an index.""" 
 44   
 45      name = "guess_guid" 
 46   
 47      __args = [ 
 48          dict(name="module", positional=True, 
 49               help="The name of the module to guess."), 
 50   
 51          dict(name="minimal_match", default=1, type="IntParser", 
 52               help="The minimal number of comparison points to be considered. " 
 53               "Sometimes not all comparison points can be used since they may " 
 54               "not be mapped."), 
 55      ] 
 56   
 57      table_header = [ 
 58          dict(name="pid", width=20), 
 59          dict(name="session", width=20), 
 60          dict(name="profile"), 
 61      ] 
 62   
 64          """Scan for module using version_scan for RSDS scanning.""" 
 65          module_name = self.plugin_args.module.split(".")[0] 
 66          for _, guid in self.session.plugins.version_scan( 
 67                  name_regex="^%s.pdb" % module_name).ScanVersions(): 
 68              yield obj.NoneObject(), "%s/GUID/%s" % (module_name, guid) 
  69   
 92   
 94          """Search for suitable profiles using a variety of methods.""" 
 95           
 96           
 97           
 98          for x in self.LookupIndex(): 
 99              yield x 
100   
101           
102           
103          for x in self.ScanProfile(): 
104              yield x 
 105   
107          for context, possibility in self.GuessProfiles(): 
108              yield (context.pid, context.SessionId, possibility) 
  109   
112      """A profile index for _EPROCESS structs.""" 
113   
114      @classmethod 
123   
125          self.index = index 
126   
127           
128           
129          self.filename_to_dtb = set() 
130          for metadata in index.values(): 
131              offsets = metadata["offsets"] 
132              relative_offset = offsets["_EPROCESS.ImageFileName"] - ( 
133                  offsets["_EPROCESS.Pcb"] + 
134                  offsets["_KPROCESS.DirectoryTableBase"]) 
135   
136              arch = metadata.get("arch", "AMD64") 
137              self.filename_to_dtb.add((relative_offset, arch)) 
  138   
144