1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 """Miscelaneous information gathering plugins."""
19
20 __author__ = "Michael Cohen <scudette@google.com>"
21 import hashlib
22 import re
23
24 from rekall import obj
25 from rekall.plugins import core
26 from rekall.plugins.darwin import common
27 from rekall.plugins.renderers import visual_aides
28
29
31 """Print the kernel debug messages."""
32
33 __name = "dmesg"
34
58
59
61 """Show information about this machine."""
62
63 __name = "machine_info"
64
74
75
77 """Show mount points."""
78
79 __name = "mount"
80
82 renderer.table_header([
83 ("Device", "device", "30"),
84 ("Mount Point", "mount_point", "60"),
85 ("Type", "type", "")])
86
87 mount_list = self.profile.get_constant_object(
88 "_mountlist", "mount")
89
90 for mount in mount_list.walk_list("mnt_list.tqe_next", False):
91 renderer.table_row(mount.mnt_vfsstat.f_mntonname,
92 mount.mnt_vfsstat.f_mntfromname,
93 mount.mnt_vfsstat.f_fstypename)
94
95
97 """Prints the EFI boot physical memory map."""
98
99 __name = "phys_map"
100
102 renderer.table_header([
103 ("Physical Start", "phys", "[addrpad]"),
104 ("Physical End", "phys", "[addrpad]"),
105 ("Virtual", "virt", "[addrpad]"),
106 ("Pages", "pages", ">10"),
107 ("Type", "type", "")])
108
109 boot_params = self.profile.get_constant_object(
110 "_PE_state", "PE_state").bootArgs
111
112
113
114 memory_map = self.profile.Array(
115 boot_params.MemoryMap,
116 vm=self.physical_address_space,
117 target="EfiMemoryRange",
118 target_size=int(boot_params.MemoryMapDescriptorSize),
119 count=(boot_params.MemoryMapSize /
120 boot_params.MemoryMapDescriptorSize))
121
122 runs = []
123 for memory_range in memory_map:
124 start = memory_range.PhysicalStart
125 end = (memory_range.PhysicalStart
126 + 0x1000
127 * memory_range.NumberOfPages)
128 runs.append(dict(
129 value=unicode(memory_range.Type), start=start, end=end))
130 renderer.table_row(
131 start,
132 end,
133 memory_range.VirtualStart.cast("Pointer"),
134 memory_range.NumberOfPages,
135 memory_range.Type)
136
137
138
139
140 resolution = 0x1000 * 0x10
141 column_count = 12
142 end = runs[-1]["end"]
143
144 while end / resolution / column_count > 200:
145 resolution *= 2
146
147 notes = ("Resolution: %(pages)d pages (%(mb).2f MB) per cell.\n"
148 "Note that colors of overlapping regions are blended "
149 "using a weighted average. Letters in cells indicate "
150 "which regions from the legend are present. They are "
151 "ordered proportionally, by their respective page "
152 "counts in each cell.") % dict(pages=resolution / 0x1000,
153 mb=resolution / 1024.0 ** 2)
154
155 legend = visual_aides.MapLegend(
156 notes=notes,
157 legend=[("Am", "kEfiACPIMemoryNVS", (0x00, 0xff, 0x00)),
158 ("Ar", "kEfiACPIReclaimMemory", (0xc7, 0xff, 0x50)),
159 ("Bc", "kEfiBootServicesCode", (0xff, 0xa5, 0x00)),
160 ("Bd", "kEfiBootServicesData", (0xff, 0x00, 0x00)),
161 ("M", "kEfiConventionalMemory", (0xff, 0xff, 0xff)),
162 ("Ec", "kEfiLoaderCode", (0x00, 0xff, 0xff)),
163 ("Ed", "kEfiLoaderData", (0x00, 0x00, 0xff)),
164 ("I", "kEfiMemoryMappedIO", (0xff, 0xff, 0x00)),
165 ("X", "kEfiReservedMemoryType", (0x00, 0x00, 0x00)),
166 ("Rc", "kEfiRuntimeServicesCode", (0xff, 0x00, 0xff)),
167 ("Rd", "kEfiRuntimeServicesData", (0xff, 0x00, 0x50))])
168
169 heatmap = visual_aides.RunBasedMap(
170 caption="Offset (p)",
171 legend=legend,
172 runs=runs,
173 resolution=resolution,
174 column_count=column_count)
175
176 renderer.table_header([
177 dict(name="Visual mapping", width=120, style="full"),
178 dict(name="Legend", orientation="vertical", style="full",
179 width=40)])
180
181 renderer.table_row(heatmap, legend)
182
183
185 """Prints the kernel command line."""
186
187 name = "boot_cmdline"
188
189 table_header = [
190 dict(name="cmdline", type="str"),
191 ]
192
198
199
200 -class DarwinSetProcessContext(core.SetProcessContextMixin,
201 common.ProcessFilterMixin,
202 common.AbstractDarwinCommand):
203 """A cc plugin for windows."""
204
205
206 -class DarwinVtoP(core.VtoPMixin, common.ProcessFilterMixin,
207 common.AbstractDarwinCommand):
208 """Describe virtual to physical translation on darwin platforms."""
209
210
212 """Fingerprint the current image.
213
214 This parameter tries to get something unique about the image quickly. The
215 idea is that two different images (even of the same system at different
216 points in time) will have very different fingerprints. The fingerprint is
217 used as a key to cache persistent information about the system.
218
219 Live systems can not have a stable fingerprint and so return a NoneObject()
220 here.
221
222 We return a list of tuples:
223 (physical_offset, expected_data)
224
225 The list uniquely identifies the image. If one were to read all physical
226 offsets and find the expected_data at these locations, then we have a very
227 high level of confidence that the image is unique and matches the
228 fingerprint.
229 """
230 name = "image_fingerprint"
231
233 if self.session.physical_address_space.volatile:
234 return obj.NoneObject("No fingerprint for volatile image.")
235
236 result = []
237 profile = self.session.profile
238 phys_as = self.session.physical_address_space
239
240 address_space = self.session.GetParameter("default_address_space")
241
242 label = profile.get_constant_object("_osversion", "String")
243 result.append((address_space.vtop(label.obj_offset), label.v()))
244
245 label = profile.get_constant_object("_version", "String")
246 result.append((address_space.vtop(label.obj_offset), label.v()))
247
248 label = profile.get_constant_object("_sched_tick", "String",
249 length=8, term=None)
250 result.append((address_space.vtop(label.obj_offset), label.v()))
251
252 catfish_offset = self.session.GetParameter("catfish_offset")
253 result.append((catfish_offset, phys_as.read(catfish_offset, 8)))
254
255
256 for task in self.session.plugins.pslist().filter_processes():
257 name = task.name.cast("String", length=30)
258 task_name_offset = address_space.vtop(name.obj_offset)
259
260 result.append((task_name_offset, name.v()))
261
262 return dict(
263 hash=hashlib.sha1(unicode(result).encode("utf8")).hexdigest(),
264 tests=result)
265
266
268 """The highest address for user mode/kernel mode division."""
269
270 name = "highest_usermode_address"
271
273 return 0x800000000000
274