yaralyzer 0.9.4__tar.gz → 0.9.6__tar.gz

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.

Files changed (29) hide show
  1. {yaralyzer-0.9.4 → yaralyzer-0.9.6}/.yaralyzer.example +5 -7
  2. {yaralyzer-0.9.4 → yaralyzer-0.9.6}/CHANGELOG.md +7 -0
  3. {yaralyzer-0.9.4 → yaralyzer-0.9.6}/PKG-INFO +2 -2
  4. {yaralyzer-0.9.4 → yaralyzer-0.9.6}/README.md +1 -1
  5. {yaralyzer-0.9.4 → yaralyzer-0.9.6}/pyproject.toml +1 -1
  6. {yaralyzer-0.9.4 → yaralyzer-0.9.6}/yaralyzer/encoding_detection/encoding_detector.py +2 -1
  7. {yaralyzer-0.9.4 → yaralyzer-0.9.6}/yaralyzer/helpers/bytes_helper.py +3 -2
  8. {yaralyzer-0.9.4 → yaralyzer-0.9.6}/yaralyzer/helpers/file_helper.py +4 -1
  9. {yaralyzer-0.9.4 → yaralyzer-0.9.6}/yaralyzer/helpers/string_helper.py +3 -0
  10. {yaralyzer-0.9.4 → yaralyzer-0.9.6}/yaralyzer/output/file_hashes_table.py +1 -1
  11. {yaralyzer-0.9.4 → yaralyzer-0.9.6}/yaralyzer/output/rich_console.py +17 -0
  12. {yaralyzer-0.9.4 → yaralyzer-0.9.6}/yaralyzer/util/argument_parser.py +3 -3
  13. {yaralyzer-0.9.4 → yaralyzer-0.9.6}/yaralyzer/yaralyzer.py +9 -4
  14. {yaralyzer-0.9.4 → yaralyzer-0.9.6}/LICENSE +0 -0
  15. {yaralyzer-0.9.4 → yaralyzer-0.9.6}/yaralyzer/__init__.py +0 -0
  16. {yaralyzer-0.9.4 → yaralyzer-0.9.6}/yaralyzer/bytes_match.py +0 -0
  17. {yaralyzer-0.9.4 → yaralyzer-0.9.6}/yaralyzer/config.py +0 -0
  18. {yaralyzer-0.9.4 → yaralyzer-0.9.6}/yaralyzer/decoding/bytes_decoder.py +0 -0
  19. {yaralyzer-0.9.4 → yaralyzer-0.9.6}/yaralyzer/decoding/decoding_attempt.py +0 -0
  20. {yaralyzer-0.9.4 → yaralyzer-0.9.6}/yaralyzer/encoding_detection/character_encodings.py +0 -0
  21. {yaralyzer-0.9.4 → yaralyzer-0.9.6}/yaralyzer/encoding_detection/encoding_assessment.py +0 -0
  22. {yaralyzer-0.9.4 → yaralyzer-0.9.6}/yaralyzer/helpers/dict_helper.py +0 -0
  23. {yaralyzer-0.9.4 → yaralyzer-0.9.6}/yaralyzer/helpers/rich_text_helper.py +0 -0
  24. {yaralyzer-0.9.4 → yaralyzer-0.9.6}/yaralyzer/output/decoding_attempts_table.py +0 -0
  25. {yaralyzer-0.9.4 → yaralyzer-0.9.6}/yaralyzer/output/file_export.py +1 -1
  26. {yaralyzer-0.9.4 → yaralyzer-0.9.6}/yaralyzer/output/regex_match_metrics.py +0 -0
  27. {yaralyzer-0.9.4 → yaralyzer-0.9.6}/yaralyzer/util/logging.py +0 -0
  28. {yaralyzer-0.9.4 → yaralyzer-0.9.6}/yaralyzer/yara/yara_match.py +0 -0
  29. {yaralyzer-0.9.4 → yaralyzer-0.9.6}/yaralyzer/yara/yara_rule_builder.py +0 -0
@@ -9,10 +9,11 @@
9
9
  # YARALYZER_MAXIMIZE_WIDTH=True
10
10
 
11
11
 
12
+
12
13
  # Expand the width of the output to the fit the display window (same as the --maximize-width options)
13
14
  # YARALYZER_MAXIMIZE_WIDTH=True
14
15
 
