1 import logging
2 import unittest
3 import pyparsing
4
5 from rekall import testlib
6 from rekall.plugins.tools import yara_support
7
8
10 rules = [
11 "rule test { condition: true }",
12 "rule test { condition: true or false }",
13 "rule test { condition: true and true }",
14 "rule test { condition: 0x1 and 0x2}",
15 "rule test { condition: false }",
16 "rule test { condition: true and false }",
17 "rule test { condition: false or false }",
18 "rule test { condition: 2 > 1 }",
19 "rule test { condition: 1 < 2 }",
20 "rule test { condition: 2 >= 1 }",
21 "rule test { condition: 1 <= 1 }",
22 "rule test { condition: 1 == 1 }",
23 "rule test { condition: 1.5 == 1.5}",
24 "rule test { condition: 1.0 == 1}",
25 "rule test { condition: 1.5 >= 1.0}",
26 "rule test { condition: 1.5 >= 1}",
27 "rule test { condition: 1.0 >= 1}",
28 "rule test { condition: 0.5 < 1}",
29 "rule test { condition: 0.5 <= 1}",
30 "rule rest { condition: 1.0 <= 1}",
31 "rule rest { condition: \"abc\" == \"abc\"}",
32 "rule rest { condition: \"abc\" <= \"abc\"}",
33 "rule rest { condition: \"abc\" >= \"abc\"}",
34 "rule rest { condition: \"ab\" < \"abc\"}",
35 "rule rest { condition: \"abc\" > \"ab\"}",
36 "rule rest { condition: \"abc\" < \"abd\"}",
37 "rule rest { condition: \"abd\" > \"abc\"}",
38 "rule test { condition: 1 != 1}",
39 "rule test { condition: 1 != 1.0}",
40 "rule test { condition: 2 > 3}",
41 "rule test { condition: 2.1 < 2}",
42 "rule test { condition: \"abc\" != \"abc\"}",
43 "rule test { condition: \"abc\" > \"abc\"}",
44 "rule test { condition: \"abc\" < \"abc\"}",
45 "rule test { condition: (1 + 1) * 2 == (9 - 1) \\ 2 }",
46 "rule test { condition: 5 % 2 == 1 }",
47 "rule test { condition: 1.5 + 1.5 == 3}",
48 "rule test { condition: 3 \\ 2 == 1}",
49 "rule test { condition: 3.0 \\ 2 == 1.5}",
50 "rule test { condition: 1 + -1 == 0}",
51 "rule test { condition: -1 + -1 == -2}",
52 "rule test { condition: 4 --2 * 2 == 8}",
53 "rule test { condition: -1.0 * 1 == -1.0}",
54 "rule test { condition: 1-1 == 0}",
55 "rule test { condition: -2.0-3.0 == -5}",
56 "rule test { condition: --1 == 1}",
57 "rule test { condition: 1--1 == 2}",
58 "rule test { condition: -0x01 == -1}",
59 "rule test { condition: 0x55 | 0xAA == 0xFF }",
60 "rule test { condition: ~0xAA ^ 0x5A & 0xFF == "
61 "(~0xAA) ^ (0x5A & 0xFF) }",
62 "rule test { condition: ~0x55 & 0xFF == 0xAA }",
63 "rule test { condition: 8 >> 2 == 2 }",
64 "rule test { condition: 1 << 3 == 8 }",
65 "rule test { condition: 1 | 3 ^ 3 == 1 | (3 ^ 3) }",
66 "rule test { condition: ~0xAA ^ 0x5A & 0xFF == 0x0F }",
67 "rule test { condition: 1 | 3 ^ 3 == (1 | 3) ^ 3}",
68 "rule test { strings: $a = \"a\" $a = \"a\" condition: all of them }",
69 "rule test { strings: $ = \"a\" $ = \"b\" condition: all of them }",
70 "rule test { strings: $a = \"a\" condition: $a }",
71 "rule test { strings: $a = \"ab\" condition: $a }",
72 "rule test { strings: $a = \"abc\" condition: $a }",
73 "rule test { strings: $a = \"xyz\" condition: $a }",
74 "rule test { strings: $a = \"abc\" nocase fullword condition: $a }",
75 "rule test { strings: $a = \"aBc\" nocase condition: $a }",
76 "rule test { strings: $a = \"abc\" fullword condition: $a }",
77 "rule test { strings: $a = \"a\" fullword condition: $a }",
78 "rule test { strings: $a = \"ab\" fullword condition: $a }",
79 "rule test { strings: $a = \"abc\" wide fullword condition: $a }",
80 "rule test { strings: $a = \"a\" wide condition: $a }",
81 "rule test { strings: $a = \"a\" wide ascii condition: $a }",
82 "rule test { strings: $a = \"ab\" wide condition: $a }",
83 "rule test { strings: $a = \"ab\" wide ascii condition: $a }",
84 "rule test { strings: $a = \"abc\" wide condition: $a }",
85 "rule test { strings: $a = \"abc\" wide nocase fullword "
86 "condition: $a }",
87 "rule test { strings: $a = \"aBc\" wide nocase condition: $a }",
88 "rule test { strings: $a = \"aBc\" wide ascii nocase condition: $a }",
89 "rule test { strings: $a = \"---xyz\" wide nocase condition: $a }",
90 "rule test { strings: $a = \"abc\" fullword condition: $a }",
91 "rule test { strings: $a = \"abc\" fullword condition: $a }",
92 "rule test { strings: $a = \"abc\" fullword condition: $a }",
93 "rule test { strings: $a = \"abc\" fullword condition: $a }",
94 "rule test { strings: $a = \"abc\" ascii wide fullword condition: $a }",
95 "rule test { strings: $a = \"abc\" ascii wide fullword condition: $a }",
96 "rule test { strings: $a = \"abc\" wide fullword condition: $a }",
97 "rule test { strings: $a = \"abc\" wide fullword condition: $a }",
98 "rule test { strings: $a = \"ab\" wide fullword condition: $a }",
99 "rule test { strings: $a = \"abc\" wide fullword condition: $a }",
100 "rule test { strings: $a = \"abc\" wide fullword condition: $a }",
101 "rule test {\n\
102 strings:\n\
103 $a = \"abcdef\"\n\
104 $b = \"cdef\"\n\
105 $c = \"ef\"\n\
106 condition:\n\
107 all of them\n\
108 }",
109 "rule test {\n\
110 strings:\n\
111 $s1 = \"abc\"\n\
112 $s2 = \"xyz\"\n\
113 condition:\n\
114 for all of ($*) : ($)\n\
115 }",
116 "rule test { \
117 strings: $a = { 64 01 00 00 60 01 } \
118 condition: $a }",
119 "rule test { \
120 strings: $a = { 64 0? 00 00 ?0 01 } \
121 condition: $a }",
122 "rule test { \
123 strings: $a = { 6? 01 00 00 60 0? } \
124 condition: $a }",
125 "rule test { \
126 strings: $a = { 64 01 [1-3] 60 01 } \
127 condition: $a }",
128 "rule test { \
129 strings: $a = { 64 01 [1-3] (60|61) 01 } \
130 condition: $a }",
131 "rule test { \
132 strings: $a = { 4D 5A [-] 6A 2A [-] 58 C3} \
133 condition: $a }",
134 "rule test { \
135 strings: $a = { 4D 5A [300-] 6A 2A [-] 58 C3} \
136 condition: $a }",
137 "rule test { \
138 strings: $a = { 2e 7? (65 | ?""?"") 78 } \
139 condition: $a }",
140 "rule test { \
141 strings: $a = { 4D 5A [0-300] 6A 2A } \
142 condition: $a }",
143 "rule test { \
144 strings: $a = { 4D 5A [0-128] 45 [0-128] 01 [0-128] C3 } \
145 condition: $a }",
146 "rule test { \
147 strings: $a = { 31 32 [-] 38 39 } \
148 condition: $a }",
149 "rule test { \
150 strings: $a = { 31 32 [-] // Inline comment\n\
151 38 39 } \
152 condition: $a }",
153 "rule test { \
154 strings: $a = { 31 32 /* Inline comment */ [-] 38 39 } \
155 condition: $a }",
156 "rule test { \
157 strings: $a = { 31 32 /* Inline multi-line\n\
158 comment */ [-] 38 39 } \
159 condition: $a }",
160 "rule test { \
161 strings: $a = { 31 32 [-] 33 34 [-] 38 39 } \
162 condition: $a }",
163 "rule test { \
164 strings: $a = { 31 32 [1] 34 35 [2] 38 39 } \
165 condition: $a }",
166 "rule test {\
167 strings: $a = { 31 32 [1-] 34 35 [1-] 38 39 } \
168 condition: $a }",
169 "rule test { \
170 strings: $a = { 31 32 [0-3] 34 35 [1-] 38 39 } \
171 condition: $a }",
172 "rule test { \
173 strings: $a = { 31 32 [0-2] 35 [1-] 37 38 39 } \
174 condition: $a }",
175 "rule test { \
176 strings: $a = { 31 32 [-] 38 39 } \
177 condition: all of them }",
178 "rule test { \
179 strings: $a = { 31 32 [-] 32 33 } \
180 condition: $a }",
181 "rule test { \
182 strings: $a = { 35 36 [-] 31 32 } \
183 condition: $a }",
184 "rule test { \
185 strings: $a = { 31 32 [2-] 34 35 } \
186 condition: $a }",
187 "rule test { \
188 strings: $a = { 31 32 [0-3] 37 38 } \
189 condition: $a }",
190 "rule test { \
191 strings: $a = { 01 [0] 02 } \
192 condition: $a }",
193 "rule test { \
194 strings: $a = { [-] 01 02 } condition: $a }",
195 "rule test { \
196 strings: $a = { 01 02 [-] } \
197 condition: $a }",
198
199 "rule test { \
200 strings: $a = { 01 02 ([-] 03 | 04) } \
201 condition: $a }",
202
203 "rule test { \
204 strings: $a = { 01 02 (03 [-] | 04) } \
205 condition: $a }",
206
207 "rule test { \
208 strings: $a = { 01 02 (03 | 04 [-]) } \
209 condition: $a }",
210
211 "rule test { strings: $a = \"ssi\" condition: #a == 2 }",
212
213 "rule test { \
214 strings: $a = \"ssi\" \
215 condition: $a at 2 and $a at 5 }",
216
217 "rule test { \
218 strings: $a = \"mis\" \
219 condition: $a at ~0xFF & 0xFF }",
220 "rule test { \
221 strings: $a = { 00 00 00 00 ?? 74 65 78 74 } \
222 condition: $a at 308}",
223 "rule test { strings: $a = \"ssi\" condition: @a == 2 }",
224 "rule test { strings: $a = \"ssi\" condition: @a == @a[1] }",
225 "rule test { strings: $a = \"ssi\" condition: @a[2] == 5 }",
226 "rule test { strings: $a = /m.*?ssi/ condition: !a == 5 }",
227 "rule test { strings: $a = /m.*?ssi/ condition: !a[1] == 5 }",
228 "rule test { strings: $a = /m.*ssi/ condition: !a == 8 }",
229 "rule test { strings: $a = /m.*ssi/ condition: !a[1] == 8 }",
230 "rule test { strings: $a = /ssi.*ppi/ condition: !a[1] == 9 }",
231 "rule test { strings: $a = /ssi.*ppi/ condition: !a[2] == 6 }",
232 "rule test { strings: $a = { 6D [1-3] 73 73 69 } condition: !a == 5}",
233 "rule test { strings: $a = { 6D [-] 73 73 69 } condition: !a == 5}",
234 "rule test { strings: $a = { 6D [-] 70 70 69 } condition: !a == 11}",
235 "rule test { strings: $a = { 6D 69 73 73 [-] 70 69 } "
236 "condition: !a == 11}",
237 "rule test { strings: $a = \"ssi\" $b = \"mis\" $c = \"oops\" "
238 "condition: any of them }",
239 "rule test { strings: $a = \"ssi\" $b = \"mis\" $c = \"oops\" "
240 "condition: 1 of them }",
241 "rule test { strings: $a = \"ssi\" $b = \"mis\" $c = \"oops\" "
242 "condition: 2 of them }",
243 "rule test { strings: $a1 = \"dummy1\" $b1 = \"dummy1\" $b2 = \"ssi\""
244 "condition: any of ($a*, $b*) }",
245 "rule test { \
246 strings: \
247 $ = /abc/ \
248 $ = /def/ \
249 $ = /ghi/ \
250 condition: \
251 for any of ($*) : ( for any i in (1..#): (uint8(@[i] - 1) == 0x00) )\
252 }",
253 "rule test { \
254 strings: \
255 $a = \"ssi\" \
256 $b = \"mis\" \
257 $c = \"oops\" \
258 condition: \
259 all of them \
260 }",
261 "rule test { condition: all of ($a*) }",
262
263 "rule test { condition: all of them }",
264 "rule test { \
265 strings: \
266 $a = \"ssi\" \
267 condition: \
268 for all i in (1..#a) : (@a[i] >= 2 and @a[i] <= 5) \
269 }",
270 "rule test { \
271 strings: \
272 $a = \"ssi\" \
273 $b = \"mi\" \
274 condition: \
275 for all i in (1..#a) : ( for all j in (1..#b) : (@a[i] >= @b[j])) \
276 }",
277 "rule test { \
278 strings: \
279 $a = \"ssi\" \
280 condition: \
281 for all i in (1..#a) : (@a[i] == 5) \
282 }",
283 "rule test { strings: $a = /ssi/ condition: $a }",
284 "rule test { strings: $a = /ssi(s|p)/ condition: $a }",
285 "rule test { strings: $a = /ssim*/ condition: $a }",
286 "rule test { strings: $a = /ssa?/ condition: $a }",
287 "rule test { strings: $a = /Miss/ nocase condition: $a }",
288 "rule test { strings: $a = /(M|N)iss/ nocase condition: $a }",
289 "rule test { strings: $a = /[M-N]iss/ nocase condition: $a }",
290 "rule test { strings: $a = /(Mi|ssi)ssippi/ nocase condition: $a }",
291 "rule test { strings: $a = /ppi\\tmi/ condition: $a }",
292 "rule test { strings: $a = /ppi\\.mi/ condition: $a }",
293 "rule test { strings: $a = /^mississippi/ fullword condition: $a }",
294 "rule test { strings: $a = /mississippi.*mississippi$/s "
295 "condition: $a }",
296 "rule test { strings: $a = /^ssi/ condition: $a }",
297 "rule test { strings: $a = /ssi$/ condition: $a }",
298 "rule test { strings: $a = /ssissi/ fullword condition: $a }",
299 "rule test { strings: $a = /^[isp]+/ condition: $a }",
300 "rule test { \
301 strings: $a = { 6a 2a 58 c3 } \
302 condition: $a at entrypoint }",
303 "rule test { \
304 strings: $a = { b8 01 00 00 00 bb 2a } \
305 condition: $a at entrypoint }",
306
307 "rule test { \
308 strings: $a = { b8 01 00 00 00 bb 2a } \
309 condition: $a at entrypoint }",
310 "rule test { condition: entrypoint >= 0 }",
311 ]
312
314 """Approximate match removing whitespace."""
315 rule = pyparsing.cppStyleComment.suppress().transformString(rule)
316 return rule.replace("\n", "").replace(" ", "")
317
328
329
330 if __name__ == "__main__":
331 logging.basicConfig(level=logging.DEBUG)
332 unittest.main()
333