maco 1.2.9__tar.gz → 1.2.11__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.
Files changed (67) hide show
  1. {maco-1.2.9/maco.egg-info → maco-1.2.11}/PKG-INFO +2 -2
  2. {maco-1.2.9/model_setup → maco-1.2.11}/maco/cli.py +10 -1
  3. {maco-1.2.9 → maco-1.2.11}/maco/collector.py +2 -0
  4. {maco-1.2.9 → maco-1.2.11}/maco/utils.py +19 -9
  5. {maco-1.2.9 → maco-1.2.11/maco.egg-info}/PKG-INFO +2 -2
  6. {maco-1.2.9 → maco-1.2.11/model_setup}/maco/cli.py +10 -1
  7. {maco-1.2.9 → maco-1.2.11}/model_setup/maco/collector.py +2 -0
  8. {maco-1.2.9 → maco-1.2.11}/model_setup/maco/utils.py +19 -9
  9. {maco-1.2.9 → maco-1.2.11}/.gitignore +0 -0
  10. {maco-1.2.9 → maco-1.2.11}/.vscode/settings.json +0 -0
  11. {maco-1.2.9 → maco-1.2.11}/LICENSE.md +0 -0
  12. {maco-1.2.9 → maco-1.2.11}/README.md +0 -0
  13. {maco-1.2.9 → maco-1.2.11}/demo_extractors/__init__.py +0 -0
  14. {maco-1.2.9 → maco-1.2.11}/demo_extractors/complex/__init__.py +0 -0
  15. {maco-1.2.9 → maco-1.2.11}/demo_extractors/complex/complex.py +0 -0
  16. {maco-1.2.9 → maco-1.2.11}/demo_extractors/complex/complex_utils.py +0 -0
  17. {maco-1.2.9 → maco-1.2.11}/demo_extractors/elfy.py +0 -0
  18. {maco-1.2.9 → maco-1.2.11}/demo_extractors/limit_other.py +0 -0
  19. {maco-1.2.9 → maco-1.2.11}/demo_extractors/nothing.py +0 -0
  20. {maco-1.2.9 → maco-1.2.11}/demo_extractors/requirements.txt +0 -0
  21. {maco-1.2.9 → maco-1.2.11}/demo_extractors/shared.py +0 -0
  22. {maco-1.2.9 → maco-1.2.11}/maco/__init__.py +0 -0
  23. {maco-1.2.9 → maco-1.2.11}/maco/base_test.py +0 -0
  24. {maco-1.2.9 → maco-1.2.11}/maco/extractor.py +0 -0
  25. {maco-1.2.9 → maco-1.2.11}/maco/model/__init__.py +0 -0
  26. {maco-1.2.9 → maco-1.2.11}/maco/model/model.py +0 -0
  27. {maco-1.2.9 → maco-1.2.11}/maco/yara.py +0 -0
  28. {maco-1.2.9 → maco-1.2.11}/maco.egg-info/SOURCES.txt +0 -0
  29. {maco-1.2.9 → maco-1.2.11}/maco.egg-info/dependency_links.txt +0 -0
  30. {maco-1.2.9 → maco-1.2.11}/maco.egg-info/entry_points.txt +0 -0
  31. {maco-1.2.9 → maco-1.2.11}/maco.egg-info/requires.txt +0 -0
  32. {maco-1.2.9 → maco-1.2.11}/maco.egg-info/top_level.txt +0 -0
  33. {maco-1.2.9 → maco-1.2.11}/model_setup/LICENSE.md +0 -0
  34. {maco-1.2.9 → maco-1.2.11}/model_setup/README.md +0 -0
  35. {maco-1.2.9 → maco-1.2.11}/model_setup/maco/__init__.py +0 -0
  36. {maco-1.2.9 → maco-1.2.11}/model_setup/maco/base_test.py +0 -0
  37. {maco-1.2.9 → maco-1.2.11}/model_setup/maco/extractor.py +0 -0
  38. {maco-1.2.9 → maco-1.2.11}/model_setup/maco/model/__init__.py +0 -0
  39. {maco-1.2.9 → maco-1.2.11}/model_setup/maco/model/model.py +0 -0
  40. {maco-1.2.9 → maco-1.2.11}/model_setup/maco/yara.py +0 -0
  41. {maco-1.2.9 → maco-1.2.11}/model_setup/pyproject.toml +0 -0
  42. {maco-1.2.9 → maco-1.2.11}/model_setup/setup.py +0 -0
  43. {maco-1.2.9 → maco-1.2.11}/pipelines/publish.yaml +0 -0
  44. {maco-1.2.9 → maco-1.2.11}/pipelines/test.yaml +0 -0
  45. {maco-1.2.9 → maco-1.2.11}/pyproject.toml +0 -0
  46. {maco-1.2.9 → maco-1.2.11}/requirements.txt +0 -0
  47. {maco-1.2.9 → maco-1.2.11}/setup.cfg +0 -0
  48. {maco-1.2.9 → maco-1.2.11}/tests/benchmark.py +0 -0
  49. {maco-1.2.9 → maco-1.2.11}/tests/data/example.txt.cart +0 -0
  50. {maco-1.2.9 → maco-1.2.11}/tests/data/trigger_complex.txt +0 -0
  51. {maco-1.2.9 → maco-1.2.11}/tests/data/trigger_complex.txt.cart +0 -0
  52. {maco-1.2.9 → maco-1.2.11}/tests/extractors/__init__.py +0 -0
  53. {maco-1.2.9 → maco-1.2.11}/tests/extractors/basic.py +0 -0
  54. {maco-1.2.9 → maco-1.2.11}/tests/extractors/basic_longer.py +0 -0
  55. {maco-1.2.9 → maco-1.2.11}/tests/extractors/bob/__init__.py +0 -0
  56. {maco-1.2.9 → maco-1.2.11}/tests/extractors/bob/bob.py +0 -0
  57. {maco-1.2.9 → maco-1.2.11}/tests/extractors/test_basic.py +0 -0
  58. {maco-1.2.9 → maco-1.2.11}/tests/pytest.ini +0 -0
  59. {maco-1.2.9 → maco-1.2.11}/tests/requirements.txt +0 -0
  60. {maco-1.2.9 → maco-1.2.11}/tests/test_base_test.py +0 -0
  61. {maco-1.2.9 → maco-1.2.11}/tests/test_cli.py +0 -0
  62. {maco-1.2.9 → maco-1.2.11}/tests/test_demo_extractors.py +0 -0
  63. {maco-1.2.9 → maco-1.2.11}/tests/test_detection.py +0 -0
  64. {maco-1.2.9 → maco-1.2.11}/tests/test_extractor.py +0 -0
  65. {maco-1.2.9 → maco-1.2.11}/tests/test_helpers.py +0 -0
  66. {maco-1.2.9 → maco-1.2.11}/tests/test_model.py +0 -0
  67. {maco-1.2.9 → maco-1.2.11}/tox.ini +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: maco
