1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 """This module implements profile indexing.
20
21 Rekall relies on accurate profiles for reliable analysis of memory artifacts. We
22 depend on selecting the correct profile from the profile repository, but
23 sometimes its hard to determine the exact profile to use. For windows, the
24 profile must match exactly the GUID in the driver.
25
26 However, sometimes, the GUID is unavailable or it could be manipulated. In that
27 case we would like to determine the profile version by applying the index.
28
29 The profile repository has an index for each kernel module stored. We can use
30 this index to determine the exact version of the profile very quickly - even if
31 the RSDS GUID is not available or incorrect.
32 """
33
34 __author__ = "Michael Cohen <scudette@google.com>"
35
36 from rekall import obj
37 from rekall import testlib
38 from rekall.plugins.windows import common
39 from rekall.plugins.overlays import basic
40
41
42 -class GuessGUID(common.WindowsCommandPlugin):
43 """Try to guess the exact version of a kernel module by using an index."""
44
45 name = "guess_guid"
46
47 __args = [
48 dict(name="module", positional=True,
49 help="The name of the module to guess."),
50
51 dict(name="minimal_match", default=1, type="IntParser",
52 help="The minimal number of comparison points to be considered. "
53 "Sometimes not all comparison points can be used since they may "
54 "not be mapped."),
55 ]
56
57 table_header = [
58 dict(name="pid", width=20),
59 dict(name="session", width=20),
60 dict(name="profile"),
61 ]
62
64 """Scan for module using version_scan for RSDS scanning."""
65 module_name = self.plugin_args.module.split(".")[0]
66 for _, guid in self.session.plugins.version_scan(
67 name_regex="^%s.pdb" % module_name).ScanVersions():
68 yield obj.NoneObject(), "%s/GUID/%s" % (module_name, guid)
69
92
94 """Search for suitable profiles using a variety of methods."""
95
96
97
98 for x in self.LookupIndex():
99 yield x
100
101
102
103 for x in self.ScanProfile():
104 yield x
105
107 for context, possibility in self.GuessProfiles():
108 yield (context.pid, context.SessionId, possibility)
109
112 """A profile index for _EPROCESS structs."""
113
114 @classmethod
123
125 self.index = index
126
127
128
129 self.filename_to_dtb = set()
130 for metadata in index.values():
131 offsets = metadata["offsets"]
132 relative_offset = offsets["_EPROCESS.ImageFileName"] - (
133 offsets["_EPROCESS.Pcb"] +
134 offsets["_KPROCESS.DirectoryTableBase"])
135
136 arch = metadata.get("arch", "AMD64")
137 self.filename_to_dtb.add((relative_offset, arch))
138
144