1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9   
 10   
 11   
 12   
 13   
 14   
 15   
 16   
 17   
 18   
 19   
 20   
 21   
 22   
 23   
 24   
 25   
 26   
 27   
 28   
 29   
 30   
 31   
 32   
 33   
 34  import re 
 35   
 36  from rekall import scan 
 37  from rekall.plugins import core 
 38  from rekall.plugins.addrspaces import intel 
 39  from rekall.plugins.common import pfn 
 40  from rekall.plugins.windows import address_resolver 
 41  from rekall.plugins.windows import common 
 42  from rekall.plugins.windows import pagefile 
 43  from rekall_lib import utils 
 44   
 45   
 46 -class VAD(common.WinProcessFilter): 
  47      """Concise dump of the VAD. 
 48   
 49      Similar to windbg's !vad. 
 50      """ 
 51   
 52      __name = "vad" 
 53   
 54      __args = [ 
 55          dict(name="regex", type="RegEx", 
 56               help="A regular expression to filter VAD filenames."), 
 57   
 58          dict(name="offset", type="IntParser", 
 59               help="Only print the vad corresponding to this offset.") 
 60      ] 
 61   
 62      table_header = [ 
 63          dict(name='_EPROCESS', type="_EPROCESS", hidden=True), 
 64          dict(name="divider", type="Divider"), 
 65          dict(name='VAD', style="address"), 
 66          dict(name='lev', width=3, align="r"), 
 67          dict(name='start', style="address"), 
 68          dict(name='end', style="address"), 
 69          dict(name='com', width=6, align="r"), 
 70          dict(name='type', width=7), 
 71          dict(name='exe', width=6), 
 72          dict(name='protect', width=20), 
 73          dict(name='filename') 
 74      ] 
 75   
 79   
 81          return dict( 
 82              _EPROCESS=self.session.profile._EPROCESS(), 
 83              divider=self.session.profile._EPROCESS(), 
 84              VAD=self.session.profile._MMVAD(), 
 85              lev=int, 
 86              start=self.session.profile.Pointer(), 
 87              end=self.session.profile.Pointer(), 
 88              com=int, 
 89              type=str, 
 90              exe=str, 
 91              protect=self.session.profile.Enumeration(), 
 92              filename=str) 
  93   
 98   
100          resolver = self.GetVadsForProcess(task) 
101          if resolver: 
102              _, _, data = resolver.get_containing_range(addr) 
103              return data 
 104   
106          result = utils.RangedCollection() 
107          self.session.report_progress( 
108              " Enumerating VADs in %s (%s)", task.name, task.pid) 
109   
110          for vad in task.RealVadRoot.traverse(): 
111              result.insert(vad.Start, vad.End, (self._get_filename(vad), vad)) 
112   
113          return result 
 114   
116          try: 
117              resolver = self._cache[task] 
118          except KeyError: 
119               
120               
121               
122               
123              self._cache[task] = None 
124              resolver = self._cache[task] = self._make_cache(task) 
125   
126          return resolver 
 127   
129          filename = "" 
130          try: 
131              file_obj = vad.ControlArea.FilePointer 
132              if file_obj: 
133                  filename = file_obj.FileName or "Pagefile-backed section" 
134          except AttributeError: 
135              pass 
136   
137          return unicode(filename) 
 138   
140          task_as = task.get_process_address_space() 
141          result = [] 
142          for vad in vad_root.traverse(): 
143               
144              if self.plugin_args.regex and not re.search( 
145                      self.plugin_args.regex, self._get_filename(vad)): 
146                  continue 
147   
148              if (self.plugin_args.offset is not None and 
149                      not vad.Start <= self.plugin_args.offset <= vad.End): 
150                  continue 
151   
152              exe = "" 
153              if "EXECUTE" in str(vad.u.VadFlags.ProtectionEnum): 
154                  exe = "Exe" 
155   
156              result.append(dict( 
157                  VAD=vad, 
158                  lev=vad.obj_context.get('depth', 0), 
159   
160                   
161                  start=self.profile.Pointer(value=vad.Start, vm=task_as), 
162                  end=self.profile.Pointer(value=vad.End, vm=task_as), 
163                  com=vad.CommitCharge if vad.CommitCharge < 0x7fffffff else -1, 
164                  type="Private" if vad.u.VadFlags.PrivateMemory > 0 else "Mapped", 
165                  exe=exe, 
166                  protect=vad.u.VadFlags.ProtectionEnum, 
167                  filename=self._get_filename(vad))) 
168   
169           
170          result.sort(key=lambda x: x["start"].v()) 
171          return result 
 172   