15
- # Passed through to yara.set_config() as the stack_size and max_match_data arguments
16
+ # yara-python internal options passed through to yara.set_config() as the stack_size and max_match_data arguments
16
17
  # YARALYZER_STACK_SIZE=10485760
17
18
  # YARALYZER_MAX_MATCH_LENGTH=10737418240
18
19
 
@@ -27,7 +28,7 @@
27
28
  # YARALYZER_MIN_CHARDET_CONFIDENCE=2.0
28
29
 
29
30
  # Configure how many bytes before and after any binary data should be included in scans and visualizations
30
- # PDFAlYZER_SURROUNDING_BYTES=64
31
+ # YARALYZER_SURROUNDING_BYTES=64
31
32
 
32
33
  # Size thresholds (in bytes) under/over which yaralyzer will NOT make attempts to decode a match.
33
34
  # Longer byte sequences are for obvious reasons slower to decode by force.
@@ -35,8 +36,8 @@
35
36
  # (in my experience) less likely to be maningful. Consider it - two frontslash characters 20,000 lines apart
36
37
  # are more likely to be random than those same frontslashes when placed nearer to each other and
37
38
  # in the vicinity of lot of computerized sigils of internet power like `.', `+bacd*?`,. and other regexes.*
38
- # Keeping the max value number low will do more to affect the speed of the app than ay anything else you
39
- # can easily configure..
39
+ # Keeping the max value number low will do more to affect the speed of the app than anything else you
40
+ # can easily configure.
40
41
  #
41
42
  # YARALYZER_MIN_DECODE_LENGTH=1
42
43
  # YARALYZER_MAX_DECODE_LENGTH=256
@@ -58,6 +59,3 @@
58
59
 
59
60
  # Log level
60
61
  # YARALYZER_LOG_LEVEL='WARN'
61
-
62
- # Path to directory containing Didier Stevens's pdf-parser.py. Only required for extracting binary streams to files.
63
- # YARALYZER_PDF_PARSER_PY_PATH=/path/to/pdfparserdotpy/
@@ -1,5 +1,12 @@
1
1
  # NEXT RELEASE
2
2
 
3
+ ### 0.9.6
4
+ * Fix help message
5
+
6
+ ### 0.9.5
7
+ * Use all files in a directory specified by `--rule-dir` instead of just those with the extension `.yara`
8
+ * Fix bug where `--rule-dir` is prefixed by `./`
9
+
3
10
  ### 0.9.4
4
11
  * Bump `yara-python` to 4.3.0+ and deal with backwards incompatibility
5
12
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: yaralyzer
3
- Version: 0.9.4
3
+ Version: 0.9.6
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
@@ -131,7 +131,7 @@ The Yaralyzer can export visualizations to HTML, ANSI colored text, and SVG vect
131
131
 
132
132
 
133
133
  # TODO
134
- * For some reason when displaying matches the output to a file iterates over all matches in a different way than just running in the console. Presumably this is related to the `rich` rendering engine in some way. For now the console output is the "more correct" one so it's generally OK. See [`issue_with_output_to_console_correct`](doc/rendered_images/issue_with_output_to_console_correct.png) vs. [`doc/rendered_images/issue_with_output_to_txt_file_incorrect.png`](doc/rendered_images/issue_with_output_to_txt_file_incorrect.png)
134
+ * For some reason when displaying matches the output to a file iterates over all matches in a different way than just running in the console. Presumably this is related to the `rich` rendering engine in some way. For now the console output is the "more correct" one so it's generally OK. See [`issue_with_output_to_console_correct`](doc/rendered_images/issue_with_output_to_console_correct.png) vs. [`issue_with_output_to_txt_file_incorrect.png`](doc/rendered_images/issue_with_output_to_txt_file_incorrect.png)
135
135
  * highlight decodes done at `chardet`s behest
136
136
  * deal with repetitive matches
137
137
 
@@ -105,7 +105,7 @@ The Yaralyzer can export visualizations to HTML, ANSI colored text, and SVG vect
105
105
 
106
106
 
107
107
  # TODO
