Package rekall :: Package plugins :: Package overlays :: Package windows :: Module win8
[frames] | no frames]

Source Code for Module rekall.plugins.overlays.windows.win8

  1  # Rekall Memory Forensics 
  2  # Copyright (c) 2008-2011 Volatile Systems 
  3  # Copyright 2013 Google Inc. All Rights Reserved. 
  4   
  5  # Author: 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  # pylint: disable=protected-access 
 23  from rekall import addrspace 
 24  from rekall import kb 
 25  from rekall import obj 
 26  from rekall.plugins.overlays.windows import common 
 27  from rekall.plugins.overlays.windows import win7 
 28  from rekall_lib import utils 
 29   
 30   
31 -def TagOffset(x):
32 if x.obj_profile.metadata("arch") == "AMD64": 33 return x.obj_offset - 12 34 return x.obj_offset - 4
35 36 # In windows 8 the VadRoot is actually composed from _MM_AVL_NODE instead of 37 # _MMVAD structs or _MMADDRESS_NODE. The structs appear to be organised by 38 # functional order - the _MM_AVL_NODE is always the first member of the struct, 39 # then the _MMVAD_SHORT, then the _MMVAD. For example, the tree traversal code, 40 # simply casts all objects to an _MM_AVL_NODE without caring what they actually 41 # are, then depending on the vad tag, they get casted to different structs. 42 43 # Additionally in windows 8.1 there are new fields StartingVpnHigh and 44 # EndingVpnHigh which are chars representing the high part of the PFN. Therefore 45 # the real PFN is (StartingVpnHigh << 32) | StartingVpn. The below overlay 46 # gracefully falls back to the old profiles (where StartingVpnHigh does not 47 # exist). 48 win8_overlays = { 49 '_EPROCESS': [None, { 50 # A symbolic link to the real vad root. 51 'RealVadRoot': lambda x: x.VadRoot.BalancedRoot 52 }], 53 54 '_MM_AVL_NODE': [None, { 55 'Tag': [TagOffset, ['String', dict(length=4)]], 56 }], 57 58 '_RTL_BALANCED_NODE': [None, { 59 'Tag': [TagOffset, ['String', dict(length=4)]], 60 }], 61 62 '_MMVAD_SHORT': [None, { 63 'Tag': [TagOffset, ['String', dict(length=4)]], 64 'Start': lambda x: ( 65 x.StartingVpn + ((x.m("StartingVpnHigh") or 0) << 32)) << 12, 66 67 'End': lambda x: ( 68 (x.EndingVpn + ((x.m("EndingVpnHigh") or 0) << 32))<<12)+0xFFF, 69 70 'Length': lambda x: x.End - x.Start + 1, 71 'CommitCharge': lambda x: x.u1.VadFlags1.CommitCharge, 72 'LeftChild': lambda x: x.VadNode.Left, 73 'RightChild': lambda x: x.VadNode.Right, 74 }], 75 76 '_MMVAD': [None, { 77 'Tag': [TagOffset, ['String', dict(length=4)]], 78 'ControlArea': lambda x: x.Subsection.ControlArea, 79 80 # The following members proxy the embedded _MMVAD_SHORT in .Core. 81 'Start': lambda x: x.Core.Start, 82 'End': lambda x: x.Core.End, 83 'Length': lambda x: x.Core.Length, 84 'CommitCharge': lambda x: x.Core.CommitCharge, 85 'u': lambda x: x.Core.u, 86 'LeftChild': lambda x: x.Core.LeftChild, 87 'RightChild': lambda x: x.Core.RightChild, 88 }], 89 90 '_MMVAD_LONG': [None, { 91 'Tag': [TagOffset, ['String', dict(length=4)]], 92 'ControlArea': lambda x: x.Subsection.ControlArea, 93 94 # The following members proxy the embedded _MMVAD_SHORT in .Core. 95 'Start': lambda x: x.Core.Start, 96 'End': lambda x: x.Core.End, 97 'Length': lambda x: x.Core.Length, 98 'CommitCharge': lambda x: x.Core.CommitCharge, 99 'u': lambda x: x.Core.u, 100 'LeftChild': lambda x: x.Core.LeftChild, 101 'RightChild': lambda x: x.Core.RightChild, 102 }], 103 104 "_CONTROL_AREA": [None, { 105 'FilePointer': [None, ['_EX_FAST_REF', dict( 106 target="_FILE_OBJECT" 107 )]], 108 }], 109 110 '_HANDLE_TABLE_ENTRY' : [None, { 111 # In Windows 8 the Object pointer is replaced with a bitfield. 112 'Object': lambda x: x.obj_profile.Pointer( 113 target="_OBJECT_HEADER", 114 value=(x.ObjectPointerBits << 4 | 0xFFFFE00000000000), 115 vm=x.obj_vm, parent=x) 116 }], 117 118 '_OBJECT_HEADER': [None, { 119 "InfoMask": [None, ["Flags", dict( 120 maskmap=utils.Invert({ 121 0x1: "CreatorInfo", 122 0x2: "NameInfo", 123 0x4: "HandleInfo", 124 0x8: "QuotaInfo", 125 0x10: "ProcessInfo", 126 0x20: "AuditInfo", 127 0x40: "PaddingInfo", 128 }), 129 target="unsigned char", 130 )]], 131 132 'GrantedAccess': lambda x: x.obj_parent.GrantedAccessBits 133 }], 134 135 '_MM_SESSION_SPACE': [None, { 136 # Specialized iterator to produce all the _IMAGE_ENTRY_IN_SESSION 137 # records. 138 'ImageIterator': lambda x: x.ImageList.list_of_type( 139 "_IMAGE_ENTRY_IN_SESSION", "Link") 140 }], 141 142 '_IMAGE_ENTRY_IN_SESSION': [None, { 143 'ImageBase': lambda x: x.Address.v() & ~7 144 }], 145 } 146 147 win8_1_overlays = { 148 '_EPROCESS': [None, { 149 # A symbolic link to the real vad root. 150 'RealVadRoot': lambda x: x.VadRoot.Root 151 }], 152 153 '_HANDLE_TABLE': [None, { 154 'HandleCount': lambda x: obj.NoneObject("Unknown") 155 }], 156 } 157 158 win8_undocumented_amd64 = { 159 # win8.1.raw 18:05:45> dis "nt!MiSessionInsertImage" 160 # 0xf802d314344a 4E e871030300 CALL 0xf802d31737c0 nt!memset 161 # ... 162 # 0xf802d314345a 5E 48897b20 MOV [RBX+0x20], RDI 163 '_IMAGE_ENTRY_IN_SESSION': [None, { 164 'Link': [0, ['_LIST_ENTRY']], 165 'Address': [0x20, ["Pointer"]], 166 }], 167 } 168 169 win8_undocumented_i386 = { 170 '_IMAGE_ENTRY_IN_SESSION': [None, { 171 'Link': [0, ['_LIST_ENTRY']], 172 'Address': [0x10, ["Pointer"]], 173 }], 174 } 175 176
177 -class ObpInfoMaskToOffsetHook(kb.ParameterHook):
178 """By caching this map we can speed up lookups significantly.""" 179 180 name = "ObpInfoMaskToOffset" 181
182 - def calculate(self):
183 table_offset = self.session.profile.get_constant( 184 "ObpInfoMaskToOffset", True) 185 186 # We use a temporary buffer for the object to save reads of the image. 187 cached_vm = addrspace.BufferAddressSpace( 188 data=self.session.kernel_address_space.read(table_offset, 0x100), 189 session=self.session) 190 191 return [int(x) for x in self.session.profile.Array( 192 target="byte", vm=cached_vm, count=0x100)]
193 194
195 -class _PSP_CID_TABLE(common._HANDLE_TABLE):
196 """Subclass the Windows handle table object for parsing PspCidTable""" 197
198 - def get_item(self, entry):
199 p = entry.Object.v() 200 201 handle = self.obj_profile.Object( 202 "_OBJECT_HEADER", 203 offset=(p & ~7) - self.obj_profile.get_obj_offset( 204 '_OBJECT_HEADER', 'Body'), 205 vm=self.obj_vm) 206 207 return handle
208 209
210 -class _MM_AVL_NODE(common.VadTraverser):
211 """All nodes in the Vad tree are treated as _MM_AVL_NODE. 212 213 The Vad structures can be either _MMVAD_SHORT or _MMVAD. At the 214 base of each struct there is an _MM_AVL_NODE which contains the LeftChild 215 and RightChild members. In order to traverse the tree, we follow the 216 _MM_AVL_NODE and create the required _MMVAD type at each point. 217 218 In Windows 8 these behave the same as windows 7's _MMADDRESS_NODE. 219 """ 220 221 ## The actual type depends on this tag value. Windows 8 does not have an 222 ## _MMVAD_LONG. 223 tag_map = {'Vadl': '_MMVAD', 224 'VadS': '_MMVAD_SHORT', 225 'Vad ': '_MMVAD', 226 'VadF': '_MMVAD_SHORT', 227 'Vadm': '_MMVAD', 228 }
229 230
231 -class _RTL_BALANCED_NODE(_MM_AVL_NODE):
232 """Win8.1 renames this type.""" 233 left = "Left" 234 right = "Right"
235 236
237 -def InitializeWindows8Profile(profile):
238 """Initialize windows 8 and 8.1 profiles.""" 239 profile.add_overlay(win8_overlays) 240 241 if profile.metadata("arch") == "AMD64": 242 profile.add_overlay(win8_undocumented_amd64) 243 else: 244 profile.add_overlay(win8_undocumented_i386) 245 246 # Win8.1 changed the vad data structures. 247 if profile.metadata("version") >= 6.3: 248 profile.add_overlay(win8_1_overlays) 249 250 profile.add_classes(dict( 251 _OBJECT_HEADER=win7._OBJECT_HEADER, 252 _PSP_CID_TABLE=_PSP_CID_TABLE, 253 _MM_AVL_NODE=_MM_AVL_NODE, 254 _RTL_BALANCED_NODE=_RTL_BALANCED_NODE, 255 _POOL_HEADER=win7._POOL_HEADER, 256 )) 257 258 # Windows 8 changes many of the pool tags. These come from windbg's 259 # pooltag.txt. 260 profile.add_constants(dict( 261 DRIVER_POOLTAG="Driv", 262 EPROCESS_POOLTAG="Proc", 263 FILE_POOLTAG="File", 264 SYMLINK_POOLTAG="Symb", 265 MODULE_POOLTAG="MmLd", 266 MUTANT_POOLTAG="Muta", 267 THREAD_POOLTAG='Thre', 268 ))
269