174          for task in self.filter_processes(): 
175              yield dict(_EPROCESS=task, divider=task) 
176   
177              for row in self.collect_vadroot(task.RealVadRoot, task): 
178                  row["_EPROCESS"] = task 
179                  yield row 
  180   
181   
182 -class VADMap(pfn.VADMapMixin, common.WinProcessFilter): 
 183      """Inspect each page in the VAD and report its status. 
184   
185      This allows us to see the address translation status of each page in the 
186      VAD. 
187      """ 
188   
238   
253   
 263   
264   
265 -class VADDump(core.DirectoryDumperMixin, VAD): 
 266      """Dumps out the vad sections to a file""" 
267   
268      __name = "vaddump" 
269   
270      @classmethod 
271 -    def args(cls, parser): 
 276   
278          self.max_size = kwargs.pop("max_size", 100*1024*1024) 
279          super(VADDump, self).__init__(*args, **kwargs) 
 280   
282          for task in self.filter_processes(): 
283              renderer.section("{0:6} ({1:2})".format( 
284                  task.name, task.UniqueProcessId)) 
285   
286              renderer.table_header([ 
287                  ("Start", "start", "[addrpad]"), 
288                  ("End", "end", "[addrpad]"), 
289                  ("Length", "length", "[addr]"), 
290                  ("Filename", "filename", "60s"), 
291                  ("Comment", "comment", "")]) 
292   
293               
294              task_space = task.get_process_address_space() 
295   
296              name = task.ImageFileName 
297              offset = task_space.vtop(task.obj_offset) 
298              if offset is None: 
299                  renderer.format( 
300                      "Process does not have a valid address space.\n") 
301                  continue 
302   
303              with self.session.plugins.cc() as cc: 
304                  cc.SwitchProcessContext(task) 
305   
306                  for vad in task.RealVadRoot.traverse(): 
307                       
308                      start = vad.Start 
309                      end = vad.End 
310   
311                      filename = "{0}.{1:x}.{2:08x}-{3:08x}.dmp".format( 
312                          name, offset, start, end) 
313   
314                      with renderer.open(directory=self.dump_dir, 
315                                         filename=filename, 
316                                         mode='wb') as fd: 
317   
318                          if end - start > self.max_size: 
319                              renderer.table_row(start, end, end-start, 
320                                                 "Skipped - Region too large") 
321                              continue 
322   
323                          self.session.report_progress("Dumping %s" % filename) 
324   
325                          self.CopyToFile(task_space, start, end + 1, fd) 
326                          renderer.table_row( 
327                              start, end, end-start, filename, 
328                              self._get_filename(vad)) 
  329   
332      """A scanner over all memory regions of a process.""" 
333   
334 -    def __init__(self, task=None, process_profile=None, **kwargs): 
 335          """Scan the process address space through the Vads. 
336   
337          Args: 
338            task: The _EPROCESS object for this task. 
339   
340            process_profile: The specialized profile for this process. In practice 
341              this is always different from task.obj_profile (which belongs to the 
342              kernel). If not provided we default to the kernel profile. 
343          """ 
344          self.task = task 
345          super(VadScanner, self).__init__( 
346              profile=process_profile or task.obj_profile, 
347              address_space=task.get_process_address_space(), 
348              **kwargs) 
 349   
350 -    def scan(self, offset=0, maxlen=None): 
  357