3
- Version: 1.2.9
3
+ Version: 1.2.11
4
4
  Author: sl-govau
5
5
  Maintainer: cccs-rs
6
6
  License: MIT License
@@ -92,6 +92,7 @@ def process_filesystem(
92
92
  force: bool,
93
93
  include_base64: bool,
94
94
  create_venv: bool = False,
95
+ skip_install: bool = False,
95
96
  ) -> Tuple[int, int, int]:
96
97
  """Process filesystem with extractors and print results of extraction.
97
98
 
@@ -99,7 +100,9 @@ def process_filesystem(
99
100
  """
100
101
  if force:
101
102
  logger.warning("force execute will cause errors if an extractor requires a yara rule hit during execution")
102
- collected = collector.Collector(path_extractors, include=include, exclude=exclude, create_venv=create_venv)
103
+ collected = collector.Collector(
104
+ path_extractors, include=include, exclude=exclude, create_venv=create_venv, skip_install=skip_install
105
+ )
103
106
 
104
107
  logger.info(f"extractors loaded: {[x for x in collected.extractors.keys()]}\n")
105
108
  for _, extractor in collected.extractors.items():
@@ -191,6 +194,11 @@ def main():
191
194
  "This runs much slower than the alternative but may be necessary "
192
195
  "when there are many extractors with conflicting dependencies.",
193
196
  )
197
+ parser.add_argument(
198
+ "--force_install",
199
+ action="store_true",
200
+ help="Force installation of Python dependencies for extractors (in both host and virtual environments).",
201
+ )
194
202
  args = parser.parse_args()
195
203
  inc = args.include.split(",") if args.include else []
196
204
  exc = args.exclude.split(",") if args.exclude else []
@@ -236,6 +244,7 @@ def main():
236
244
  force=args.force,
237
245
  include_base64=args.base64,
238
246
  create_venv=args.create_venv,
247
+ skip_install=not args.force_install,
239
248
  )
240
249
 
241
250
 
@@ -67,6 +67,7 @@ class Collector:
67
67
  include: List[str] = None,
68
68
  exclude: List[str] = None,
69
69
  create_venv: bool = False,