108
- * For some reason when displaying matches the output to a file iterates over all matches in a different way than just running in the console. Presumably this is related to the `rich` rendering engine in some way. For now the console output is the "more correct" one so it's generally OK. See [`issue_with_output_to_console_correct`](doc/rendered_images/issue_with_output_to_console_correct.png) vs. [`doc/rendered_images/issue_with_output_to_txt_file_incorrect.png`](doc/rendered_images/issue_with_output_to_txt_file_incorrect.png)
108
+ * For some reason when displaying matches the output to a file iterates over all matches in a different way than just running in the console. Presumably this is related to the `rich` rendering engine in some way. For now the console output is the "more correct" one so it's generally OK. See [`issue_with_output_to_console_correct`](doc/rendered_images/issue_with_output_to_console_correct.png) vs. [`issue_with_output_to_txt_file_incorrect.png`](doc/rendered_images/issue_with_output_to_txt_file_incorrect.png)
109
109
  * highlight decodes done at `chardet`s behest
110
110
  * deal with repetitive matches
111
111
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "yaralyzer"
3
- version = "0.9.4"
3
+ version = "0.9.6"
4
4
  description = "Visualize and force decode YARA and regex matches found in a file or byte stream. With colors. Lots of colors."
5
5
  authors = ["Michel de Cryptadamus <michel@cryptadamus.com>"]
6
6
  readme = "README.md"
@@ -1,6 +1,6 @@
1
1
  """
2
2
  Manager class to ease dealing with the chardet encoding detection library 'chardet'.
3
- Each instance of this classes managed a chardet.detect_all() scan on a single set of bytes.
3
+ Each instance of this class manages a chardet.detect_all() scan on a single set of bytes.
4
4
  """
5
5
  from operator import attrgetter
6
6
  from typing import List
@@ -30,6 +30,7 @@ class EncodingDetector:
30
30
  self.bytes_len = len(_bytes)
31
31
  self.table = _empty_chardet_results_table()
32
32
 
33
+ # Skip chardet if there's not enough bytes available
33
34
  if not self.has_enough_bytes():
34
35
  log.debug(f"{self.bytes_len} is not enough bytes to run chardet.detect()")
35
36
  self._set_empty_results()
@@ -1,6 +1,7 @@
1
- import hashlib
1
+ """
2
+ Helper methods to work with bytes.
3
+ """
2
4
  import re
3
- from collections import namedtuple
4
5
  from io import StringIO
5
6
  from sys import byteorder
6
7
 
@@ -1,3 +1,6 @@
1
+ """
2
+ Helper methods to work with files.
3
+ """
1
4
  from datetime import datetime
2
5
  from os import listdir, path
3
6
  from typing import List, Optional
@@ -10,7 +13,7 @@ def timestamp_for_filename() -> str:
10
13
 
11
14
  def files_in_dir(dir: str, with_extname: Optional[str] = None) -> List[str]:
12
15
  """paths for non dot files, optionally ending in 'with_extname'"""
13
- files = [path.join(dir, file) for file in listdir(dir) if not file.startswith('.')]
16
+ files = [path.join(dir, path.basename(file)) for file in listdir(dir) if not file.startswith('.')]
14
17
  files = [file for file in files if not path.isdir(file)]
15
18
 
16
19
  if with_extname:
@@ -1,3 +1,6 @@
1
+ """
2
+ Helper methods to work with strings.
3
+ """
1
4
  from functools import partial
2
5
  from typing import Any, Callable, List
3
6
 
@@ -1,5 +1,5 @@
1
1
  """
2
- Methods for building Rich layout elements
2
+ Methods for building Rich layout elements for display of results.
3
3
  """
4
4
  import hashlib
5
5
  from collections import namedtuple
@@ -1,8 +1,14 @@
1
+ """
2
+ Variables and methods for working with Rich text output.
3
+ """
1
4
  from shutil import get_terminal_size
5
+ from sys import exit
2
6
  from typing import List
3
7
 
8
+ from rich import box
4
9
  from rich.console import Console
5
10
  from rich.errors import MarkupError
11
+ from rich.panel import Panel
6
12
  from rich.style import Style
7
13
  from rich.text import Text
8
14
  from rich.theme import Theme
@@ -107,3 +113,14 @@ def console_print_with_fallback(_string, style=None) -> None:
107
113
 
108
114
  def theme_colors_with_prefix(prefix: str) -> List[Text]:
109
115
  return [Text(k, v) for k, v in YARALYZER_THEME.styles.items() if k.startswith(prefix)]
116
+
117
+
118
+ def print_fatal_error_and_exit(error_message: str) -> None:
119
+ console.line(1)
120
+ print_header_panel(error_message, style='bold red reverse')
121
+ console.line(1)
122
+ exit()
123
+
124
+
125
+ def print_header_panel(headline: str, style: str, expand: bool = True, padding: tuple = (0,2)) -> None:
126
+ console.print(Panel(headline, box=box.DOUBLE_EDGE, style=style, expand=expand, padding=padding))
@@ -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
- "'{YaralyzerConfig.LOG_DIR_ENV_VAR}' environment variable is configured."
32
+ f"{YaralyzerConfig.LOG_DIR_ENV_VAR} environment variable is configured."
33
33
 
