Package rekall :: Package plugins :: Package windows :: Module ssdt
[frames] | no frames]

Source Code for Module rekall.plugins.windows.ssdt

  1  # Rekall Memory Forensics 
  2  # Copyright 2014 Google Inc. All Rights Reserved. 
  3  # 
  4  # Authors: 
  5  # Michael Cohen <scudette@gmail.com> 
  6   
  7  # This program is free software; you can redistribute it and/or modify 
  8  # it under the terms of the GNU General Public License as published by 
  9  # the Free Software Foundation; either version 2 of the License, or (at 
 10  # your option) any later version. 
 11  # 
 12  # This program is distributed in the hope that it will be useful, but 
 13  # WITHOUT ANY WARRANTY; without even the implied warranty of 
 14  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
 15  # General Public License for more details. 
 16  # 
 17  # You should have received a copy of the GNU General Public License 
 18  # along with this program; if not, write to the Free Software 
 19  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
 20  # 
 21   
 22   
 23  # This code is loosely based on the original Volatility code, except that it is 
 24  # much simpler, since all the information we need is taken directly from the 
 25  # profile. 
 26   
 27  from rekall.plugins.windows import common 
 28  from rekall_lib import utils 
 29   
 30   
31 -class WinSSDT(common.WindowsCommandPlugin):
32 """Enumerate the SSDT.""" 33 34 name = "ssdt" 35 36 table_header = [ 37 dict(name="divider", type="Divider"), 38 dict(name="entry_obj", hidden=True), 39 dict(name="entry", style="address"), 40 dict(name="target", style="address"), 41 dict(name="symbol") 42 ] 43
44 - def _find_process_context(self, table_ptr, cc):
45 for proc in self.session.plugins.pslist( 46 proc_regex="csrss").filter_processes(): 47 48 cc.SwitchProcessContext(proc) 49 table_ptr.obj_vm = self.session.GetParameter( 50 "default_address_space") 51 52 if table_ptr.is_valid(): 53 break 54 55 return table_ptr
56
57 - def _render_x64_table(self, table):
58 resolver = self.session.address_resolver 59 60 for j, entry in enumerate(table): 61 function_address = table.v() + (entry >> 4) 62 yield dict( 63 entry=j, target=function_address, 64 symbol=utils.FormattedAddress(resolver, function_address))
65
66 - def _render_x86_table(self, table):
67 resolver = self.session.address_resolver 68 69 for j, function_address in enumerate(table): 70 yield dict( 71 entry=j, target=function_address, 72 symbol=utils.FormattedAddress(resolver, function_address))
73
74 - def collect(self):
75 # Directly get the SSDT. 76 # http://en.wikipedia.org/wiki/System_Service_Dispatch_Table 77 ssdt = self.session.address_resolver.get_constant_object( 78 "nt!KeServiceDescriptorTableShadow", 79 target="_SERVICE_DESCRIPTOR_TABLE") 80 81 cc = self.session.plugins.cc() 82 with cc: 83 for i, descriptor in enumerate(ssdt.Descriptors): 84 table_ptr = descriptor.KiServiceTable 85 86 # Sometimes the table is not mapped. In this case we need to 87 # find a process context which maps the win32k.sys driver. 88 if table_ptr[0] == 0: 89 table_ptr = self._find_process_context(table_ptr, cc) 90 91 yield dict( 92 divider="Table %s @ %#x" % (i, table_ptr[0].obj_offset)) 93 94 if self.profile.metadata("arch") == "AMD64": 95 for x in self._render_x64_table(table_ptr): 96 yield x 97 else: 98 for x in self._render_x86_table(table_ptr): 99 yield x
100