70
+ skip_install: bool = False,
70
71
  ):
71
72
  """Discover and load extractors from file system."""
72
73
  # maco requires the extractor to be imported directly, so ensure they are available on the path
@@ -135,6 +136,7 @@ class Collector:
135
136
  root_directory=path_extractors,
136
137
  scanner=yara.compile(source=utils.MACO_YARA_RULE),
137
138
  create_venv=create_venv and os.path.isdir(path_extractors),
139
+ skip_install=skip_install,
138
140
  ),
139
141
  )
140
142
  p.start()
@@ -39,8 +39,8 @@ logger = logging.getLogger("maco.lib.utils")
39
39
 
40
40
  VENV_DIRECTORY_NAME = ".venv"
41
41
 
42
- RELATIVE_FROM_RE = re.compile(r"from (\.+)")
43
- RELATIVE_FROM_IMPORT_RE = re.compile(r"from (\.+) import")
42
+ RELATIVE_FROM_RE = re.compile(rb"from (\.+)")
43
+ RELATIVE_FROM_IMPORT_RE = re.compile(rb"from (\.+) import")
44
44
 
45
45
  UV_BIN = find_uv_bin()
46
46
 
@@ -171,19 +171,19 @@ def scan_for_extractors(root_directory: str, scanner: yara.Rules, logger: Logger
171
171
  # Scan Python file for potential extractors
172
172
  if package:
173
173
  # Inspect the contents and look for any relative import issues
174
- with open(path, "r") as f:
174
+ with open(path, "rb") as f:
175
175
  data = f.read()
176
176
 
177
- with open(path, "w") as f:
177
+ with open(path, "wb") as f:
178
178
  # Replace any relative importing with absolute
179
179
  curr_dir = os.path.dirname(path)
180
180
  split = curr_dir.split("/")[::-1]
181
181
  for pattern in [RELATIVE_FROM_IMPORT_RE, RELATIVE_FROM_RE]:
182
182
  for match in pattern.findall(data):
183
- depth = match.count(".")
183
+ depth = match.count(b".")
184
184
  abspath = ".".join(split[depth - 1 : split.index(package) + 1][::-1])
185
185
  abspath += "." if pattern == RELATIVE_FROM_RE else ""
186
- data = data.replace(f"from {match}", f"from {abspath}", 1)
186
+ data = data.replace(f"from {match.decode()}".encode(), f"from {abspath}".encode(), 1)
187
187
  f.write(data)
188
188
 
189
189
  if scanner.match(path):
@@ -450,9 +450,19 @@ def run_extractor(
450
450
  key = f"{module_name}_{extractor_class}"
451
451
  if key not in _loaded_extractors:
452
452
  # dynamic import of extractor
453
- mod = importlib.import_module(module_name)
454
- extractor_cls = mod.__getattribute__(extractor_class)
455
- extractor = extractor_cls()
453
+ try:
454
+ # Add the correct directory to the PATH before attempting to load the extractor
455
+ import_path = module_path[: -4 - len(module_name)]
456
+ sys.path.insert(1, import_path)
457
+ mod = importlib.import_module(module_name)
458
+ extractor_cls = mod.__getattribute__(extractor_class)
459
+ extractor = extractor_cls()
460
+
461
+ # Add to cache
462
+ _loaded_extractors[key] = extractor
463
+ finally:
464
+ sys.path.pop(1)
465
+
456
466
  else:
457
467
  # retrieve cached extractor
458
468
  extractor = _loaded_extractors[key]
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: maco
3
- Version: 1.2.9
3
+ Version: 1.2.11
4
4
  Author: sl-govau
5
5
  Maintainer: cccs-rs
6
6
  License: MIT License
@@ -92,6 +92,7 @@ def process_filesystem(
92
92
  force: bool,
93
93
  include_base64: bool,
94
94
  create_venv: bool = False,
95
+ skip_install: bool = False,
95
96
  ) -> Tuple[int, int, int]:
96
97
  """Process filesystem with extractors and print results of extraction.
97
98
 
@@ -99,7 +100,9 @@ def process_filesystem(
99
100
  """
100
101
  if force:
101
102
  logger.warning("force execute will cause errors if an extractor requires a yara rule hit during execution")
102
- collected = collector.Collector(path_extractors, include=include, exclude=exclude, create_venv=create_venv)
103
+ collected = collector.Collector(
104
+ path_extractors, include=include, exclude=exclude, create_venv=create_venv, skip_install=skip_install
105
+ )
103
106
 
104
107
  logger.info(f"extractors loaded: {[x for x in collected.extractors.keys()]}\n")
105
108
  for _, extractor in collected.extractors.items():
@@ -191,6 +194,11 @@ def main():
191
194
  "This runs much slower than the alternative but may be necessary "
192
195
  "when there are many extractors with conflicting dependencies.",
193
196
  )
197
+ parser.add_argument(
198
+ "--force_install",
199
+ action="store_true",
200
+ help="Force installation of Python dependencies for extractors (in both host and virtual environments).",
201
+ )
194
202
  args = parser.parse_args()
195
203
  inc = args.include.split(",") if args.include else []
196
204
  exc = args.exclude.split(",") if args.exclude else []
@@ -236,6 +244,7 @@ def main():
236
244
  force=args.force,
237
245
  include_base64=args.base64,
238
246
  create_venv=args.create_venv,
247
+ skip_install=not args.force_install,
239
248
  )
