yaralyzer 1.0.7__py3-none-any.whl → 1.0.9__py3-none-any.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 yaralyzer might be problematic. Click here for more details.
- CHANGELOG.md +9 -0
- yaralyzer/__init__.py +5 -3
- yaralyzer/bytes_match.py +106 -16
- yaralyzer/config.py +18 -5
- yaralyzer/decoding/bytes_decoder.py +41 -11
- yaralyzer/decoding/decoding_attempt.py +54 -17
- yaralyzer/encoding_detection/character_encodings.py +11 -7
- yaralyzer/encoding_detection/encoding_assessment.py +31 -5
- yaralyzer/encoding_detection/encoding_detector.py +43 -9
- yaralyzer/helpers/bytes_helper.py +113 -15
- yaralyzer/helpers/dict_helper.py +1 -1
- yaralyzer/helpers/file_helper.py +20 -13
- yaralyzer/helpers/rich_text_helper.py +16 -13
- yaralyzer/helpers/string_helper.py +1 -1
- yaralyzer/output/decoding_attempts_table.py +43 -9
- yaralyzer/output/file_export.py +23 -6
- yaralyzer/output/file_hashes_table.py +31 -2
- yaralyzer/output/regex_match_metrics.py +33 -8
- yaralyzer/output/rich_console.py +26 -9
- yaralyzer/util/argument_parser.py +12 -3
- yaralyzer/util/logging.py +31 -16
- yaralyzer/yara/yara_match.py +40 -17
- yaralyzer/yara/yara_rule_builder.py +55 -11
- yaralyzer/yaralyzer.py +117 -31
- {yaralyzer-1.0.7.dist-info → yaralyzer-1.0.9.dist-info}/METADATA +10 -9
- yaralyzer-1.0.9.dist-info/RECORD +32 -0
- yaralyzer-1.0.7.dist-info/RECORD +0 -32
- {yaralyzer-1.0.7.dist-info → yaralyzer-1.0.9.dist-info}/LICENSE +0 -0
- {yaralyzer-1.0.7.dist-info → yaralyzer-1.0.9.dist-info}/WHEEL +0 -0
- {yaralyzer-1.0.7.dist-info → yaralyzer-1.0.9.dist-info}/entry_points.txt +0 -0
yaralyzer/yaralyzer.py
CHANGED
|
@@ -1,19 +1,11 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Central class that handles setting up / compiling rules and reading binary data from files as needed.
|
|
3
|
-
Alternate constructors are provided depending on whether:
|
|
4
|
-
1. YARA rules are already compiled
|
|
5
|
-
2. YARA rules should be compiled from a string
|
|
6
|
-
3. YARA rules should be read from a file
|
|
7
|
-
4. YARA rules should be read from a directory of .yara files
|
|
8
|
-
|
|
9
|
-
The real action happens in the __rich__console__() dunder method.
|
|
10
|
-
"""
|
|
1
|
+
"""Main Yaralyzer class and alternate constructors."""
|
|
11
2
|
from os import path
|
|
12
|
-
from typing import Iterator, List, Optional, Tuple, Union
|
|
3
|
+
from typing import Callable, Iterator, List, Optional, Tuple, Union
|
|
13
4
|
|
|
14
5
|
import yara
|
|
15
6
|
from rich.console import Console, ConsoleOptions, RenderResult
|
|
16
7
|
from rich.padding import Padding
|
|
8
|
+
from rich.style import Style
|
|
17
9
|
from rich.text import Text
|
|
18
10
|
|
|
19
11
|
from yaralyzer.bytes_match import BytesMatch
|
|
@@ -34,6 +26,33 @@ YARA_FILE_DOES_NOT_EXIST_ERROR_MSG = "is not a valid yara rules file (it doesn't
|
|
|
34
26
|
|
|
35
27
|
# TODO: might be worth introducing a Scannable namedtuple or similar
|
|
36
28
|
class Yaralyzer:
|
|
29
|
+
"""
|
|
30
|
+
Central class that handles setting up / compiling YARA rules and reading binary data from files as needed.
|
|
31
|
+
|
|
32
|
+
Alternate constructors are provided depending on whether:
|
|
33
|
+
|
|
34
|
+
* YARA rules are already compiled
|
|
35
|
+
|
|
36
|
+
* YARA rules should be compiled from a string
|
|
37
|
+
|
|
38
|
+
* YARA rules should be read from a file
|
|
39
|
+
|
|
40
|
+
* YARA rules should be read from a directory of .yara files
|
|
41
|
+
|
|
42
|
+
The real action happens in the `__rich__console__()` dunder method.
|
|
43
|
+
|
|
44
|
+
Attributes:
|
|
45
|
+
bytes (bytes): The binary data to scan.
|
|
46
|
+
bytes_length (int): The length of the binary data.
|
|
47
|
+
scannable_label (str): A label for the binary data, typically the filename or a user-provided label.
|
|
48
|
+
rules (yara.Rules): The compiled YARA rules to use for scanning.
|
|
49
|
+
rules_label (str): A label for the ruleset, typically derived from filenames or user input.
|
|
50
|
+
highlight_style (str): The style to use for highlighting matches in the output.
|
|
51
|
+
non_matches (List[dict]): A list of YARA rules that did not match the binary data.
|
|
52
|
+
matches (List[YaraMatch]): A list of YaraMatch objects representing the matches found.
|
|
53
|
+
extraction_stats (RegexMatchMetrics): Metrics related to decoding attempts on matched data
|
|
54
|
+
"""
|
|
55
|
+
|
|
37
56
|
def __init__(
|
|
38
57
|
self,
|
|
39
58
|
rules: Union[str, yara.Rules],
|
|
@@ -43,10 +62,22 @@ class Yaralyzer:
|
|
|
43
62
|
highlight_style: str = YaralyzerConfig.HIGHLIGHT_STYLE
|
|
44
63
|
) -> None:
|
|
45
64
|
"""
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
65
|
+
Initialize a `Yaralyzer` instance for scanning binary data with YARA rules.
|
|
66
|
+
|
|
67
|
+
Args:
|
|
68
|
+
rules (Union[str, yara.Rules]): YARA rules to use for scanning. Can be a string or a pre-compiled
|
|
69
|
+
`yara.Rules` object (strings will be compiled to an instance of `yara.Rules`).
|
|
70
|
+
rules_label (str): Label to identify the ruleset in output and logs.
|
|
71
|
+
scannable (Union[bytes, str]): The data to scan. If it's `bytes` type then that data is scanned;
|
|
72
|
+
if it's a string it is treated as a file path to load bytes from.
|
|
73
|
+
scannable_label (Optional[str], optional): Label for the `scannable` arg data.
|
|
74
|
+
Required if `scannable` is `bytes`.
|
|
75
|
+
If `scannable` is a file path `scannable_label` will default to the file's basename.
|
|
76
|
+
highlight_style (str, optional): Style to use for highlighting matches in output.
|
|
77
|
+
Defaults to `YaralyzerConfig.HIGHLIGHT_STYLE`.
|
|
78
|
+
|
|
79
|
+
Raises:
|
|
80
|
+
TypeError: If `scannable` is `bytes` and `scannable_label` is not provided.
|
|
50
81
|
"""
|
|
51
82
|
if 'args' not in vars(YaralyzerConfig):
|
|
52
83
|
YaralyzerConfig.set_default_args()
|
|
@@ -58,7 +89,7 @@ class Yaralyzer:
|
|
|
58
89
|
|
|
59
90
|
if isinstance(scannable, bytes):
|
|
60
91
|
if scannable_label is None:
|
|
61
|
-
raise TypeError("Must provide scannable_label arg when yaralyzing raw bytes")
|
|
92
|
+
raise TypeError("Must provide 'scannable_label' arg when yaralyzing raw bytes")
|
|
62
93
|
|
|
63
94
|
self.bytes: bytes = scannable
|
|
64
95
|
self.scannable_label: str = scannable_label
|
|
@@ -87,13 +118,26 @@ class Yaralyzer:
|
|
|
87
118
|
scannable: Union[bytes, str],
|
|
88
119
|
scannable_label: Optional[str] = None
|
|
89
120
|
) -> 'Yaralyzer':
|
|
90
|
-
"""
|
|
121
|
+
"""
|
|
122
|
+
Alternate constructor to load YARA rules from files and label rules with the filenames.
|
|
123
|
+
|
|
124
|
+
Args:
|
|
125
|
+
yara_rules_files (List[str]): List of file paths to YARA rules files.
|
|
126
|
+
scannable (Union[bytes, str]): The data to scan. If `bytes`, raw data is scanned;
|
|
127
|
+
if `str`, it is treated as a file path to load bytes from.
|
|
128
|
+
scannable_label (Optional[str], optional): Label for the `scannable` data.
|
|
129
|
+
Required if `scannable` is `bytes`. If scannable is a file path, defaults to the file's basename.
|
|
130
|
+
|
|
131
|
+
Raises:
|
|
132
|
+
TypeError: If `yara_rules_files` is not a list.
|
|
133
|
+
FileNotFoundError: If any file in `yara_rules_files` does not exist.
|
|
134
|
+
"""
|
|
91
135
|
if not isinstance(yara_rules_files, list):
|
|
92
136
|
raise TypeError(f"{yara_rules_files} is not a list")
|
|
93
137
|
|
|
94
138
|
for file in yara_rules_files:
|
|
95
139
|
if not path.exists(file):
|
|
96
|
-
raise
|
|
140
|
+
raise FileNotFoundError(f"'{file}' {YARA_FILE_DOES_NOT_EXIST_ERROR_MSG}")
|
|
97
141
|
|
|
98
142
|
filepaths_arg = {path.basename(file): file for file in yara_rules_files}
|
|
99
143
|
|
|
@@ -112,9 +156,21 @@ class Yaralyzer:
|
|
|
112
156
|
scannable: Union[bytes, str],
|
|
113
157
|
scannable_label: Optional[str] = None
|
|
114
158
|
) -> 'Yaralyzer':
|
|
115
|
-
"""
|
|
159
|
+
"""
|
|
160
|
+
Alternate constructor that will load all `.yara` files in `yara_rules_dir`.
|
|
161
|
+
|
|
162
|
+
Args:
|
|
163
|
+
dirs (List[str]): List of directories to search for `.yara` files.
|
|
164
|
+
scannable (Union[bytes, str]): The data to scan. If `bytes`, raw data is scanned;
|
|
165
|
+
if `str`, it is treated as a file path to load bytes from.
|
|
166
|
+
scannable_label (Optional[str], optional): Label for the `scannable` data.
|
|
167
|
+
Required if `scannable` is `bytes`. If scannable is a file path, defaults to the file's basename.
|
|
168
|
+
|
|
169
|
+
Raises:
|
|
170
|
+
FileNotFoundError: If `dirs` is not a list of valid directories.
|
|
171
|
+
"""
|
|
116
172
|
if not (isinstance(dirs, list) and all(path.isdir(dir) for dir in dirs)):
|
|
117
|
-
raise
|
|
173
|
+
raise FileNotFoundError(f"'{dirs}' is not a list of valid directories")
|
|
118
174
|
|
|
119
175
|
rules_files = [path.join(dir, f) for dir in dirs for f in files_in_dir(dir)]
|
|
120
176
|
return cls.for_rules_files(rules_files, scannable, scannable_label)
|
|
@@ -130,7 +186,22 @@ class Yaralyzer:
|
|
|
130
186
|
pattern_label: Optional[str] = None,
|
|
131
187
|
regex_modifier: Optional[str] = None,
|
|
132
188
|
) -> 'Yaralyzer':
|
|
133
|
-
"""
|
|
189
|
+
"""
|
|
190
|
+
Alternate constructor taking regex pattern strings. Rules label defaults to the patterns joined by comma.
|
|
191
|
+
|
|
192
|
+
Args:
|
|
193
|
+
patterns (List[str]): List of regex or hex patterns to build rules from.
|
|
194
|
+
patterns_type (str): Either `"regex"` or `"hex"` to indicate the type of patterns provided.
|
|
195
|
+
scannable (Union[bytes, str]): The data to scan. If `bytes`, raw data is scanned;
|
|
196
|
+
if `str`, it is treated as a file path to load bytes from.
|
|
197
|
+
scannable_label (Optional[str], optional): Label for the `scannable` data.
|
|
198
|
+
Required if `scannable` is `bytes`.
|
|
199
|
+
If scannable is a file path, defaults to the file's basename.
|
|
200
|
+
rules_label (Optional[str], optional): Label for the ruleset. Defaults to the patterns joined by comma.
|
|
201
|
+
pattern_label (Optional[str], optional): Label for each pattern in the YARA rules. Defaults to "pattern".
|
|
202
|
+
regex_modifier (Optional[str], optional): Optional regex modifier (e.g. "nocase", "ascii", "wide", etc).
|
|
203
|
+
Only valid if `patterns_type` is `"regex"`.
|
|
204
|
+
"""
|
|
134
205
|
rule_strings = []
|
|
135
206
|
|
|
136
207
|
for i, pattern in enumerate(patterns):
|
|
@@ -149,11 +220,16 @@ class Yaralyzer:
|
|
|
149
220
|
return cls(rules_string, rules_label, scannable, scannable_label)
|
|
150
221
|
|
|
151
222
|
def yaralyze(self) -> None:
|
|
152
|
-
"""Use YARA to find matches and then force decode them"""
|
|
223
|
+
"""Use YARA to find matches and then force decode them."""
|
|
153
224
|
console.print(self)
|
|
154
225
|
|
|
155
226
|
def match_iterator(self) -> Iterator[Tuple[BytesMatch, BytesDecoder]]:
|
|
156
|
-
"""
|
|
227
|
+
"""
|
|
228
|
+
Iterator version of `yaralyze()`.
|
|
229
|
+
|
|
230
|
+
Yields:
|
|
231
|
+
Tuple[BytesMatch, BytesDecoder]: Match and decode data tuple.
|
|
232
|
+
"""
|
|
157
233
|
self.rules.match(data=self.bytes, callback=self._yara_callback)
|
|
158
234
|
|
|
159
235
|
for yara_match in self.matches:
|
|
@@ -167,7 +243,16 @@ class Yaralyzer:
|
|
|
167
243
|
|
|
168
244
|
self._print_non_matches()
|
|
169
245
|
|
|
170
|
-
def _yara_callback(self, data: dict):
|
|
246
|
+
def _yara_callback(self, data: dict) -> Callable:
|
|
247
|
+
"""
|
|
248
|
+
Callback invoked by `yara-python` to handle matches and non-matches as they are discovered.
|
|
249
|
+
|
|
250
|
+
Args:
|
|
251
|
+
data (dict): Data provided when `yara-python` invokes the callback.
|
|
252
|
+
|
|
253
|
+
Returns:
|
|
254
|
+
Callable: Always returns `yara.CALLBACK_CONTINUE` to signal `yara-python` should continue processing.
|
|
255
|
+
"""
|
|
171
256
|
if data['matches']:
|
|
172
257
|
self.matches.append(YaraMatch(data, self._panel_text()))
|
|
173
258
|
else:
|
|
@@ -176,7 +261,7 @@ class Yaralyzer:
|
|
|
176
261
|
return yara.CALLBACK_CONTINUE
|
|
177
262
|
|
|
178
263
|
def _print_non_matches(self) -> None:
|
|
179
|
-
"""Print info about the YARA rules that didn't match the bytes"""
|
|
264
|
+
"""Print info about the YARA rules that didn't match the bytes."""
|
|
180
265
|
if len(self.non_matches) == 0:
|
|
181
266
|
return
|
|
182
267
|
|
|
@@ -193,21 +278,21 @@ class Yaralyzer:
|
|
|
193
278
|
console.print(Padding(Text(', ', 'white').join(non_matches_text), (0, 0, 1, 4)))
|
|
194
279
|
|
|
195
280
|
def _panel_text(self) -> Text:
|
|
196
|
-
"""Inverted colors for the panel at the top of the match section of the output"""
|
|
281
|
+
"""Inverted colors for the panel at the top of the match section of the output."""
|
|
197
282
|
styles = [reverse_color(YARALYZER_THEME.styles[f"yara.{s}"]) for s in ('scanned', 'rules')]
|
|
198
283
|
return self.__text__(*styles)
|
|
199
284
|
|
|
200
|
-
def _filename_string(self):
|
|
201
|
-
"""The string to use when exporting this yaralyzer to SVG/HTML/etc"""
|
|
285
|
+
def _filename_string(self) -> str:
|
|
286
|
+
"""The string to use when exporting this yaralyzer to SVG/HTML/etc."""
|
|
202
287
|
return str(self).replace('>', '').replace('<', '').replace(' ', '_')
|
|
203
288
|
|
|
204
|
-
def __text__(self, byte_style: str = 'yara.scanned', rule_style: str = 'yara.rules') -> Text:
|
|
205
|
-
"""Text representation of this YARA scan (__text__() was taken)"""
|
|
289
|
+
def __text__(self, byte_style: Style | str = 'yara.scanned', rule_style: Style | str = 'yara.rules') -> Text:
|
|
290
|
+
"""Text representation of this YARA scan (__text__() was taken)."""
|
|
206
291
|
txt = Text('').append(self.scannable_label, style=byte_style or 'yara.scanned')
|
|
207
292
|
return txt.append(' scanned with <').append(self.rules_label, style=rule_style or 'yara.rules').append('>')
|
|
208
293
|
|
|
209
294
|
def __rich_console__(self, _console: Console, options: ConsoleOptions) -> RenderResult:
|
|
210
|
-
"""Does the stuff. TODO: not the best place to put the core logic"""
|
|
295
|
+
"""Does the stuff. TODO: not the best place to put the core logic."""
|
|
211
296
|
yield bytes_hashes_table(self.bytes, self.scannable_label)
|
|
212
297
|
|
|
213
298
|
for _bytes_match, bytes_decoder in self.match_iterator():
|
|
@@ -215,4 +300,5 @@ class Yaralyzer:
|
|
|
215
300
|
yield attempt
|
|
216
301
|
|
|
217
302
|
def __str__(self) -> str:
|
|
303
|
+
"""Plain text (no rich colors) representation of the scan for display."""
|
|
218
304
|
return self.__text__().plain
|
|
@@ -1,20 +1,19 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: yaralyzer
|
|
3
|
-
Version: 1.0.
|
|
4
|
-
Summary: Visualize and force decode YARA and regex matches found in a file or byte stream
|
|
3
|
+
Version: 1.0.9
|
|
4
|
+
Summary: Visualize and force decode YARA and regex matches found in a file or byte stream with colors. Lots of colors.
|
|
5
5
|
Home-page: https://github.com/michelcrypt4d4mus/yaralyzer
|
|
6
6
|
License: GPL-3.0-or-later
|
|
7
7
|
Keywords: ascii art,binary,character encoding,color,cybersecurity,data visualization,decode,DFIR,encoding,infosec,maldoc,malicious,malware,malware analysis,regex,regular expressions,reverse engineering,reversing,security,threat assessment,threat hunting,threat intelligence,threat research,threatintel,visualization,yara
|
|
8
8
|
Author: Michel de Cryptadamus
|
|
9
9
|
Author-email: michel@cryptadamus.com
|
|
10
|
-
Requires-Python: >=3.
|
|
10
|
+
Requires-Python: >=3.10,<4.0
|
|
11
11
|
Classifier: Development Status :: 5 - Production/Stable
|
|
12
12
|
Classifier: Environment :: Console
|
|
13
13
|
Classifier: Intended Audience :: Information Technology
|
|
14
14
|
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
|
|
15
15
|
Classifier: Programming Language :: Python
|
|
16
16
|
Classifier: Programming Language :: Python :: 3
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
18
17
|
Classifier: Programming Language :: Python :: 3.10
|
|
19
18
|
Classifier: Programming Language :: Python :: 3.11
|
|
20
19
|
Classifier: Programming Language :: Python :: 3.12
|
|
@@ -23,12 +22,12 @@ Classifier: Topic :: Artistic Software
|
|
|
23
22
|
Classifier: Topic :: Scientific/Engineering :: Visualization
|
|
24
23
|
Classifier: Topic :: Security
|
|
25
24
|
Requires-Dist: chardet (>=5.0.0,<6.0.0)
|
|
26
|
-
Requires-Dist: python-dotenv (>=
|
|
25
|
+
Requires-Dist: python-dotenv (>=1.1.1,<2.0.0)
|
|
27
26
|
Requires-Dist: rich (>=14.1.0,<15.0.0)
|
|
28
27
|
Requires-Dist: rich-argparse-plus (>=0.3.1,<0.4.0)
|
|
29
28
|
Requires-Dist: yara-python (>=4.5.4,<5.0.0)
|
|
30
29
|
Project-URL: Changelog, https://github.com/michelcrypt4d4mus/yaralyzer/blob/master/CHANGELOG.md
|
|
31
|
-
Project-URL: Documentation, https://github.
|
|
30
|
+
Project-URL: Documentation, https://michelcrypt4d4mus.github.io/yaralyzer/
|
|
32
31
|
Project-URL: Repository, https://github.com/michelcrypt4d4mus/yaralyzer
|
|
33
32
|
Description-Content-Type: text/markdown
|
|
34
33
|
|
|
@@ -79,7 +78,7 @@ YARA just tells you the byte position and the matched string but it can't tell y
|
|
|
79
78
|
|
|
80
79
|
Enter **The Yaralyzer**, which lets you quickly scan the regions around matches while also showing you what those regions would look like if they were forced into various character encodings.
|
|
81
80
|
|
|
82
|
-
|
|
81
|
+
**The Yaralyzer** isn't a malware reversing tool. It can't do all the things a tool like [CyberChef](https://gchq.github.io/CyberChef/) does and it doesn't try to. It's more intended to give you a quick visual overview of suspect regions in the binary so you can hone in on the areas you might want to inspect with a more serious tool like [CyberChef](https://gchq.github.io/CyberChef/).
|
|
83
82
|
|
|
84
83
|
# Installation
|
|
85
84
|
Install it with [`pipx`](https://pypa.github.io/pipx/) or `pip3`. `pipx` is a marginally better solution as it guarantees any packages installed with it will be isolated from the rest of your local python environment. Of course if you don't really have a local python environment this is a moot point and you can feel free to install with `pip`/`pip3`.
|
|
@@ -87,6 +86,7 @@ Install it with [`pipx`](https://pypa.github.io/pipx/) or `pip3`. `pipx` is a ma
|
|
|
87
86
|
pipx install yaralyzer
|
|
88
87
|
```
|
|
89
88
|
|
|
89
|
+
|
|
90
90
|
# Usage
|
|
91
91
|
Run `yaralyze -h` to see the command line options (screenshot below).
|
|
92
92
|
|
|
@@ -100,7 +100,7 @@ If you place a file called `.yaralyzer` in your home directory or the current wo
|
|
|
100
100
|
Only one `.yaralyzer` file will be loaded and the working directory's `.yaralyzer` takes precedence over the home directory's `.yaralyzer`.
|
|
101
101
|
|
|
102
102
|
### As A Library
|
|
103
|
-
[`Yaralyzer`](yaralyzer/yaralyzer.py) is the main class. It has a variety of constructors supporting:
|
|
103
|
+
[`Yaralyzer`](yaralyzer/yaralyzer.py) is the main class. Auto generated documentation for `Yaralyzer`'s various classes and methods can be found [here](https://michelcrypt4d4mus.github.io/yaralyzer/). It has a variety of [alternate constructors](https://michelcrypt4d4mus.github.io/yaralyzer/api/yaralyzer/) supporting:
|
|
104
104
|
|
|
105
105
|
1. Precompiled YARA rules
|
|
106
106
|
1. Creating a YARA rule from a string
|
|
@@ -109,7 +109,7 @@ Only one `.yaralyzer` file will be loaded and the working directory's `.yaralyze
|
|
|
109
109
|
1. Scanning `bytes`
|
|
110
110
|
1. Scanning a file
|
|
111
111
|
|
|
112
|
-
Should you want to iterate over the `BytesMatch` (like a `re.Match` object for a YARA match) and `BytesDecoder` (tracks decoding attempt stats) objects
|
|
112
|
+
Should you want to iterate over the [`BytesMatch`](https://michelcrypt4d4mus.github.io/yaralyzer/api/bytes_match/) (like a `re.Match` object for a YARA match) and [`BytesDecoder`](https://michelcrypt4d4mus.github.io/yaralyzer/api/bytes_decoder/) (tracks decoding attempt stats) objects used by The Yaralyzer, you can do so like this:
|
|
113
113
|
|
|
114
114
|
```python
|
|
115
115
|
from yaralyzer.yaralyzer import Yaralyzer
|
|
@@ -120,6 +120,7 @@ for bytes_match, bytes_decoder in yaralyzer.match_iterator():
|
|
|
120
120
|
do_stuff()
|
|
121
121
|
```
|
|
122
122
|
|
|
123
|
+
|
|
123
124
|
# Example Output
|
|
124
125
|
The Yaralyzer can export visualizations to HTML, ANSI colored text, and SVG vector images using the file export functionality that comes with [Rich](https://github.com/Textualize/rich) as well as a (somewhat limited) plain text JSON format. SVGs can be turned into `png` format images with a tool like [Inkscape](https://inkscape.org/) or `cairosvg`. In our experience they both work though we've seen some glitchiness with `cairosvg`.
|
|
125
126
|
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
.yaralyzer.example,sha256=z3_mk41xxm0Pr_8MGM7AKQG0xEFRtGcyJLboMuelRp4,3504
|
|
2
|
+
CHANGELOG.md,sha256=lepFLLmnoHWaac4ae49WqSbpqXXxge2S2mDvE2qbixE,3408
|
|
3
|
+
LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
4
|
+
yaralyzer/__init__.py,sha256=FHfzll5jfldsqx3pXVBPu9xwDqFKjEVfTL7dha9BYX8,2793
|
|
5
|
+
yaralyzer/bytes_match.py,sha256=ROMv9gK0R1bDP5IpheNyxQ44_oEJPkHn_XYwkoIYKdQ,10901
|
|
6
|
+
yaralyzer/config.py,sha256=uVT8Jjw6kViH_PvBQ0etaH3JXPWOIXgiaoAv3ompnJA,4558
|
|
7
|
+
yaralyzer/decoding/bytes_decoder.py,sha256=8uKmqXEchjhTFULrcIKk699bfbBJrwvr9A8GlzCq0Z0,10200
|
|
8
|
+
yaralyzer/decoding/decoding_attempt.py,sha256=gUroTUSgWrgD-EZH8t5vsdDk0DSPqHMt0ow947sSFok,10290
|
|
9
|
+
yaralyzer/encoding_detection/character_encodings.py,sha256=_b3Vk5abAcKVDZ7QQyrAMQODAgMjG54AjqxdSGSdaj0,5637
|
|
10
|
+
yaralyzer/encoding_detection/encoding_assessment.py,sha256=q7wa2rls5nXEioX9UqzaNk4TxdW5WKzXjQik9e9AHs4,3262
|
|
11
|
+
yaralyzer/encoding_detection/encoding_detector.py,sha256=9zV1ZA6D3z9t6-Bz2IhcmqufJ_7zGJ0Rzh2gn0fmaO8,6487
|
|
12
|
+
yaralyzer/helpers/bytes_helper.py,sha256=7l0EycirLsPl--BakAEH-P7ruAgGgu75zYEfiw0OwO4,10212
|
|
13
|
+
yaralyzer/helpers/dict_helper.py,sha256=rhyu-xlpl4yevXdLZUIgVwap0b57O9I3DNAEv8MfTlI,186
|
|
14
|
+
yaralyzer/helpers/file_helper.py,sha256=tjiwCr8EMFHHmX4R13J4Sba5xv0IWXhEGyWUvGvCSa8,1588
|
|
15
|
+
yaralyzer/helpers/list_helper.py,sha256=zX6VzJDbnyxuwQpth5Mc7k7yeJytqWPzpo1v5nXCMtE,394
|
|
16
|
+
yaralyzer/helpers/rich_text_helper.py,sha256=7h3MOORdfZ8vrfUJ5sei4GOMxyfTonxmzii_VhrJZ6U,4383
|
|
17
|
+
yaralyzer/helpers/string_helper.py,sha256=8XsvYlKn-fGhKihfJBOG6mqi5nV_8LM-IWgHzvkRgCc,933
|
|
18
|
+
yaralyzer/output/decoding_attempts_table.py,sha256=wQ3cyN9czZkC3cbwjgflSu0t4wDKGDIs5NPOE6UwBLk,5004
|
|
19
|
+
yaralyzer/output/file_export.py,sha256=iTlCYErquuy6tqBZ1_BQHxBk-6jZ2ihTnGe83HEI_5o,3300
|
|
20
|
+
yaralyzer/output/file_hashes_table.py,sha256=pKbIc1bHJIIorqk9R2gz3IhTxKJpYU1TioGgceyoxiI,2615
|
|
21
|
+
yaralyzer/output/regex_match_metrics.py,sha256=ZQjzePPXpq_g99KNQjHrRQ1N6u_OUxD32uf9xnqcOw8,4341
|
|
22
|
+
yaralyzer/output/rich_console.py,sha256=mQEK0hq2qyCzqebzNDmNTqG2O8pqwBKs_UFIC0DEvxM,5124
|
|
23
|
+
yaralyzer/util/argument_parser.py,sha256=ZOsBf5xkAWHFSWPbZt7_OdkYHIY3RIjtK1QIXOj2g6U,13281
|
|
24
|
+
yaralyzer/util/logging.py,sha256=aBvpNukwZTGOgzm_zpwWzTWFrptThk-g2cqi8D4Fkmo,4616
|
|
25
|
+
yaralyzer/yara/yara_match.py,sha256=BwWbVgYYCybT9TMhWgkT5vA54C9XJ7fAmGf6JKncjhA,5845
|
|
26
|
+
yaralyzer/yara/yara_rule_builder.py,sha256=PeuhPtO4FvXJoTegQr0NXwGpX7wxPfGzAO1tMozaZd8,4535
|
|
27
|
+
yaralyzer/yaralyzer.py,sha256=CLczlTW2ppyoChkPIGvQWwAo-5F0LG_rMEJpCy4cucg,13813
|
|
28
|
+
yaralyzer-1.0.9.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
29
|
+
yaralyzer-1.0.9.dist-info/METADATA,sha256=sN9ZZxRsjj79m5miQ535kers7OVuSYLcvB6Uuu8COqY,11255
|
|
30
|
+
yaralyzer-1.0.9.dist-info/WHEEL,sha256=d2fvjOD7sXsVzChCqf0Ty0JbHKBaLYwDbGQDwQTnJ50,88
|
|
31
|
+
yaralyzer-1.0.9.dist-info/entry_points.txt,sha256=7LnLJrNTfql0vuctjRWwp_ZD-BYvtv9ENVipdjuT7XI,136
|
|
32
|
+
yaralyzer-1.0.9.dist-info/RECORD,,
|
yaralyzer-1.0.7.dist-info/RECORD
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
.yaralyzer.example,sha256=z3_mk41xxm0Pr_8MGM7AKQG0xEFRtGcyJLboMuelRp4,3504
|
|
2
|
-
CHANGELOG.md,sha256=UHpQ3BD0GvGKBE6uX9MrUvLyK0qDi_bY7BlElM9JuWk,3001
|
|
3
|
-
LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
4
|
-
yaralyzer/__init__.py,sha256=xR5L4w3HQYiQeRUmhI89G4z0mgGF5tFZ4s5DibVbMiQ,2619
|
|
5
|
-
yaralyzer/bytes_match.py,sha256=HiN5Afnx64ReolQuLJzx827VOZ9Okb7ix2GfZNUEe4U,8091
|
|
6
|
-
yaralyzer/config.py,sha256=zQbDFlTxNrA_ViBJ6ocpGQFaPBCJNWPxgSwNwVspzuE,3942
|
|
7
|
-
yaralyzer/decoding/bytes_decoder.py,sha256=3AT1xvHd2Uh-5lVRAq-iybtw4w-iZtTMeqD-5qVq8zc,8596
|
|
8
|
-
yaralyzer/decoding/decoding_attempt.py,sha256=Wi82uQHsz7-GBvt7i6QbaxgGBIU9o1t-VyqpEmBuQE0,8460
|
|
9
|
-
yaralyzer/encoding_detection/character_encodings.py,sha256=DvsBcUFLLsd5yzv3kGtGMhEME2noELysq-pZMjt17ZU,5463
|
|
10
|
-
yaralyzer/encoding_detection/encoding_assessment.py,sha256=fmA3XlFw3-s7rMgn-E_DTnZk2JDGcw93bGvSkjNI2WM,2350
|
|
11
|
-
yaralyzer/encoding_detection/encoding_detector.py,sha256=xpyWyIpcFzR84Hx_HnlekLQsAjUhP6etwYjZ11myPG0,4683
|
|
12
|
-
yaralyzer/helpers/bytes_helper.py,sha256=MZakPrba_8CRUFx60Z8vwf7tozYX8ZuyCN2FudJYfcY,7440
|
|
13
|
-
yaralyzer/helpers/dict_helper.py,sha256=hp96ZLzKDvacb9iJh1386ciXx-XejSGiPzllB7WhDZw,185
|
|
14
|
-
yaralyzer/helpers/file_helper.py,sha256=uf8dTOhRrJng0V36o7Mwk5t-L5gc4_uOaGj9F0s5OBA,1254
|
|
15
|
-
yaralyzer/helpers/list_helper.py,sha256=zX6VzJDbnyxuwQpth5Mc7k7yeJytqWPzpo1v5nXCMtE,394
|
|
16
|
-
yaralyzer/helpers/rich_text_helper.py,sha256=PYHne9bBVnotb0d7i55TETJjOTshEVU87i0gE0MLOuc,4195
|
|
17
|
-
yaralyzer/helpers/string_helper.py,sha256=AT2_CAgpvtp8GiUSKLTiDoToDD3tBB9BbrlX-s2bL7o,932
|
|
18
|
-
yaralyzer/output/decoding_attempts_table.py,sha256=x6AViJqAj7ept92OXWl9-PVk8MyBSyYt62mUgJjsP7U,4040
|
|
19
|
-
yaralyzer/output/file_export.py,sha256=J7La_7ryg6mMipbeBUYGPFJrkgshn14ERoayCrnFHtc,2901
|
|
20
|
-
yaralyzer/output/file_hashes_table.py,sha256=bM7xl8ucgrNxWVSUXfOLrtei2rDbrL1a8nV-Q2uGtok,1616
|
|
21
|
-
yaralyzer/output/regex_match_metrics.py,sha256=deJPaVnhpy-AUX6PCE_jbPLIlmfIOtl-cEVWsiFp3KY,3003
|
|
22
|
-
yaralyzer/output/rich_console.py,sha256=yME6giQosel8XlEnnHhQGMYishGCRWL9wrpkoyrICjc,4249
|
|
23
|
-
yaralyzer/util/argument_parser.py,sha256=tLLTet7I3LBnvMxJ3epcSIrbKkwjqGzSipO2netZTsw,12924
|
|
24
|
-
yaralyzer/util/logging.py,sha256=tPtAeZQf1VassyHTxgR69Y7t1Y6v6SmDWel2-Og93kA,4239
|
|
25
|
-
yaralyzer/yara/yara_match.py,sha256=F_1tn1ynbTwzOWSblis02DlVunn-vY3IPX8QjJhukMs,5118
|
|
26
|
-
yaralyzer/yara/yara_rule_builder.py,sha256=P7NPzMMz03V1rDH3PMwb3VAbpBFD-oLNkiCIJAtLa7A,2990
|
|
27
|
-
yaralyzer/yaralyzer.py,sha256=3EIiDHHbi_fjWdCmMnDEW8ZGWxL6xPeNxt58oTeZxJw,9291
|
|
28
|
-
yaralyzer-1.0.7.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
29
|
-
yaralyzer-1.0.7.dist-info/METADATA,sha256=a3aiyG-MzWHoiJ55dkDSOkC_G4gFCeIHfhpjh2F2zS4,10993
|
|
30
|
-
yaralyzer-1.0.7.dist-info/WHEEL,sha256=d2fvjOD7sXsVzChCqf0Ty0JbHKBaLYwDbGQDwQTnJ50,88
|
|
31
|
-
yaralyzer-1.0.7.dist-info/entry_points.txt,sha256=7LnLJrNTfql0vuctjRWwp_ZD-BYvtv9ENVipdjuT7XI,136
|
|
32
|
-
yaralyzer-1.0.7.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|