1   
  2   
  3   
  4   
  5   
  6   
  7   
  8   
  9   
 10   
 11   
 12   
 13   
 14   
 15   
 16   
 17   
 18   
 19   
 20   
 21   
 22   
 23  from rekall import plugin 
 24  from rekall import scan 
 25  from rekall.plugins.windows import common 
 26  from rekall_lib import utils 
 27   
 28   
 29 -class Modules(common.WindowsCommandPlugin): 
  30      """Print list of loaded kernel modules.""" 
 31   
 32      __name = "modules" 
 33   
 34      __args = [ 
 35          dict(name="name_regex", type="RegEx", 
 36               help="Filter module names by this regex.") 
 37      ] 
 38   
 39      table_header = [ 
 40          dict(name="_LDR_DATA_TABLE_ENTRY", style="address"), 
 41          dict(name="name", width=20), 
 42          dict(name="base", style="address"), 
 43          dict(name="size", style="address"), 
 44          dict(name="path") 
 45      ] 
 46   
 48          """ A Generator for modules (uses _KPCR symbols) """ 
 49          for module in self.session.GetParameter( 
 50                  "PsLoadedModuleList").list_of_type( 
 51                      "_LDR_DATA_TABLE_ENTRY", "InLoadOrderLinks"): 
 52   
 53               
 54              if (self.plugin_args.name_regex and 
 55                      not self.plugin_args.name_regex.search( 
 56                          utils.SmartUnicode(module.FullDllName))): 
 57                  continue 
 58   
 59              yield module 
  60   
 62          """Returns a list of module addresses.""" 
 63          return sorted(self.mod_lookup.keys()) 
  64   
 66          object_tree_plugin = self.session.plugins.object_tree() 
 67   
 68          for module in self.lsmod(): 
 69              yield dict(_LDR_DATA_TABLE_ENTRY=module, 
 70                         name=module.BaseDllName, 
 71                         base=module.DllBase, 
 72                         size=module.SizeOfImage, 
 73                         path=object_tree_plugin.FileNameWithDrive( 
 74                             module.FullDllName.v())) 
   75   
 76   
 78      """Scan for RSDS objects.""" 
 79   
 80      checks = [ 
 81          ("StringCheck", dict(needle="RSDS")) 
 82          ] 
  83   
 84   
 86      """Try to determine the versions for all kernel drivers.""" 
 87   
 88      __name = "version_modules" 
 89   
 90      table_header = [ 
 91          dict(name="offset_v", style="address"), 
 92          dict(name="name", width=20), 
 93          dict(name="guid", width=33), 
 94          dict(name="pdb") 
 95      ] 
 96   
 98          pe_profile = self.session.LoadProfile("pe") 
 99          scanner = RSDSScanner(address_space=self.kernel_address_space, 
100                                session=self.session) 
101   
102          for module in self.lsmod(): 
103              for hit in scanner.scan(offset=int(module.DllBase), 
104                                      maxlen=int(module.SizeOfImage)): 
105   
106                  rsds = pe_profile.CV_RSDS_HEADER(offset=hit, 
107                                                   vm=self.kernel_address_space) 
108                  guid = "%s%x" % (rsds.GUID.AsString, rsds.Age) 
109                  yield module, rsds, guid 
 110   
112          for module, rsds, guid in self.ScanVersions(): 
113              yield dict(offset_v=rsds, 
114                         name=module.BaseDllName, 
115                         guid=guid, 
116                         pdb=rsds.Filename) 
  117   
118   
119 -class VersionScan(plugin.PhysicalASMixin, plugin.TypedProfileCommand, 
120                    plugin.Command): 
 121      """Scan the physical address space for RSDS versions.""" 
122   
123      __name = "version_scan" 
124   
125      PHYSICAL_AS_REQUIRED = False 
126   
127      __args = [ 
128          dict(name="name_regex", type="RegEx", default=".", 
129               help="Filter module names by this regex."), 
130   
131          dict(name="scan_filename", required=False, positional=True, 
132               help="Optional file to scan. If not specified " 
133               "we scan the physical address space.") 
134      ] 
135   
136      table_header = [ 
137          dict(name="offset", style="address"), 
138          dict(name="guid", width=33), 
139          dict(name="pdb", width=30) 
140      ] 
141   
149   
171   
173          for rsds, guid in self.ScanVersions(): 
174              yield dict(offset=rsds, guid=guid, pdb=rsds.Filename) 
  175   
176   
178      """Print a list of recently unloaded modules. 
179   
180      Ref: 
181      http://volatility-labs.blogspot.de/2013/05/movp-ii-22-unloaded-windows-kernel_22.html 
182      """ 
183   
184      name = "unloaded_modules" 
185   
186      table_header = [ 
187          dict(name="name", width=20), 
188          dict(name="start", style="address"), 
189          dict(name="end", style="address"), 
190          dict(name="time") 
191      ] 
192   
194          unloaded_table = self.profile.get_constant_object( 
195              "MmUnloadedDrivers", 
196              target="Pointer", 
197              target_args=dict( 
198                  target="Array", 
199                  target_args=dict( 
200                      target="_UNLOADED_DRIVER", 
201                      count=self.profile.get_constant_object( 
202                          "MmLastUnloadedDriver", "unsigned int").v(), 
203                      ) 
204                  ) 
205              ) 
206   
207           
208          if unloaded_table == None: 
209              mistate = self.profile.get_constant_object( 
210                  "MiState", target="_MI_SYSTEM_INFORMATION") 
211   
212              unloaded_table = mistate.multi_m( 
213                  "UnloadedDrivers", 
214                  "Vs.UnloadedDrivers" 
215              ).dereference_as( 
216                  "Array", 
217                  target_args=dict( 
218                      target="_UNLOADED_DRIVERS", 
219                      count=mistate.LastUnloadedDriver) 
220              ) 
221   
222          for driver in unloaded_table: 
223              yield (driver.Name, 
224                     driver.StartAddress.v(), 
225                     driver.EndAddress.v(), 
226                     driver.CurrentTime) 
  227