1  """Rekall plugins for displaying processes in live triaging.""" 
  2   
  3  import psutil 
  4  from efilter.protocols import structured 
  5   
  6  from rekall_lib import utils 
  7   
  8  from rekall.plugins import core 
  9  from rekall.plugins.response import common 
 10  from rekall.plugins.overlays import basic 
 11   
 12  from rekall.plugins import yarascanner 
 16      """An object to represent a live process. 
 17   
 18      This is the live equivalent of _EPROCESS. 
 19      """ 
 20      __slots__ = ("_proc", "_obj_profile", "session", 
 21                   "start_time", "obj_offset", "pid") 
 22   
 23      obj_offset = 0 
 24   
 39   
 40      @utils.safe_property 
 42           
 43           
 44          if self._obj_profile is None: 
 45              self._obj_profile = common.IRProfile( 
 46                  session=self.session, proc=self) 
 47   
 48          return self._obj_profile 
  49   
 52   
 54          try: 
 55              result = getattr(self._proc, field_name) 
 56              if callable(result): 
 57                  result = result() 
 58   
 59              return result 
 60          except psutil.Error: 
 61               
 62              if field_name == "environ": 
 63                  return {} 
 64   
 65              return None 
 66          except AttributeError: 
 67              return None 
  68   
 78   
 80          return "<Live Process pid=%s>" % self.pid 
  81   
 84   
 86          try: 
 87              return self._proc.as_dict() 
 88          except Exception: 
 89               
 90              return {} 
   91   
 92   
 93  psutil_fields = ['cmdline', 'connections', 'cpu_affinity', 
 94                   'cpu_percent', 'cpu_times', 'create_time', 
 95                   'cwd', 'environ', 'exe', 'gids', 'io_counters', 
 96                   'ionice', 'memory_full_info', 'memory_info', 
 97                   'memory_info_ex', 'memory_maps', 'memory_percent', 
 98                   'name', 'nice', 'num_ctx_switches', 'num_fds', 
 99                   'num_threads', 'open_files', 'pid', 'ppid', 
100                   'status', 'terminal', 'threads', 'uids', 'username', 
101                   'num_handles'] 
102   
103   
104  properties = dict(__slots__=()) 
105  for field in psutil_fields: 
106      properties[field] = property( 
107          lambda self, field=field: self._get_field(field)) 
108   
109  LiveProcess = type("LiveProcess", (_LiveProcess, ), properties) 
110   
111   
112  structured.IStructured.implement( 
113      for_type=LiveProcess, 
114      implementations={ 
115          structured.resolve: lambda d, m: getattr(d, m, None), 
116          structured.getmembers_runtime: lambda d: set(psutil_fields + d.keys()), 
117      } 
118  ) 
122      """A live process filter using the system APIs.""" 
123   
124      __abstract = True 
125   
126      __args = [ 
127          dict(name="pids", positional=True, type="ArrayIntParser", default=[], 
128               help="One or more pids of processes to select."), 
129   
130          dict(name="proc_regex", default=None, type="RegEx", 
131               help="A regex to select a process by name."), 
132      ] 
133   
134      @utils.safe_property 
137   
152   
 158   
160      """A plugin which lists all open files.""" 
161      name = "lsof" 
162   
163      table_header = [ 
164          dict(name="divider", type="Divider"), 
165          dict(name="proc", hidden=True), 
166          dict(name="file", hidden=True), 
167          dict(name="name", width=30), 
168          dict(name="pid", width=6, align="r"), 
169          dict(name="user", width=8), 
170          dict(name="fd", width=4), 
171          dict(name="mode", width=4), 
172          dict(name="offset", width=12), 
173          dict(name="node", width=8), 
174          dict(name="path"), 
175      ] 
176   
 190   
194      """A live pslist plugin using the APIs.""" 
195   
196      name = "pslist" 
197   
198      table_header = [ 
199          dict(name="proc", hidden=True), 
200          dict(name="Name", width=30), 
201          dict(name="pid", width=6, align="r"), 
202          dict(name="ppid", width=6, align="r"), 
203          dict(name="Thds", width=6, align="r"), 
204          dict(name="Hnds", width=8, align="r"), 
205          dict(name="wow64", width=6), 
206          dict(name="start", width=24), 
207          dict(name="binary"), 
208      ] 
209   
212   
214          """Determine if the proc is Wow64.""" 
215           
216          return (proc.environ.get("PROCESSOR_ARCHITECTURE") == 'x86' and 
217                  proc.environ.get("PROCESSOR_ARCHITEW6432") == 'AMD64') 
 218   
219 -    def _row(self, proc): 
 229   
 233   
234   
235 -class APISetProcessContext(core.SetProcessContextMixin, 
236                             APIProcessFilter): 
 237      """A cc plugin for setting process context to live mode.""" 
238      name = "cc" 
 239   
242      """Scanner for scanning processes using the ReadProcessMemory() API.""" 
243   
244      __abstract = True 
245   
 266   
269      """Yara scan process memory using the ReadProcessMemory() API.""" 
270      name = "yarascan" 
 271