240
249
 
241
250
 
@@ -67,6 +67,7 @@ class Collector:
67
67
  include: List[str] = None,
68
68
  exclude: List[str] = None,
69
69
  create_venv: bool = False,
70
+ skip_install: bool = False,
70
71
  ):
71
72
  """Discover and load extractors from file system."""
72
73
  # maco requires the extractor to be imported directly, so ensure they are available on the path
@@ -135,6 +136,7 @@ class Collector:
135
136
  root_directory=path_extractors,
136
137
  scanner=yara.compile(source=utils.MACO_YARA_RULE),
137
138
  create_venv=create_venv and os.path.isdir(path_extractors),
139
+ skip_install=skip_install,
138
140
  ),
139
141
  )
140
142
  p.start()
@@ -39,8 +39,8 @@ logger = logging.getLogger("maco.lib.utils")
39
39
 
40
40
  VENV_DIRECTORY_NAME = ".venv"
41
41
 
42
- RELATIVE_FROM_RE = re.compile(r"from (\.+)")
43
- RELATIVE_FROM_IMPORT_RE = re.compile(r"from (\.+) import")
42
+ RELATIVE_FROM_RE = re.compile(rb"from (\.+)")
43
+ RELATIVE_FROM_IMPORT_RE = re.compile(rb"from (\.+) import")
44
44
 
45
45
  UV_BIN = find_uv_bin()
46
46
 
@@ -171,19 +171,19 @@ def scan_for_extractors(root_directory: str, scanner: yara.Rules, logger: Logger
171
171
  # Scan Python file for potential extractors
172
172
  if package:
173
173
  # Inspect the contents and look for any relative import issues
174
- with open(path, "r") as f:
174
+ with open(path, "rb") as f:
175
175
  data = f.read()
176
176
 
177
- with open(path, "w") as f:
177
+ with open(path, "wb") as f:
178
178
  # Replace any relative importing with absolute
179
179
  curr_dir = os.path.dirname(path)
180
180
  split = curr_dir.split("/")[::-1]
181
181
  for pattern in [RELATIVE_FROM_IMPORT_RE, RELATIVE_FROM_RE]:
182
182
  for match in pattern.findall(data):
183
- depth = match.count(".")
183
+ depth = match.count(b".")
184
184
  abspath = ".".join(split[depth - 1 : split.index(package) + 1][::-1])
185
185
  abspath += "." if pattern == RELATIVE_FROM_RE else ""
186
- data = data.replace(f"from {match}", f"from {abspath}", 1)
186
+ data = data.replace(f"from {match.decode()}".encode(), f"from {abspath}".encode(), 1)
187
187
  f.write(data)
188
188
 
189
189
  if scanner.match(path):
@@ -450,9 +450,19 @@ def run_extractor(
450
450
  key = f"{module_name}_{extractor_class}"
451
451
  if key not in _loaded_extractors:
452
452
  # dynamic import of extractor
453
- mod = importlib.import_module(module_name)
454
- extractor_cls = mod.__getattribute__(extractor_class)
455
- extractor = extractor_cls()
453
+ try:
454
+ # Add the correct directory to the PATH before attempting to load the extractor
455
+ import_path = module_path[: -4 - len(module_name)]
456
+ sys.path.insert(1, import_path)
457
+ mod = importlib.import_module(module_name)
458
+ extractor_cls = mod.__getattribute__(extractor_class)
459
+ extractor = extractor_cls()
460
+
461
+ # Add to cache
462
+ _loaded_extractors[key] = extractor
463
+ finally:
464
+ sys.path.pop(1)
465
+
456
466
  else:
457
467
  # retrieve cached extractor
458
468
  extractor = _loaded_extractors[key]
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes