yarax-python-dex 1.20.0__cp38-abi3-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of yarax-python-dex might be problematic. Click here for more details.
- yara_x/__init__.py +5 -0
- yara_x/__init__.pyi +640 -0
- yara_x/py.typed +0 -0
- yara_x/yara_x.pyd +0 -0
- yarax_python_dex-1.20.0.dist-info/METADATA +46 -0
- yarax_python_dex-1.20.0.dist-info/RECORD +8 -0
- yarax_python_dex-1.20.0.dist-info/WHEEL +4 -0
- yarax_python_dex-1.20.0.dist-info/sboms/yara-x-py.cyclonedx.json +11374 -0
yara_x/__init__.py
ADDED
yara_x/__init__.pyi
ADDED
|
@@ -0,0 +1,640 @@
|
|
|
1
|
+
import collections
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict, BinaryIO, TextIO, Optional, Tuple, final, List
|
|
4
|
+
from enum import Enum
|
|
5
|
+
|
|
6
|
+
class CompileError(Exception):
|
|
7
|
+
r"""
|
|
8
|
+
Error occurred while compiling rules.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
class ScanError(Exception):
|
|
12
|
+
r"""
|
|
13
|
+
Error occurred during a scan operation.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
class TimeoutError(Exception):
|
|
17
|
+
r"""
|
|
18
|
+
Error indicating that a timeout occurred during a scan operation.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
@final
|
|
22
|
+
class Compiler:
|
|
23
|
+
r"""
|
|
24
|
+
Compiles YARA source code producing a set of compiled [`Rules`].
|
|
25
|
+
"""
|
|
26
|
+
def __new__(
|
|
27
|
+
cls,
|
|
28
|
+
relaxed_re_syntax: bool = False,
|
|
29
|
+
error_on_slow_pattern: bool = False,
|
|
30
|
+
includes_enabled: bool = True,
|
|
31
|
+
) -> Compiler:
|
|
32
|
+
r"""
|
|
33
|
+
Creates a new [`Compiler`].
|
|
34
|
+
|
|
35
|
+
The `relaxed_re_syntax` argument controls whether the compiler should
|
|
36
|
+
adopt a more relaxed syntax check for regular expressions, allowing
|
|
37
|
+
constructs that YARA-X doesn't accept by default.
|
|
38
|
+
|
|
39
|
+
YARA-X enforces stricter regular expression syntax compared to YARA.
|
|
40
|
+
For instance, YARA accepts invalid escape sequences and treats them
|
|
41
|
+
as literal characters (e.g., \R is interpreted as a literal 'R'). It
|
|
42
|
+
also allows some special characters to appear unescaped, inferring
|
|
43
|
+
their meaning from the context (e.g., `{` and `}` in `/foo{}bar/` are
|
|
44
|
+
literal, but in `/foo{0,1}bar/` they form the repetition operator
|
|
45
|
+
`{0,1}`).
|
|
46
|
+
|
|
47
|
+
The `error_on_slow_pattern` argument tells the compiler to treat slow
|
|
48
|
+
patterns as errors, instead of warnings.
|
|
49
|
+
|
|
50
|
+
The `includes_enabled` argument controls whether the compiler should
|
|
51
|
+
enable or disable the inclusion of files with the `include` directive.
|
|
52
|
+
"""
|
|
53
|
+
...
|
|
54
|
+
|
|
55
|
+
def add_source(self, src: str, origin: Optional[str] = None) -> None:
|
|
56
|
+
r"""
|
|
57
|
+
Adds a YARA source code to be compiled.
|
|
58
|
+
|
|
59
|
+
This function may be invoked multiple times to add several sets of YARA
|
|
60
|
+
rules before calling [`Compiler::build`]. If the rules provided in
|
|
61
|
+
`src` contain errors that prevent compilation, the function will raise
|
|
62
|
+
an exception with the first error encountered. Additionally, the
|
|
63
|
+
compiler will store this error, along with any others discovered during
|
|
64
|
+
compilation, which can be accessed using [`Compiler::errors`].
|
|
65
|
+
|
|
66
|
+
Even if a previous invocation resulted in a compilation error, you can
|
|
67
|
+
continue calling this function. In such cases, any rules that failed to
|
|
68
|
+
compile will not be included in the final compiled set.
|
|
69
|
+
|
|
70
|
+
The optional parameter `origin` allows to specify the origin of the
|
|
71
|
+
source code. This usually receives the path of the file from where the
|
|
72
|
+
code was read, but it can be any arbitrary string that conveys information
|
|
73
|
+
about the source code's origin.
|
|
74
|
+
"""
|
|
75
|
+
...
|
|
76
|
+
|
|
77
|
+
def add_include_dir(self, dir: str) -> None:
|
|
78
|
+
r"""
|
|
79
|
+
Adds a directory to the list of directories where the compiler should
|
|
80
|
+
look for included files.
|
|
81
|
+
"""
|
|
82
|
+
...
|
|
83
|
+
|
|
84
|
+
def enable_includes(self, yes: bool) -> None:
|
|
85
|
+
r"""
|
|
86
|
+
Enables or disables the inclusion of files with the `include` directive.
|
|
87
|
+
"""
|
|
88
|
+
...
|
|
89
|
+
|
|
90
|
+
def max_warnings(self, n: int) -> None:
|
|
91
|
+
r"""
|
|
92
|
+
Sets the maximum number of warnings.
|
|
93
|
+
"""
|
|
94
|
+
...
|
|
95
|
+
|
|
96
|
+
def define_global(self, ident: str, value: Any) -> None:
|
|
97
|
+
r"""
|
|
98
|
+
Defines a global variable and sets its initial value.
|
|
99
|
+
|
|
100
|
+
Global variables must be defined before calling [`Compiler::add_source`]
|
|
101
|
+
with some YARA rule that uses the variable. The variable will retain its
|
|
102
|
+
initial value when the [`Rules`] are used for scanning data, however
|
|
103
|
+
each scanner can change the variable's value by calling
|
|
104
|
+
[`crate::Scanner::set_global`].
|
|
105
|
+
|
|
106
|
+
The type of `value` must be: bool, str, bytes, int, float or dict. When
|
|
107
|
+
the value is a dict, keys must be of type string and valid YARA identifiers
|
|
108
|
+
(the first character must be `_` or a letter, and the remaining ones must
|
|
109
|
+
be a `_`, a letter or a digit).
|
|
110
|
+
|
|
111
|
+
# Raises
|
|
112
|
+
|
|
113
|
+
[TypeError](https://docs.python.org/3/library/exceptions.html#TypeError)
|
|
114
|
+
if the type of `value` is not one of the supported ones.
|
|
115
|
+
"""
|
|
116
|
+
...
|
|
117
|
+
|
|
118
|
+
def new_namespace(self, namespace: str) -> None:
|
|
119
|
+
r"""
|
|
120
|
+
Creates a new namespace.
|
|
121
|
+
|
|
122
|
+
Further calls to [`Compiler::add_source`] will put the rules under the
|
|
123
|
+
newly created namespace.
|
|
124
|
+
"""
|
|
125
|
+
...
|
|
126
|
+
|
|
127
|
+
def ignore_module(self, module: str) -> None:
|
|
128
|
+
r"""
|
|
129
|
+
Tell the compiler that a YARA module is not supported.
|
|
130
|
+
|
|
131
|
+
Import statements for unsupported modules will be ignored without
|
|
132
|
+
errors, but a warning will be issued. Any rule that make use of an
|
|
133
|
+
ignored module will be ignored, while the rest of rules that
|
|
134
|
+
don't rely on that module will be correctly compiled.
|
|
135
|
+
"""
|
|
136
|
+
...
|
|
137
|
+
|
|
138
|
+
def ignore_invalid_rules(self, yes: bool) -> None:
|
|
139
|
+
r"""
|
|
140
|
+
Tell the compiler to ignore any rules that are invalid.
|
|
141
|
+
|
|
142
|
+
Any ignored rules and the reasons for them being ignored are available
|
|
143
|
+
in [`Compiler::ignored_rules`].
|
|
144
|
+
"""
|
|
145
|
+
...
|
|
146
|
+
|
|
147
|
+
def ignored_rules() -> List[IgnoredRule]:
|
|
148
|
+
r"""
|
|
149
|
+
Retrieve all ignored rules during compilation.
|
|
150
|
+
|
|
151
|
+
Returns a list of [`IgnoredRule`] objects.
|
|
152
|
+
"""
|
|
153
|
+
...
|
|
154
|
+
|
|
155
|
+
def build(self) -> Rules:
|
|
156
|
+
r"""
|
|
157
|
+
Builds the source code previously added to the compiler.
|
|
158
|
+
|
|
159
|
+
This function returns an instance of [`Rules`] containing all the rules
|
|
160
|
+
previously added with [`Compiler::add_source`] and sets the compiler
|
|
161
|
+
to its initial empty state.
|
|
162
|
+
"""
|
|
163
|
+
...
|
|
164
|
+
|
|
165
|
+
def errors(self) -> Any:
|
|
166
|
+
r"""
|
|
167
|
+
Retrieves all errors generated by the compiler.
|
|
168
|
+
|
|
169
|
+
This method returns every error encountered during the compilation,
|
|
170
|
+
across all invocations of [`Compiler::add_source`].
|
|
171
|
+
"""
|
|
172
|
+
...
|
|
173
|
+
|
|
174
|
+
def warnings(self) -> Any:
|
|
175
|
+
r"""
|
|
176
|
+
Retrieves all warnings generated by the compiler.
|
|
177
|
+
|
|
178
|
+
This method returns every warning encountered during the compilation,
|
|
179
|
+
across all invocations of [`Compiler::add_source`].
|
|
180
|
+
"""
|
|
181
|
+
...
|
|
182
|
+
|
|
183
|
+
def allowed_rule_name(self, regexp: str, error: bool = False) -> None:
|
|
184
|
+
r"""
|
|
185
|
+
Tell the compiler that any rule must match this regular expression or it
|
|
186
|
+
will result in a compiler warning.
|
|
187
|
+
|
|
188
|
+
# Raises
|
|
189
|
+
|
|
190
|
+
[ValueError](https://docs.python.org/3/library/exceptions.html#ValueError)
|
|
191
|
+
if the regular expression is invalid.
|
|
192
|
+
"""
|
|
193
|
+
...
|
|
194
|
+
|
|
195
|
+
def allowed_tags(self, tags: List[str], error: bool = False) -> None:
|
|
196
|
+
r"""List the allowed tags for rules."""
|
|
197
|
+
...
|
|
198
|
+
|
|
199
|
+
def allowed_tags_regex(self, regexp: str, error: bool = False) -> None:
|
|
200
|
+
r"""A regular expression that must match all tags on rules."""
|
|
201
|
+
...
|
|
202
|
+
|
|
203
|
+
def allowed_metadata(
|
|
204
|
+
self,
|
|
205
|
+
identifier: str,
|
|
206
|
+
value_type: MetaType,
|
|
207
|
+
required: bool,
|
|
208
|
+
regexp: Optional[str],
|
|
209
|
+
error: bool = False):
|
|
210
|
+
r"""Define expected type and value for metadata on rules."""
|
|
211
|
+
...
|
|
212
|
+
|
|
213
|
+
@final
|
|
214
|
+
class IgnoredRuleReason(Enum):
|
|
215
|
+
IgnoredModule: int
|
|
216
|
+
IgnoredRule: int
|
|
217
|
+
CompileError: int
|
|
218
|
+
|
|
219
|
+
@final
|
|
220
|
+
class IgnoredRule:
|
|
221
|
+
r"""
|
|
222
|
+
Names and reasons for any ignored rules during compilation.
|
|
223
|
+
|
|
224
|
+
See [`Compiler::ignore_invalid_rules] for details.
|
|
225
|
+
"""
|
|
226
|
+
def name() -> str:
|
|
227
|
+
r"""
|
|
228
|
+
Name of the ignored rule.
|
|
229
|
+
"""
|
|
230
|
+
...
|
|
231
|
+
|
|
232
|
+
def message() -> str:
|
|
233
|
+
r"""
|
|
234
|
+
Message for why the rule was ignored.
|
|
235
|
+
"""
|
|
236
|
+
...
|
|
237
|
+
|
|
238
|
+
def reason() -> IgnoredRuleReason:
|
|
239
|
+
r"""
|
|
240
|
+
Reason for why the rule was ignored.
|
|
241
|
+
"""
|
|
242
|
+
...
|
|
243
|
+
|
|
244
|
+
@final
|
|
245
|
+
class ScanOptions:
|
|
246
|
+
r"""
|
|
247
|
+
Optional information for the scan operation.
|
|
248
|
+
"""
|
|
249
|
+
|
|
250
|
+
def __new__(cls) -> ScanOptions:
|
|
251
|
+
r"""
|
|
252
|
+
Creates a new [`ScanOptions`].
|
|
253
|
+
"""
|
|
254
|
+
...
|
|
255
|
+
|
|
256
|
+
def set_module_metadata(self, module: str, metadata: bytes) -> None:
|
|
257
|
+
r"""
|
|
258
|
+
Sets the data associated with a YARA module.
|
|
259
|
+
"""
|
|
260
|
+
...
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
@final
|
|
264
|
+
class Scanner:
|
|
265
|
+
r"""
|
|
266
|
+
Scans data with already compiled YARA rules.
|
|
267
|
+
|
|
268
|
+
The scanner receives a set of compiled [`Rules`] and scans data with those
|
|
269
|
+
rules. The same scanner can be used for scanning multiple files or in-memory
|
|
270
|
+
data sequentially, but you need multiple scanners for scanning in parallel.
|
|
271
|
+
"""
|
|
272
|
+
|
|
273
|
+
def __new__(cls, rules: Rules) -> Scanner:
|
|
274
|
+
r"""
|
|
275
|
+
Creates a new [`Scanner`] with a given set of [`Rules`].
|
|
276
|
+
"""
|
|
277
|
+
...
|
|
278
|
+
|
|
279
|
+
def scan(self, data: bytes) -> ScanResults:
|
|
280
|
+
r"""
|
|
281
|
+
Scans in-memory data.
|
|
282
|
+
"""
|
|
283
|
+
...
|
|
284
|
+
|
|
285
|
+
def scan_file(self, path: str) -> ScanResults:
|
|
286
|
+
r"""
|
|
287
|
+
Scans a file
|
|
288
|
+
"""
|
|
289
|
+
...
|
|
290
|
+
|
|
291
|
+
def scan_with_options(self, data: bytes, options: ScanOptions) -> ScanResults:
|
|
292
|
+
r"""
|
|
293
|
+
Like `scan`, but with options.
|
|
294
|
+
"""
|
|
295
|
+
...
|
|
296
|
+
|
|
297
|
+
def scan_file_with_options(self, path: str, options: ScanOptions) -> ScanResults:
|
|
298
|
+
r"""
|
|
299
|
+
Like `scan_file`, but with options.
|
|
300
|
+
"""
|
|
301
|
+
...
|
|
302
|
+
|
|
303
|
+
def set_module_output(self, module: str, data: bytes) -> None:
|
|
304
|
+
r"""
|
|
305
|
+
Specifies the output data structure for a module, as raw data.
|
|
306
|
+
|
|
307
|
+
Each YARA module generates an output consisting of a data structure
|
|
308
|
+
that contains information about the scanned file. This data
|
|
309
|
+
structure is represented by a Protocol Buffer message. Typically,
|
|
310
|
+
you won't need to provide this data yourself, as the YARA module
|
|
311
|
+
automatically generates different outputs for each file it scans.
|
|
312
|
+
|
|
313
|
+
However, there are two scenarios in which you may want to provide
|
|
314
|
+
the output for a module yourself:
|
|
315
|
+
|
|
316
|
+
1) When the module does not produce any output on its own.
|
|
317
|
+
2) When you already know the output of the module for the upcoming
|
|
318
|
+
file to be scanned, and you prefer to reuse this data instead of
|
|
319
|
+
generating it again.
|
|
320
|
+
|
|
321
|
+
Case 1) applies to certain modules lacking a main function, thus
|
|
322
|
+
incapable of producing any output on their own. For such modules,
|
|
323
|
+
you must set the output before scanning the associated data. Since
|
|
324
|
+
the module's output typically varies with each scanned file, you
|
|
325
|
+
need to call this function prior to each invocation of `scan`.
|
|
326
|
+
Once `scan` is executed, the module's output is consumed and will
|
|
327
|
+
be empty unless set again before the subsequent call.
|
|
328
|
+
|
|
329
|
+
Case 2) applies when you have previously stored the module's output
|
|
330
|
+
for certain scanned data. In such cases, when rescanning the data,
|
|
331
|
+
you can utilize this function to supply the module's output,
|
|
332
|
+
thereby preventing redundant computation by the module. This
|
|
333
|
+
optimization enhances performance by eliminating the need for the
|
|
334
|
+
module to reparse the scanned data.
|
|
335
|
+
|
|
336
|
+
`module` can be either the YARA module name (i.e: "pe", "elf",
|
|
337
|
+
"dotnet", etc.) or the fully-qualified name for the protobuf message
|
|
338
|
+
associated to the module (i.e: "pe.PE", "elf.ELF", "dotnet.Dotnet",
|
|
339
|
+
etc.). `data` must be the Protocol Buffer message corresponding to
|
|
340
|
+
that module, serialized as raw bytes.
|
|
341
|
+
"""
|
|
342
|
+
...
|
|
343
|
+
|
|
344
|
+
def set_global(self, ident: str, value: Any) -> None:
|
|
345
|
+
r"""
|
|
346
|
+
Sets the value of a global variable.
|
|
347
|
+
|
|
348
|
+
The variable must has been previously defined by calling
|
|
349
|
+
[`Compiler::define_global`], and the type it has during the definition
|
|
350
|
+
must match the type of the new value.
|
|
351
|
+
|
|
352
|
+
The variable will retain the new value in subsequent scans, unless this
|
|
353
|
+
function is called again for setting a new value.
|
|
354
|
+
|
|
355
|
+
The type of `value` must be: `bool`, `str`, `bytes`, `int` or `float`.
|
|
356
|
+
|
|
357
|
+
# Raises
|
|
358
|
+
|
|
359
|
+
[TypeError](https://docs.python.org/3/library/exceptions.html#TypeError)
|
|
360
|
+
if the type of `value` is not one of the supported ones.
|
|
361
|
+
"""
|
|
362
|
+
...
|
|
363
|
+
|
|
364
|
+
def set_timeout(self, seconds: int) -> None:
|
|
365
|
+
r"""
|
|
366
|
+
Sets a timeout for each scan.
|
|
367
|
+
|
|
368
|
+
After setting a timeout scans will abort after the specified `seconds`.
|
|
369
|
+
"""
|
|
370
|
+
...
|
|
371
|
+
|
|
372
|
+
def max_matches_per_pattern(self, matches: int) -> None:
|
|
373
|
+
r"""
|
|
374
|
+
Sets the maximum number of matches per pattern.
|
|
375
|
+
|
|
376
|
+
When some pattern reaches the specified number of `matches` it won't produce more matches.
|
|
377
|
+
"""
|
|
378
|
+
...
|
|
379
|
+
|
|
380
|
+
def fast_scan(self, yes: bool) -> None:
|
|
381
|
+
r"""
|
|
382
|
+
Enables or disables fast scan mode.
|
|
383
|
+
|
|
384
|
+
In fast scan mode, the scanner avoids tracking matches for patterns when
|
|
385
|
+
it is not necessary (e.g. when a rule condition only performs a simple
|
|
386
|
+
boolean check `$a`).
|
|
387
|
+
|
|
388
|
+
Note that using fast scan mode implies that not all matches will be
|
|
389
|
+
reported. For instance, when iterating matches, you won't get all occurrences
|
|
390
|
+
of the pattern in the file, only the first one.
|
|
391
|
+
"""
|
|
392
|
+
...
|
|
393
|
+
|
|
394
|
+
def console_log(self, callback: collections.abc.Callable[[str], Any]) -> None:
|
|
395
|
+
r"""
|
|
396
|
+
Sets a callback that is invoked every time a YARA rule calls the
|
|
397
|
+
`console` module.
|
|
398
|
+
|
|
399
|
+
The `callback` function is invoked with a string representing the
|
|
400
|
+
message being logged. The function can print the message to stdout,
|
|
401
|
+
append it to a file, etc. If no callback is set these messages are
|
|
402
|
+
ignored.
|
|
403
|
+
"""
|
|
404
|
+
...
|
|
405
|
+
|
|
406
|
+
@final
|
|
407
|
+
class Formatter:
|
|
408
|
+
r"""
|
|
409
|
+
Formats YARA rules.
|
|
410
|
+
"""
|
|
411
|
+
def __new__(
|
|
412
|
+
cls,
|
|
413
|
+
align_metadata: bool = True,
|
|
414
|
+
align_patterns: bool = True,
|
|
415
|
+
indent_section_headers: bool = True,
|
|
416
|
+
indent_section_contents: bool = True,
|
|
417
|
+
indent_spaces: int = 2,
|
|
418
|
+
newline_before_curly_brace: bool = False,
|
|
419
|
+
empty_line_before_section_header: bool = True,
|
|
420
|
+
empty_line_after_section_header: bool = False,
|
|
421
|
+
) -> Formatter:
|
|
422
|
+
r"""
|
|
423
|
+
Creates a new [`Formatter`].
|
|
424
|
+
|
|
425
|
+
`align_metadata` allows for aligning the equals signs in metadata definitions.
|
|
426
|
+
`align_patterns` allows for aligning the equals signs in pattern definitions.
|
|
427
|
+
`indent_section_headers` allows for indenting section headers.
|
|
428
|
+
`indent_section_contents` allows for indenting section contents.
|
|
429
|
+
`indent_spaces` is the number of spaces to use for indentation.
|
|
430
|
+
`newline_before_curly_brace` controls whether a newline is inserted before a curly brace.
|
|
431
|
+
`empty_line_before_section_header` controls whether an empty line is inserted before a section header.
|
|
432
|
+
`empty_line_after_section_header` controls whether an empty line is inserted after a section header.
|
|
433
|
+
"""
|
|
434
|
+
...
|
|
435
|
+
|
|
436
|
+
def format(self, input: TextIO, output: TextIO) -> None:
|
|
437
|
+
r"""
|
|
438
|
+
Format a YARA rule
|
|
439
|
+
"""
|
|
440
|
+
...
|
|
441
|
+
|
|
442
|
+
@final
|
|
443
|
+
class Match:
|
|
444
|
+
r"""
|
|
445
|
+
Represents a match found for a pattern.
|
|
446
|
+
"""
|
|
447
|
+
@property
|
|
448
|
+
def offset(self) -> int:
|
|
449
|
+
r"""
|
|
450
|
+
Offset where the match occurred.
|
|
451
|
+
"""
|
|
452
|
+
...
|
|
453
|
+
|
|
454
|
+
@property
|
|
455
|
+
def length(self) -> int:
|
|
456
|
+
r"""
|
|
457
|
+
Length of the match in bytes.
|
|
458
|
+
"""
|
|
459
|
+
...
|
|
460
|
+
|
|
461
|
+
@property
|
|
462
|
+
def xor_key(self) -> Optional[int]:
|
|
463
|
+
r"""
|
|
464
|
+
XOR key used for decrypting the data if the pattern had the xor
|
|
465
|
+
modifier, or None if otherwise.
|
|
466
|
+
"""
|
|
467
|
+
...
|
|
468
|
+
|
|
469
|
+
@final
|
|
470
|
+
class Pattern:
|
|
471
|
+
r"""
|
|
472
|
+
Represents a pattern in a YARA rule.
|
|
473
|
+
"""
|
|
474
|
+
|
|
475
|
+
@property
|
|
476
|
+
def identifier(self) -> str:
|
|
477
|
+
r"""
|
|
478
|
+
Pattern identifier (e.g: '$a', '$foo').
|
|
479
|
+
"""
|
|
480
|
+
...
|
|
481
|
+
|
|
482
|
+
@property
|
|
483
|
+
def matches(self) -> Tuple[Match, ...]:
|
|
484
|
+
r"""
|
|
485
|
+
Matches found for this pattern.
|
|
486
|
+
"""
|
|
487
|
+
...
|
|
488
|
+
|
|
489
|
+
@final
|
|
490
|
+
class Rule:
|
|
491
|
+
r"""
|
|
492
|
+
Represents a rule that matched while scanning some data.
|
|
493
|
+
"""
|
|
494
|
+
|
|
495
|
+
@property
|
|
496
|
+
def identifier(self) -> str:
|
|
497
|
+
r"""
|
|
498
|
+
Returns the rule's name.
|
|
499
|
+
"""
|
|
500
|
+
...
|
|
501
|
+
|
|
502
|
+
@property
|
|
503
|
+
def namespace(self) -> str:
|
|
504
|
+
r"""
|
|
505
|
+
Returns the rule's namespace.
|
|
506
|
+
"""
|
|
507
|
+
...
|
|
508
|
+
|
|
509
|
+
@property
|
|
510
|
+
def tags(self) -> Tuple[str, ...]:
|
|
511
|
+
r"""
|
|
512
|
+
Returns the rule's tags.
|
|
513
|
+
"""
|
|
514
|
+
...
|
|
515
|
+
|
|
516
|
+
@property
|
|
517
|
+
def metadata(self) -> Tuple[Tuple[str, Any], ...]:
|
|
518
|
+
r"""
|
|
519
|
+
A tuple of pairs `(identifier, value)` with the metadata associated to
|
|
520
|
+
the rule.
|
|
521
|
+
"""
|
|
522
|
+
...
|
|
523
|
+
|
|
524
|
+
@property
|
|
525
|
+
def patterns(self) -> Tuple[Pattern, ...]:
|
|
526
|
+
r"""
|
|
527
|
+
Patterns defined by the rule.
|
|
528
|
+
"""
|
|
529
|
+
...
|
|
530
|
+
|
|
531
|
+
@final
|
|
532
|
+
class Rules:
|
|
533
|
+
r"""
|
|
534
|
+
A set of YARA rules in compiled form.
|
|
535
|
+
|
|
536
|
+
This is the result of [`Compiler::build`].
|
|
537
|
+
"""
|
|
538
|
+
|
|
539
|
+
def __iter__(self) -> collections.abc.Iterator[Rule]:
|
|
540
|
+
...
|
|
541
|
+
|
|
542
|
+
def scan(self, data: bytes) -> ScanResults:
|
|
543
|
+
r"""
|
|
544
|
+
Scans in-memory data with these rules.
|
|
545
|
+
"""
|
|
546
|
+
...
|
|
547
|
+
|
|
548
|
+
def scan_with_options(self, data: bytes, options: ScanOptions) -> ScanResults:
|
|
549
|
+
r"""
|
|
550
|
+
Like `scan`, but with options.
|
|
551
|
+
"""
|
|
552
|
+
...
|
|
553
|
+
|
|
554
|
+
def imports(self) -> list[str]:
|
|
555
|
+
r"""
|
|
556
|
+
Returns a list of modules imported by the rules.
|
|
557
|
+
"""
|
|
558
|
+
...
|
|
559
|
+
|
|
560
|
+
def serialize_into(self, file: BinaryIO) -> None:
|
|
561
|
+
r"""
|
|
562
|
+
Serializes the rules into a file-like object.
|
|
563
|
+
"""
|
|
564
|
+
...
|
|
565
|
+
|
|
566
|
+
@staticmethod
|
|
567
|
+
def deserialize_from(file: BinaryIO) -> Rules:
|
|
568
|
+
r"""
|
|
569
|
+
Deserializes rules from a file-like object.
|
|
570
|
+
"""
|
|
571
|
+
...
|
|
572
|
+
|
|
573
|
+
@final
|
|
574
|
+
class ScanResults:
|
|
575
|
+
r"""
|
|
576
|
+
Results produced by a scan operation.
|
|
577
|
+
"""
|
|
578
|
+
|
|
579
|
+
@property
|
|
580
|
+
def matching_rules(self) -> Tuple[Rule, ...]:
|
|
581
|
+
r"""
|
|
582
|
+
Rules that matched during the scan.
|
|
583
|
+
"""
|
|
584
|
+
...
|
|
585
|
+
|
|
586
|
+
@property
|
|
587
|
+
def module_outputs(self) -> Dict[str, Any]:
|
|
588
|
+
r"""
|
|
589
|
+
Module output from the scan.
|
|
590
|
+
"""
|
|
591
|
+
...
|
|
592
|
+
|
|
593
|
+
def compile(src: str) -> Rules:
|
|
594
|
+
r"""
|
|
595
|
+
Compiles a YARA source code producing a set of compiled [`Rules`].
|
|
596
|
+
|
|
597
|
+
This function allows compiling simple rules that don't depend on external
|
|
598
|
+
variables. For more complex use cases you will need to use a [`Compiler`].
|
|
599
|
+
"""
|
|
600
|
+
...
|
|
601
|
+
|
|
602
|
+
@final
|
|
603
|
+
class Module:
|
|
604
|
+
r"""A YARA-X module."""
|
|
605
|
+
def __new__(cls, name: str) -> Module:
|
|
606
|
+
r"""Creates a new [`Module`] with the given name, which must be a valid YARA-X module name."""
|
|
607
|
+
...
|
|
608
|
+
def invoke(self, data: str) -> Any:
|
|
609
|
+
r"""Parse the data and collect module metadata."""
|
|
610
|
+
...
|
|
611
|
+
|
|
612
|
+
@final
|
|
613
|
+
class MetaType(Enum):
|
|
614
|
+
STRING: int
|
|
615
|
+
INTEGER: int
|
|
616
|
+
FLOAT: int
|
|
617
|
+
BOOL: int
|
|
618
|
+
SHA256: int
|
|
619
|
+
SHA1: int
|
|
620
|
+
MD5: int
|
|
621
|
+
HASH: int
|
|
622
|
+
|
|
623
|
+
@final
|
|
624
|
+
class CheckResult:
|
|
625
|
+
r"""Result from the [`Compiler::check`] method after checking source code."""
|
|
626
|
+
def warning(self) -> bool:
|
|
627
|
+
r"""True if the result is a warning, false if it is an error."""
|
|
628
|
+
...
|
|
629
|
+
|
|
630
|
+
def code(self) -> bool:
|
|
631
|
+
r"""The string representation of the result code."""
|
|
632
|
+
...
|
|
633
|
+
|
|
634
|
+
def title(self) -> str:
|
|
635
|
+
r"""The title of the result code."""
|
|
636
|
+
...
|
|
637
|
+
|
|
638
|
+
def message(self) -> str:
|
|
639
|
+
r"""A multi-line message containing code, title and full compiler details."""
|
|
640
|
+
...
|
yara_x/py.typed
ADDED
|
File without changes
|
yara_x/yara_x.pyd
ADDED
|
Binary file
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: yarax-python-dex
|
|
3
|
+
Version: 1.20.0
|
|
4
|
+
Classifier: Programming Language :: Rust
|
|
5
|
+
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
6
|
+
Classifier: Programming Language :: Python :: Implementation :: PyPy
|
|
7
|
+
Classifier: License :: OSI Approved :: BSD License
|
|
8
|
+
Summary: Patched YARA-X Python bindings for APKiD (restored DEX fields)
|
|
9
|
+
Keywords: pattern-matching,cybersecurity,forensics,malware,yara
|
|
10
|
+
Home-Page: https://virustotal.github.io/yara-x
|
|
11
|
+
Requires-Python: >=3.9
|
|
12
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
|
13
|
+
Project-URL: homepage, https://virustotal.github.io/yara-x
|
|
14
|
+
Project-URL: repository, https://github.com/VirusTotal/yara-x.git
|
|
15
|
+
|
|
16
|
+

|
|
17
|
+

|
|
18
|
+
[](https://virustotal.github.io/yara-x/docs/api/python)
|
|
19
|
+
[](https://pepy.tech/project/yara-x)
|
|
20
|
+
[](https://pepy.tech/project/yara-x)
|
|
21
|
+

|
|
22
|
+
|
|
23
|
+
The official Python library for [YARA-X](https://virustotal.github.io/yara-x).
|
|
24
|
+
Supports Python 3.9+ in Linux, MacOS and Windows.
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
import yara_x
|
|
28
|
+
|
|
29
|
+
rules = yara_x.compile('''
|
|
30
|
+
rule test {
|
|
31
|
+
strings:
|
|
32
|
+
$a = "foobar"
|
|
33
|
+
condition:
|
|
34
|
+
$a
|
|
35
|
+
}''')
|
|
36
|
+
|
|
37
|
+
results = rules.scan(b"foobar")
|
|
38
|
+
|
|
39
|
+
assert results.matching_rules[0].identifier == "test"
|
|
40
|
+
assert results.matching_rules[0].patterns[0].identifier == "$a"
|
|
41
|
+
assert results.matching_rules[0].patterns[0].matches[0].offset == 0
|
|
42
|
+
assert results.matching_rules[0].patterns[0].matches[0].length == 6
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
For more information about how to use this library, please check
|
|
46
|
+
the [documentation](https://virustotal.github.io/yara-x/docs/api/python).
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
yara_x/__init__.py,sha256=nMyCIYe2XAcE0xoh-kWfMlEZjVx9_cnT6O6Iaxh9JoM,107
|
|
2
|
+
yara_x/__init__.pyi,sha256=l4VfitXqubcNJicQ-kDIMhHCrUjSr3hYRv8jfXNwq9w,19275
|
|
3
|
+
yara_x/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
yara_x/yara_x.pyd,sha256=_67eWgKFVtvedbJir7fA9c4o7CHrrwXpQauL9UE6U54,20195840
|
|
5
|
+
yarax_python_dex-1.20.0.dist-info/METADATA,sha256=6Hx-58oP0n0oP1h2g6XygT6qVjSCrh1oPeGzv1Apdkw,1878
|
|
6
|
+
yarax_python_dex-1.20.0.dist-info/WHEEL,sha256=ExUtbgnaLPBhPHV-Srgt0ISw4k8qD_AD8T3iaFig1l0,95
|
|
7
|
+
yarax_python_dex-1.20.0.dist-info/sboms/yara-x-py.cyclonedx.json,sha256=-FRJKC2zRviZMgM1ndtIPyVnfHT322hifmMFzABoN6A,374136
|
|
8
|
+
yarax_python_dex-1.20.0.dist-info/RECORD,,
|