1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 __author__ = "Andreas Moser <grrrrrrrrr@surfsup.at>"
20
21
22 import re
23
24 from rekall import plugin
25 from rekall import scan
26 from rekall import testlib
30 """A scanner that searches for a signature.
31
32 The signature is given as a list of strings and this scanner checks that
33 each part of the signature is present in memory in ascending order.
34 """
35
36 - def __init__(self, needles=None, **kwargs):
37 """Init.
38
39 Args:
40 needles: A list of strings we search for.
41 **kwargs: passthrough.
42 Raises:
43 RuntimeError: No needles provided.
44 """
45 super(SignatureScannerCheck, self).__init__(**kwargs)
46
47
48 if not needles:
49 raise RuntimeError("No needles provided to search.")
50
51 self.needles = needles
52 self.current_needle = 0
53
54 - def check(self, buffer_as, offset):
55 if self.current_needle >= len(self.needles):
56
57 return False
58
59
60 buffer_offset = buffer_as.get_buffer_offset(offset)
61 next_part = self.needles[self.current_needle]
62 if buffer_as.data.startswith(next_part, buffer_offset):
63 self.current_needle += 1
64 return next_part
65 else:
66 return False
67
68 - def skip(self, buffer_as, offset):
69 if self.current_needle >= len(self.needles):
70
71 return buffer_as.end() - offset
72
73
74 buffer_offset = buffer_as.get_buffer_offset(offset)
75 next_part = self.needles[self.current_needle]
76 correction = 0
77 if self.current_needle:
78
79
80 correction = len(self.needles[self.current_needle - 1])
81 dindex = buffer_as.data.find(next_part, buffer_offset + correction)
82 if dindex > -1:
83 return dindex - buffer_offset
84
85
86 return buffer_as.end() - offset
87
90
91 - def __init__(self, needles=None, **kwargs):
98
104
105 - def skip(self, buffer_as, offset):
107
108 - def scan(self, **kwargs):
115
118 """Scan memory for signatures."""
119
120 name = "sigscan"
121
122 @classmethod
123 - def args(cls, parser):
124 super(SigScanMixIn, cls).args(parser)
125 parser.add_argument("signature", default=None, nargs="*",
126 help="The signature(s) to scan for. Format is "
127 "000102*0506*AAFF")
128
129 parser.add_argument(
130 "--scan_physical", default=False, type="Boolean",
131 help="If specified we scan the physcial address space.")
132
133 parser.add_argument(
134 "--scan_kernel", default=False, type="Boolean",
135 help="If specified we scan the kernel address space.")
136
137 - def __init__(self, signature=None, scan_kernel=False, scan_physical=False,
138 **kwargs):
139 """Scan using custom signatures."""
140 super(SigScanMixIn, self).__init__(**kwargs)
141
142 if not self.filtering_requested and not scan_kernel:
143 scan_physical = True
144
145 if not signature:
146 raise plugin.PluginError("No signature given.")
147 sig_re = re.compile("^[0-9A-F*]*$")
148
149 if isinstance(signature, basestring):
150 signature = [signature]
151
152 self.signatures = []
153 for sig in signature:
154 sig = sig.upper()
155 if not sig_re.match(sig):
156 raise plugin.PluginError(
157 "Signature %s has invalid format. Format is eg. "
158 "000102*0506*AAFF" % sig)
159 parts = sig.split("*")
160 decoded_parts = []
161 for p in parts:
162 try:
163 decoded_parts.append(p.decode("hex"))
164 except TypeError:
165 raise plugin.PluginError(
166 "Signature %s has invalid format." % sig)
167 self.signatures.append(decoded_parts)
168 self.scan_physical = scan_physical
169 self.scan_kernel = scan_kernel
170
181
191
192 - def _scan(self, renderer, hit_msg, address_space, end=2**64):
201
208
210 """This method scans the kernel memory."""
211 self.session.logging.debug("sigscanning against the kernel.")
212 return self._scan(renderer, "Hit in kernel AS:\n",
213 self.kernel_address_space)
214
222
225 """Runs sigscan against physical memory."""
226
227 PARAMETERS = dict(
228 commandline="sigscan --signature %(signature)s --scan_physical",
229 signature="")
230
233 """Runs sigscan against the kernel."""
234
235 PARAMETERS = dict(
236 commandline="sigscan --signature %(signature)s --scan_kernel",
237 signature="")
238
241 """Runs sigscan against processes."""
242
243 PARAMETERS = dict(
244 commandline=("sigscan --signature %(signature)s "
245 "--proc_regex %(proc_regex)s"),
246 signature="",
247 proc_regex=".")
248