Package rekall :: Package plugins :: Package windows :: Package malware :: Module devicetree
[frames] | no frames]

Source Code for Module rekall.plugins.windows.malware.devicetree

  1  # Rekall Memory Forensics 
  2  # Copyright (c) 2010, 2011, 2012 Michael Ligh <michael.ligh@mnin.org> 
  3  # Copyright 2013 Google Inc. All Rights Reserved. 
  4  # 
  5  # This program is free software; you can redistribute it and/or modify 
  6  # it under the terms of the GNU General Public License as published by 
  7  # the Free Software Foundation; either version 2 of the License, or (at 
  8  # your option) any later version. 
  9  # 
 10  # This program is distributed in the hope that it will be useful, but 
 11  # WITHOUT ANY WARRANTY; without even the implied warranty of 
 12  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
 13  # General Public License for more details. 
 14  # 
 15  # You should have received a copy of the GNU General Public License 
 16  # along with this program; if not, write to the Free Software 
 17  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 
 18  # 
 19  from rekall.plugins.windows import common 
 20  from rekall.plugins.windows import filescan 
 21  from rekall_lib import utils 
 22   
 23   
24 -class DeviceTree(common.PoolScannerPlugin):
25 "Show device tree." 26 27 __name = "devicetree" 28 29 table_header = [ 30 dict(name="Type", type="TreeNode", width=10, max_depth=10), 31 dict(name="Address", style="address", padding="0"), 32 dict(name="Name", width=30), 33 dict(name="device_type", width=30), 34 dict(name="Path"), 35 ] 36 37 scanner_defaults = dict( 38 scan_kernel_nonpaged_pool=True 39 ) 40
41 - def generate_hits(self):
42 for run in self.generate_memory_ranges(): 43 scanner = filescan.PoolScanDriver( 44 session=self.session, profile=self.profile, 45 address_space=run.address_space) 46 47 for pool_obj in scanner.scan(run.start, run.length): 48 for object_obj in pool_obj.IterObject("Driver", freed=True): 49 yield object_obj.Object
50
51 - def collect(self):
52 for driver_obj in self.generate_hits(): 53 yield dict( 54 Type=utils.AttributedString("DRV", [(0, 30, "BLACK", "RED")]), 55 Address=driver_obj.obj_offset, 56 Name=driver_obj.DriverName.v(vm=self.kernel_address_space), 57 depth=0) 58 59 first_device = driver_obj.DeviceObject.dereference( 60 vm=self.kernel_address_space) 61 62 for device in first_device.walk_list("NextDevice"): 63 device_header = self.profile.Object( 64 "_OBJECT_HEADER", offset=device.obj_offset - 65 device.obj_profile.get_obj_offset("_OBJECT_HEADER", "Body"), 66 vm=device.obj_vm) 67 68 device_name = device_header.NameInfo.Name.cast( 69 vm=self.kernel_address_space) 70 71 yield dict( 72 Type=utils.AttributedString( 73 "DEV", [(0, 30, "WHITE", "BLUE")]), 74 Address=device.obj_offset, Name=device_name, 75 device_type=device.DeviceType, 76 depth=1) 77 78 level = 1 79 80 for att_device in device.walk_list( 81 "AttachedDevice", include_current=False): 82 yield dict( 83 Type=utils.AttributedString( 84 "ATT", [(0, 30, "BLACK", "GREEN")]), 85 Address=att_device.obj_offset, Name=device_name, 86 device_type=att_device.DeviceType, 87 Path=att_device.DriverObject.DriverName, 88 depth=level + 1) 89 90 level += 1
91 92
93 -class DriverIrp(common.PoolScannerPlugin):
94 "Driver IRP hook detection" 95 96 __name = "driverirp" 97 98 mod_re = None 99 100 __args = [ 101 dict(name="regex", type="RegEx", 102 help='Analyze drivers matching REGEX'), 103 ] 104 105 table_header = [ 106 dict(name="divider", type="Divider"), 107 dict(name="driver", hidden=True), 108 dict(name="idx", width=4, align="r"), 109 dict(name="function", width=36), 110 dict(name="func_addres", style="address"), 111 dict(name="name") 112 ] 113
114 - def generate_hits(self):
115 if not self.scan_specification_requested(): 116 obj_tree_plugin = self.session.plugins.object_tree( 117 type_regex="Driver") 118 for hit in obj_tree_plugin.collect(): 119 yield hit["_OBJECT_HEADER"].Object 120 121 return 122 123 for run in self.generate_memory_ranges(): 124 scanner = filescan.PoolScanDriver( 125 session=self.session, profile=self.profile, 126 address_space=run.address_space) 127 128 for pool_obj in scanner.scan(run.start, run.length): 129 for object_obj in pool_obj.IterObject("Driver", freed=True): 130 yield object_obj.Object
131
132 - def collect(self):
133 invalid_address = self.session.address_resolver.get_constant_object( 134 "nt!IopInvalidDeviceRequest", "Function").obj_offset 135 136 for driver_obj in self.generate_hits(): 137 driver_name = driver_obj.DriverName.v(vm=self.kernel_address_space) 138 139 # Continue if a regex was supplied and it doesn't match 140 if self.plugin_args.regex: 141 if not driver_name: 142 continue 143 144 # Continue if a regex was supplied and it doesn't match 145 if not self.plugin_args.regex.search(driver_name): 146 continue 147 148 driver_start = driver_obj.DriverStart.v() 149 driver_end = driver_obj.DriverStart.v() + driver_obj.DriverSize 150 151 interesting = False 152 functions = [] 153 # Write the address and owner of each IRP function 154 for i, function in enumerate(driver_obj.MajorFunction): 155 # Make sure this is in the kernel address space. 156 function = driver_obj.MajorFunction[i].dereference( 157 vm=self.kernel_address_space) 158 159 func_addres = function.obj_offset 160 if func_addres == None: 161 continue 162 163 symbol = utils.FormattedAddress( 164 self.session.address_resolver, func_addres) 165 166 # Suppress function pointers which point at the default invalid 167 # address function. 168 if (self.plugin_args.verbosity < 5 and 169 func_addres == invalid_address): 170 continue 171 172 highlight = None 173 174 # Functions residing within the driver are not suspicious. 175 if not (driver_start <= func_addres <= driver_end): 176 interesting = True 177 # Extra important if we have no idea where it came from. 178 if not self.session.address_resolver.format_address( 179 func_addres): 180 highlight = "important" 181 182 functions.append(dict(driver=driver_obj, 183 idx=i, 184 function=function.obj_name, 185 func_addres=func_addres, 186 name=symbol, 187 highlight=highlight)) 188 189 # By default only show interesting drivers. 190 if (self.plugin_args.verbosity < 2 and not interesting): 191 continue 192 193 # Write the standard header for each driver object 194 divider = "DriverName: %s %#x-%#x" % ( 195 driver_name, driver_start, driver_end) 196 197 yield dict(divider=divider) 198 199 for x in functions: 200 yield x
201