Package rekall :: Package plugins :: Package darwin :: Module zones
[frames] | no frames]

Source Code for Module rekall.plugins.darwin.zones

  1  # Rekall Memory Forensics 
  2  # 
  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  """ 
 20  Collectors and plugins that deal with Darwin zone allocator. 
 21  """ 
 22   
 23  __author__ = "Adam Sindelar <adamsh@google.com>" 
 24   
 25  from rekall_lib import utils 
 26   
 27  from rekall.plugins.darwin import common 
28 29 30 -class DarwinZoneHook(common.AbstractDarwinParameterHook):
31 """Lists all allocation zones.""" 32 33 name = "zones" 34
35 - def calculate(self):
36 first_zone = self.session.profile.get_constant_object( 37 "_first_zone", 38 target="Pointer", 39 target_args=dict( 40 target="zone")) 41 42 return [x.obj_offset for x in first_zone.walk_list("next_zone")]
43
44 45 -class DarwinZoneCollector(common.AbstractDarwinCachedProducer):
46 name = "zones" 47 type_name = "zone"
48
49 50 -class AbstractZoneElementFinder(common.AbstractDarwinParameterHook):
51 """Finds all the valid structs in an allocation zone.""" 52 53 __abstract = True 54 55 zone_name = None 56 type_name = None 57
58 - def validate_element(self, element):
59 raise NotImplementedError("Subclasses must override.")
60
61 - def calculate(self):
62 # Find the zone that contains our data. 63 zone = self.session.plugins.search( 64 "(select zone from zones() where zone.name == ?).zone", 65 query_parameters=[self.zone_name]).first_result 66 67 if not zone: 68 raise ValueError("Zone %r doesn't exist." % self.zone_name) 69 70 results = set() 71 for offset in zone.known_offsets: 72 element = self.session.profile.Object(offset=offset, 73 type_name=self.type_name) 74 75 if self.validate_element(element): 76 results.add(element.obj_offset) 77 78 return results
79
80 81 -class DarwinDumpZone(common.AbstractDarwinCommand):
82 """Dumps an allocation zone's contents.""" 83 84 name = "dump_zone" 85 86 table_header = [ 87 dict(name="offset", style="address"), 88 dict(name="data", width=34) 89 ] 90 91 @classmethod
92 - def args(cls, parser):
93 super(DarwinDumpZone, cls).args(parser) 94 parser.add_argument("--zone", default="buf.512")
95
96 - def __init__(self, zone="buf.512", **kwargs):
97 super(DarwinDumpZone, self).__init__(**kwargs) 98 self.zone_name = zone
99
100 - def collect(self):
101 zone = self.session.plugins.search( 102 "(select zone from zones() where zone.name == {zone_name}).zone", 103 query_parameters=dict(zone_name=self.zone_name), 104 silent=True 105 ).first_result 106 107 if not zone: 108 raise ValueError("No such zone %r." % self.zone_name) 109 110 for offset in zone.known_offsets: 111 yield dict(offset=offset, 112 data=utils.HexDumpedString( 113 zone.obj_vm.read(offset, zone.elem_size)))
114
115 116 # All plugins below dump and validate elements from specific zones. 117 118 119 -class DarwinSocketZoneFinder(AbstractZoneElementFinder):
120 name = "dead_sockets" 121 zone_name = "socket" 122 type_name = "socket" 123
124 - def validate_element(self, socket):
125 return socket == socket.so_rcv.sb_so
126
127 128 -class DarwinSocketZoneCollector(common.AbstractDarwinCachedProducer):
129 name = "dead_sockets" 130 type_name = "socket"
131
132 133 -class DarwinTTYZoneFinder(AbstractZoneElementFinder):
134 name = "dead_ttys" 135 zone_name = "ttys" 136 type_name = "tty" 137
138 - def validate_element(self, tty):
139 return tty.t_lock == tty
140
141 142 -class DarwinTTYZoneCollector(common.AbstractDarwinCachedProducer):
143 name = "dead_ttys" 144 type_name = "tty"
145
146 147 -class DarwinSessionZoneFinder(AbstractZoneElementFinder):
148 name = "dead_sessions" 149 zone_name = "session" 150 type_name = "session" 151
152 - def validate_element(self, session):
153 return session.s_count > 0 and session.s_leader.p_argc > 0
154
155 156 -class DarwinSessionZoneCollector(common.AbstractDarwinCachedProducer):
157 name = "dead_sessions" 158 type_name = "session"
159
160 161 -class DarwinZoneVnodeFinder(AbstractZoneElementFinder):
162 zone_name = "vnodes" 163 type_name = "vnode" 164 name = "dead_vnodes" 165
166 - def validate_element(self, vnode):
167 # Note for later: HFS-related vnodes can be validated 168 # by the pointer they have back to the vnode from the cnode (v_data). 169 return vnode.v_owner == 0 and vnode.v_mount != 0
170
171 172 -class DarwinZoneVnodeCollector(common.AbstractDarwinCachedProducer):
173 name = "dead_vnodes" 174 type_name = "vnode"
175
176 177 -class PsListDeadProcFinder(AbstractZoneElementFinder):
178 name = "dead_procs" 179 zone_name = "proc" 180 type_name = "proc" 181
182 - def validate_element(self, element):
183 return element.validate()
184
185 186 -class DarwinDeadProcessCollector(common.AbstractDarwinCachedProducer):
187 """Lists dead processes using the proc allocation zone.""" 188 name = "dead_procs" 189 type_name = "proc"
190
191 192 -class DarwinZoneFileprocFinder(AbstractZoneElementFinder):
193 name = "dead_fileprocs" 194 type_name = "fileproc" 195 zone_name = "fileproc" 196
197 - def validate_element(self, element):
198 return True
199
200 201 -class DarwinDeadFileprocCollector(common.AbstractDarwinCachedProducer):
202 name = "dead_fileprocs" 203 type_name = "fileproc"
204