34
34
 
35
35
  # Positional args, version, help, etc
@@ -49,7 +49,7 @@ source.add_argument('--yara-file', '-Y',
49
49
  dest='yara_rules_files')
50
50
 
51
51
  source.add_argument('--rule-dir', '-dir',
52
- help='directory with .yara files (can be supplied more than once)',
52
+ help='directory with yara rules files (all files are used, can be supplied more than once)',
53
53
  action='append',
54
54
  metavar='DIR',
55
55
  dest='yara_rules_dirs')
@@ -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 decodes attempts for matched bytes (only hex/raw output will be shown)')
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',
@@ -9,6 +9,7 @@ Alternate constructors are provided depending on whether:
9
9
  The real action happens in the __rich__console__() dunder method.
10
10
  """
11
11
  from os import path
12
+ from sys import exit
12
13
  from typing import Iterator, List, Optional, Tuple, Union
13
14
 
14
15
  import yara
@@ -23,13 +24,12 @@ from yaralyzer.helpers.file_helper import files_in_dir, load_binary_data
23
24
  from yaralyzer.helpers.rich_text_helper import dim_if, reverse_color
24
25
  from yaralyzer.helpers.string_helper import comma_join, newline_join
25
26
  from yaralyzer.output.regex_match_metrics import RegexMatchMetrics
26
- from yaralyzer.output.rich_console import YARALYZER_THEME, console
27
+ from yaralyzer.output.rich_console import YARALYZER_THEME, console, print_fatal_error_and_exit
27
28
  from yaralyzer.output.file_hashes_table import bytes_hashes_table
28
29
  from yaralyzer.util.logging import log
29
30
  from yaralyzer.yara.yara_match import YaraMatch
30
31
  from yaralyzer.yara.yara_rule_builder import yara_rule_string
31
32
 
32
- YARA_EXT = 'yara'
33
33
  YARA_FILE_DOES_NOT_EXIST_ERROR_MSG = "is not a valid yara rules file (it doesn't exist)"
34
34
 
35
35
 
@@ -97,7 +97,12 @@ class Yaralyzer:
97
97
  raise ValueError(f"'{file}' {YARA_FILE_DOES_NOT_EXIST_ERROR_MSG}")
98
98
 
99
99
  filepaths_arg = {path.basename(file): file for file in yara_rules_files}
100
- yara_rules = yara.compile(filepaths=filepaths_arg)
100
+
101
+ try:
102
+ yara_rules = yara.compile(filepaths=filepaths_arg)
103
+ except yara.SyntaxError as e:
104
+ print_fatal_error_and_exit(f"Failed to parse YARA rules file(s): {e}")
105
+
101
106
  yara_rules_label = comma_join(yara_rules_files, func=path.basename)
102
107
  return cls(yara_rules, yara_rules_label, scannable, scannable_label)
103
108
 
@@ -112,7 +117,7 @@ class Yaralyzer:
112
117
  if not (isinstance(dirs, list) and all(path.isdir(dir) for dir in dirs)):
113
118
  raise TypeError(f"'{dirs}' is not a list of valid directories")
114
119
 
115
- rules_files = [path.join(dir, f) for dir in dirs for f in files_in_dir(dir, YARA_EXT)]
120
+ rules_files = [path.join(dir, f) for dir in dirs for f in files_in_dir(dir)]
116
121
  return cls.for_rules_files(rules_files, scannable, scannable_label)
117
122
 
118
123
  @classmethod
File without changes
File without changes
@@ -46,6 +46,7 @@ _EXPORT_KWARGS = {
46
46
  },
47
47
  }
48
48
 
49
+
49
50
  def invoke_rich_export(export_method, output_file_basepath) -> str:
50
51
  """
51
52
  Announce the export, perform the export, announce completion.
@@ -72,4 +73,3 @@ def invoke_rich_export(export_method, output_file_basepath) -> str:
72
73
  elapsed_time = time.perf_counter() - start_time
73
74
  log_and_print(f"'{output_file_path}' written in {elapsed_time:02f} seconds")
74
75
  return output_file_path
75
-