Trees | Indices | Help |
|
---|
|
1 #!/usr/bin/python 2 3 # Rekall Memory Forensics 4 # Copyright (C) 2014 Michael Cohen <scudette@gmail.com> 5 # Copyright 2014 Google Inc. All Rights Reserved. 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 """This module discovers the kernel base address. 22 23 The profile provides kernel addresses relative to the kernel base address. This 24 varies each time, so we need a way to locate the kernel base address in the 25 kernel address space. 26 """ 27 28 __author__ = "Michael Cohen <scudette@google.com>" 29 30 from rekall import obj 31 from rekall import scan 32 from rekall.plugins import core 33 from rekall.plugins.windows import common 34 from rekall.plugins.overlays.windows import pe_vtypes38 # We search for the name of a section present in the PE header. 39 checks = [("MultiStringFinderCheck", dict(needles=[ 40 "INITKDBG", "MISYSPTE", "PAGEKD"]))]4144 """Cache the object tree.""" 45 46 name = "object_tree" 479549 for x in root: 50 # This prevents circular references to parent objects. They should 51 # never happen but some possibly corrupt images may contain links to 52 # parent objects. 53 if x.obj_offset in seen: 54 continue 55 56 seen.add(x.obj_offset) 57 58 name = x.NameInfo.Name.v() 59 if name == None: 60 continue 61 62 # We store the _OBJECT_HEADER offset and some metadata about the 63 # types. 64 object_type = x.get_object_type() 65 entry = result[name] = dict( 66 type=object_type, 67 type_name="_OBJECT_HEADER", 68 offset=x.obj_offset, 69 ) 70 71 if object_type == "Directory": 72 children = entry["Children"] = {} 73 self.BuildTree(children, x.Object, seen)74 75 @core.MethodWithAddressSpace()77 seen = set() 78 79 root = self.session.profile.get_constant_object( 80 "ObpRootDirectoryObject", 81 target="Pointer", 82 target_args=dict( 83 target="_OBJECT_DIRECTORY" 84 ) 85 ) 86 87 result = dict( 88 type="Directory", 89 type_name="_OBJECT_DIRECTORY", 90 offset=root.deref().obj_offset, 91 Children={}) 92 93 self.BuildTree(result["Children"], root, seen) 94 return result98 """Maps device names to drive letters.""" 99 100 name = "drive_letter_device_map" 101 102 @core.MethodWithAddressSpace()124104 try: 105 result = {} 106 obj_tree_plugin = self.session.plugins.object_tree() 107 # The global path contains symlinks from the drive letter to the 108 # device name. 109 for global_obj in obj_tree_plugin.GetObjectByName( 110 r"\GLOBAL??").Object: 111 name = global_obj.NameInfo.Name.v() 112 if (global_obj.get_object_type() == "SymbolicLink" and 113 len(name) > 1 and name[1] == ":"): 114 target = global_obj.Object.LinkTarget.v() 115 116 result[target] = name 117 118 return result 119 120 # If we fail to traverse the object tree we just return None which will 121 # fail to resolve this drive letter but will try again next time. 122 except KeyError: 123 return None127 """Finds the kernel base address.""" 128 129 name = "kernel_base" 130165132 address_space = self.session.kernel_address_space 133 if not address_space: 134 return 135 136 scanner = ExportScanner(session=self.session, 137 address_space=address_space) 138 139 # The kernel image is always loaded in the same range called the 140 # "Initial Loader Mappings". Narrowing the possible range makes scanning 141 # much faster. (See http://www.codemachine.com/article_x64kvas.html) 142 if self.session.profile.metadata("arch") == "AMD64": 143 kernel_boundary = 0xFFFFF80000000000 144 else: 145 kernel_boundary = 0x80000000 146 147 maxlen = 0xFFFFF87FFFFFFFFF - kernel_boundary 148 kernel_boundary = obj.Pointer.integer_to_address(kernel_boundary) 149 for hit in scanner.scan(offset=kernel_boundary, maxlen=maxlen): 150 151 # Search backwards for an MZ signature on the page boundary. 152 page = hit & 0xFFFFFFFFFFFFF000 153 for _ in range(10): 154 if address_space.read(page, 2) == "MZ": 155 helper = pe_vtypes.PE( 156 address_space=address_space, 157 session=self.session, image_base=page) 158 159 if str(helper.RSDS.Filename) in common.KERNEL_NAMES: 160 self.session.logging.info( 161 "Detected kernel base at 0x%X", page) 162 return page 163 else: 164 page -= 0x1000168 """The highest address for user mode/kernel mode division.""" 169 170 name = "highest_usermode_address" 171185 198173 result = self.session.profile.get_constant_object( 174 "MmHighestUserAddress", "Pointer").v() 175 176 # Sometimes the pointer is not present, in that case we use hardcoded 177 # values. I dont think these values will ever change, maybe we should 178 # just hard code them anyway. 179 if result == 0: 180 if self.profile.metadata("arch") == "AMD64": 181 result = 0x7fffffeffff 182 result = 0x7ffeffff 183 184 return result
Trees | Indices | Help |
|
---|
Generated by Epydoc 3.0.1 on Mon Oct 9 03:29:36 2017 | http://epydoc.sourceforge.net |