yaralyzer 0.9.5__py3-none-any.whl → 1.0.0__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 +6 -0
- yaralyzer/__init__.py +4 -1
- yaralyzer/bytes_match.py +20 -2
- yaralyzer/output/file_export.py +20 -0
- yaralyzer/util/argument_parser.py +8 -3
- yaralyzer/yara/yara_match.py +0 -1
- {yaralyzer-0.9.5.dist-info → yaralyzer-1.0.0.dist-info}/METADATA +2 -2
- {yaralyzer-0.9.5.dist-info → yaralyzer-1.0.0.dist-info}/RECORD +11 -11
- {yaralyzer-0.9.5.dist-info → yaralyzer-1.0.0.dist-info}/LICENSE +0 -0
- {yaralyzer-0.9.5.dist-info → yaralyzer-1.0.0.dist-info}/WHEEL +0 -0
- {yaralyzer-0.9.5.dist-info → yaralyzer-1.0.0.dist-info}/entry_points.txt +0 -0
CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# NEXT RELEASE
|
|
2
2
|
|
|
3
|
+
# 1.0.0
|
|
4
|
+
* Add `--export-json` option
|
|
5
|
+
|
|
6
|
+
### 0.9.6
|
|
7
|
+
* Fix help message
|
|
8
|
+
|
|
3
9
|
### 0.9.5
|
|
4
10
|
* Use all files in a directory specified by `--rule-dir` instead of just those with the extension `.yara`
|
|
5
11
|
* Fix bug where `--rule-dir` is prefixed by `./`
|
yaralyzer/__init__.py
CHANGED
|
@@ -12,7 +12,7 @@ if not environ.get('INVOKED_BY_PYTEST', False):
|
|
|
12
12
|
break
|
|
13
13
|
|
|
14
14
|
from yaralyzer.config import YaralyzerConfig
|
|
15
|
-
from yaralyzer.output.file_export import invoke_rich_export
|
|
15
|
+
from yaralyzer.output.file_export import export_json, invoke_rich_export
|
|
16
16
|
from yaralyzer.output.rich_console import console
|
|
17
17
|
from yaralyzer.util.argument_parser import get_export_basepath, parse_arguments
|
|
18
18
|
from yaralyzer.util.logging import log
|
|
@@ -59,6 +59,9 @@ def yaralyze():
|
|
|
59
59
|
if args.export_svg:
|
|
60
60
|
invoke_rich_export(console.save_svg, output_basepath)
|
|
61
61
|
|
|
62
|
+
if args.export_json:
|
|
63
|
+
export_json(yaralyzer, output_basepath)
|
|
64
|
+
|
|
62
65
|
if args.file_to_scan_path.endswith('.pdf'):
|
|
63
66
|
console.print(PDFALYZER_MSG_TXT)
|
|
64
67
|
|
yaralyzer/bytes_match.py
CHANGED
|
@@ -14,9 +14,8 @@ from yara import StringMatch, StringMatchInstance
|
|
|
14
14
|
|
|
15
15
|
from yaralyzer.config import YaralyzerConfig
|
|
16
16
|
from yaralyzer.helpers.rich_text_helper import prefix_with_plain_text_obj
|
|
17
|
-
from yaralyzer.output.rich_console import ALERT_STYLE, GREY_ADDRESS
|
|
18
17
|
from yaralyzer.output.file_hashes_table import bytes_hashes_table
|
|
19
|
-
from yaralyzer.
|
|
18
|
+
from yaralyzer.output.rich_console import ALERT_STYLE, GREY_ADDRESS
|
|
20
19
|
|
|
21
20
|
|
|
22
21
|
class BytesMatch:
|
|
@@ -157,6 +156,25 @@ class BytesMatch:
|
|
|
157
156
|
|
|
158
157
|
return txt
|
|
159
158
|
|
|
159
|
+
def to_json(self) -> dict:
|
|
160
|
+
"""Convert this BytesMatch to a JSON-serializable dict."""
|
|
161
|
+
json_dict = {
|
|
162
|
+
'label': self.label,
|
|
163
|
+
'match_length': self.match_length,
|
|
164
|
+
'matched_bytes': self.bytes.hex(),
|
|
165
|
+
'ordinal': self.ordinal,
|
|
166
|
+
'start_idx': self.start_idx,
|
|
167
|
+
'end_idx': self.end_idx,
|
|
168
|
+
'surrounding_bytes': self.surrounding_bytes.hex(),
|
|
169
|
+
'surrounding_start_idx': self.surrounding_start_idx,
|
|
170
|
+
'surrounding_end_idx': self.surrounding_end_idx,
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if self.match:
|
|
174
|
+
json_dict['pattern'] = self.match.re.pattern
|
|
175
|
+
|
|
176
|
+
return json_dict
|
|
177
|
+
|
|
160
178
|
def _find_surrounding_bytes(self, num_before: Optional[int] = None, num_after: Optional[int] = None) -> None:
|
|
161
179
|
"""Find the surrounding bytes, making sure not to step off the beginning or end"""
|
|
162
180
|
num_after = num_after or num_before or YaralyzerConfig.args.surrounding_bytes
|
yaralyzer/output/file_export.py
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
|
+
import json
|
|
1
2
|
import time
|
|
3
|
+
from argparse import Namespace
|
|
4
|
+
from pathlib import Path
|
|
2
5
|
from os import path
|
|
3
6
|
|
|
4
7
|
from rich.terminal_theme import TerminalTheme
|
|
5
8
|
|
|
6
9
|
from yaralyzer.util.logging import log_and_print
|
|
10
|
+
from yaralyzer.yaralyzer import Yaralyzer
|
|
7
11
|
|
|
8
12
|
# TerminalThemes are used when saving SVGS. This one just swaps white for black in DEFAULT_TERMINAL_THEME
|
|
9
13
|
YARALYZER_TERMINAL_THEME = TerminalTheme(
|
|
@@ -47,6 +51,22 @@ _EXPORT_KWARGS = {
|
|
|
47
51
|
}
|
|
48
52
|
|
|
49
53
|
|
|
54
|
+
def export_json(yaralyzer: Yaralyzer, output_basepath: str | None) -> str:
|
|
55
|
+
"""Export YARA scan results to JSON. Returns the path to the output file that was written."""
|
|
56
|
+
output_path = f"{output_basepath or 'yara_matches'}.json"
|
|
57
|
+
|
|
58
|
+
matches_data = [
|
|
59
|
+
bytes_match.to_json()
|
|
60
|
+
for bytes_match, _bytes_decoder in yaralyzer.match_iterator()
|
|
61
|
+
]
|
|
62
|
+
|
|
63
|
+
with open(output_path, 'w') as f:
|
|
64
|
+
json.dump(matches_data, f, indent=4)
|
|
65
|
+
|
|
66
|
+
log_and_print(f"YARA matches exported to JSON file: '{output_path}'")
|
|
67
|
+
return output_path
|
|
68
|
+
|
|
69
|
+
|
|
50
70
|
def invoke_rich_export(export_method, output_file_basepath) -> str:
|
|
51
71
|
"""
|
|
52
72
|
Announce the export, perform the export, announce completion.
|
|
@@ -29,7 +29,7 @@ DESCRIPTION = "Get a good hard colorful look at all the byte sequences that make
|
|
|
29
29
|
EPILOG = "* Values for various config options can be set permanently by a .yaralyzer file in your home directory; " + \
|
|
30
30
|
"see the documentation for details.\n" + \
|
|
31
31
|
f"* A registry of previous yaralyzer invocations will be incribed to a file if the " + \
|
|
32
|
-
"
|
|
32
|
+
f"{YaralyzerConfig.LOG_DIR_ENV_VAR} environment variable is configured."
|
|
33
33
|
|
|
34
34
|
|
|
35
35
|
# Positional args, version, help, etc
|
|
@@ -95,7 +95,7 @@ tuning.add_argument('--suppress-decodes-table', action='store_true',
|
|
|
95
95
|
help='suppress decodes table entirely (including hex/raw output)')
|
|
96
96
|
|
|
97
97
|
tuning.add_argument('--suppress-decoding-attempts', action='store_true',
|
|
98
|
-
help='suppress
|
|
98
|
+
help='suppress decode attempts for matched bytes (only hex/raw output will be shown)')
|
|
99
99
|
|
|
100
100
|
tuning.add_argument('--min-decode-length',
|
|
101
101
|
help='suppress decode attempts for quoted byte sequences shorter than N',
|
|
@@ -179,6 +179,11 @@ export.add_argument('-html', '--export-html',
|
|
|
179
179
|
const='html',
|
|
180
180
|
help='export analysis to styled html files')
|
|
181
181
|
|
|
182
|
+
export.add_argument('-json', '--export-json',
|
|
183
|
+
action='store_const',
|
|
184
|
+
const='json',
|
|
185
|
+
help='export analysis to JSON files')
|
|
186
|
+
|
|
182
187
|
export.add_argument('-out', '--output-dir',
|
|
183
188
|
metavar='OUTPUT_DIR',
|
|
184
189
|
help='write files to OUTPUT_DIR instead of current dir, does nothing if not exporting a file')
|
|
@@ -257,7 +262,7 @@ def parse_arguments(args: Optional[Namespace] = None):
|
|
|
257
262
|
EncodingDetector.force_display_threshold = args.force_display_threshold
|
|
258
263
|
|
|
259
264
|
# File export options
|
|
260
|
-
if args.
|
|
265
|
+
if args.export_html or args.export_json or args.export_svg or args.export_txt:
|
|
261
266
|
args.output_dir = args.output_dir or getcwd()
|
|
262
267
|
elif args.output_dir:
|
|
263
268
|
log.warning('--output-dir provided but no export option was chosen')
|
yaralyzer/yara/yara_match.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: yaralyzer
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 1.0.0
|
|
4
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
|
|
@@ -113,7 +113,7 @@ for bytes_match, bytes_decoder in yaralyzer.match_iterator():
|
|
|
113
113
|
```
|
|
114
114
|
|
|
115
115
|
# Example Output
|
|
116
|
-
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). 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`.
|
|
116
|
+
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`.
|
|
117
117
|
|
|
118
118
|
**PyPi Users:** If you are reading this document [on PyPi](https://pypi.org/project/yaralyzer/) be aware that it renders a lot better [over on GitHub](https://github.com/michelcrypt4d4mus/yaralyzer). Pretty pictures, footnotes that work, etc.
|
|
119
119
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
.yaralyzer.example,sha256=4QKFDDNvnAlT3NVS0eiM_Qed9Hxy4ZPQFJkye8lKYAk,3486
|
|
2
|
-
CHANGELOG.md,sha256=
|
|
3
|
-
yaralyzer/__init__.py,sha256=
|
|
4
|
-
yaralyzer/bytes_match.py,sha256=
|
|
2
|
+
CHANGELOG.md,sha256=XN0_isuQMJy03PATrBkBIPWyIXzUV1g5YG1FMThCves,2158
|
|
3
|
+
yaralyzer/__init__.py,sha256=YItEM_QKbLUj-6QZg2ZINrTzPQZ1IHOjGgoxmRR2buA,2703
|
|
4
|
+
yaralyzer/bytes_match.py,sha256=ShAxI_jZYElG1w-FJ9wNF-5SReL2uv-iJTiQQS3VTM0,8213
|
|
5
5
|
yaralyzer/config.py,sha256=eRJ88wBFs1rfjOv4htI1Ye0LFCFfk4kGDiFHuqZfkX0,3730
|
|
6
6
|
yaralyzer/decoding/bytes_decoder.py,sha256=lulfZZhYmo9ky2KpqBW-c9hs5_uhlaz0gatdtT_NYSY,7951
|
|
7
7
|
yaralyzer/decoding/decoding_attempt.py,sha256=GAxMNOX7I_FsuzGWIelTWAECytLUJD-wpmUAuVe2bn0,7241
|
|
@@ -14,17 +14,17 @@ yaralyzer/helpers/file_helper.py,sha256=uf8dTOhRrJng0V36o7Mwk5t-L5gc4_uOaGj9F0s5
|
|
|
14
14
|
yaralyzer/helpers/rich_text_helper.py,sha256=9Wc6WM625iKxAXRvxBkVzvszfcxb8YtqoQ6d7d8EqoQ,4218
|
|
15
15
|
yaralyzer/helpers/string_helper.py,sha256=AT2_CAgpvtp8GiUSKLTiDoToDD3tBB9BbrlX-s2bL7o,932
|
|
16
16
|
yaralyzer/output/decoding_attempts_table.py,sha256=cMY9eCXZHj0FfGxJ9uoM5cpdhQve-EtTRHv3fTHKJAo,3712
|
|
17
|
-
yaralyzer/output/file_export.py,sha256=
|
|
17
|
+
yaralyzer/output/file_export.py,sha256=YfF5D8aHOUQHwV0akFaaSMafbhdhUakvipadpq6HZmk,2927
|
|
18
18
|
yaralyzer/output/file_hashes_table.py,sha256=SnS2ip8dSeHoycQ0Ng3Gtpv9rXJSkKnvD2krTuhNg7s,1632
|
|
19
19
|
yaralyzer/output/regex_match_metrics.py,sha256=deJPaVnhpy-AUX6PCE_jbPLIlmfIOtl-cEVWsiFp3KY,3003
|
|
20
20
|
yaralyzer/output/rich_console.py,sha256=Botb8aec4_aRiPyaEkwrnhwERHE8a5-lk5KfgzXVlBE,4202
|
|
21
|
-
yaralyzer/util/argument_parser.py,sha256=
|
|
21
|
+
yaralyzer/util/argument_parser.py,sha256=cVUe3lQCb6iFnP5leE-C0OeXkBPomw55Xi1MiD1Gl50,12776
|
|
22
22
|
yaralyzer/util/logging.py,sha256=3qtLnCFbN8L1nTSwIQvxfcM5jfhIRWTFZj9XGQk74kc,4326
|
|
23
|
-
yaralyzer/yara/yara_match.py,sha256=
|
|
23
|
+
yaralyzer/yara/yara_match.py,sha256=4_26eaJT9I0PULiCdxerQtX4TfAIwcT-B6GJociGM9A,5119
|
|
24
24
|
yaralyzer/yara/yara_rule_builder.py,sha256=kAa3RBojM5GEaXDJjKZODAyx6yj34AlkOnQhACAFfZM,3021
|
|
25
25
|
yaralyzer/yaralyzer.py,sha256=f1y8qST6GZHEWl7nDNEBWpQuYjnsJ8dm9nGPWqZ4Hkk,9417
|
|
26
|
-
yaralyzer-0.
|
|
27
|
-
yaralyzer-0.
|
|
28
|
-
yaralyzer-0.
|
|
29
|
-
yaralyzer-0.
|
|
30
|
-
yaralyzer-0.
|
|
26
|
+
yaralyzer-1.0.0.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
27
|
+
yaralyzer-1.0.0.dist-info/METADATA,sha256=HfE-vyCyOUs_QyM7saQAU9b4hiS9poBxuwLuFf8jsNM,10795
|
|
28
|
+
yaralyzer-1.0.0.dist-info/WHEEL,sha256=d2fvjOD7sXsVzChCqf0Ty0JbHKBaLYwDbGQDwQTnJ50,88
|
|
29
|
+
yaralyzer-1.0.0.dist-info/entry_points.txt,sha256=7LnLJrNTfql0vuctjRWwp_ZD-BYvtv9ENVipdjuT7XI,136
|
|
30
|
+
yaralyzer-1.0.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|