maco 1.2.11__py3-none-any.whl → 1.2.12__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.
@@ -1 +1,4 @@
1
1
  httpx
2
+
3
+ # Install maco from source for testing
4
+ ../
@@ -0,0 +1,17 @@
1
+ from io import BytesIO
2
+ from typing import List, Optional
3
+
4
+ from maco import extractor, model, yara
5
+ from maco.exceptions import AnalysisAbortedException
6
+
7
+
8
+ class Terminator(extractor.Extractor):
9
+ """Terminates early during extraction"""
10
+
11
+ family = "terminator"
12
+ author = "skynet"
13
+ last_modified = "1997-08-29"
14
+
15
+ def run(self, stream: BytesIO, matches: List[yara.Match]) -> Optional[model.ExtractorModel]:
16
+ # Terminate early and indicate I can't run on this sample
17
+ raise AnalysisAbortedException("I can't run on this sample")
maco/cli.py CHANGED
@@ -3,18 +3,20 @@
3
3
  import argparse
4
4
  import base64
5
5
  import binascii
6
+ import cart
6
7
  import hashlib
7
8
  import io
8
9
  import json
9
10
  import logging
10
11
  import os
11
12
  import sys
12
- from typing import BinaryIO, List, Tuple
13
13
 
14
- import cart
14
+ from importlib.metadata import version
15
+ from typing import BinaryIO, List, Tuple
15
16
 
16
17
  from maco import collector
17
18
 
19
+
18
20
  logger = logging.getLogger("maco.lib.cli")
19
21
 
20
22
 
@@ -199,6 +201,13 @@ def main():
199
201
  action="store_true",
200
202
  help="Force installation of Python dependencies for extractors (in both host and virtual environments).",
201
203
  )
204
+ parser.add_argument(
205
+ "--version",
206
+ action="version",
207
+ version=f"version: {version('maco')}",
208
+ help="Show version of MACO",
209
+ )
210
+
202
211
  args = parser.parse_args()
203
212
  inc = args.include.split(",") if args.include else []
204
213
  exc = args.exclude.split(",") if args.exclude else []
maco/collector.py CHANGED
@@ -13,6 +13,7 @@ from multiprocess import Manager, Process, Queue
13
13
  from pydantic import BaseModel
14
14
 
15
15
  from maco import extractor, model, utils, yara
16
+ from maco.exceptions import AnalysisAbortedException
16
17
 
17
18
 
18
19
  class ExtractorLoadError(Exception):
@@ -191,6 +192,9 @@ class Collector:
191
192
  venv=extractor["venv"],
192
193
  )
193
194
  )
195
+ except AnalysisAbortedException:
196
+ # Extractor voluntarily aborted analysis of sample
197
+ return
194
198
  except Exception:
195
199
  # caller can deal with the exception
196
200
  raise
maco/exceptions.py ADDED
@@ -0,0 +1,3 @@
1
+ # Can be raised by extractors to abort analysis of a sample
2
+ # ie. Can abort if preliminary checks at start of run indicate the file shouldn't be analyzed by extractor
3
+ class AnalysisAbortedException(Exception): ...
maco/utils.py CHANGED
@@ -34,6 +34,7 @@ from uv import find_uv_bin
34
34
 
35
35
  from maco import model
36
36
  from maco.extractor import Extractor
37
+ from maco.exceptions import AnalysisAbortedException
37
38
 
38
39
  logger = logging.getLogger("maco.lib.utils")
39
40
 
@@ -514,9 +515,15 @@ def run_extractor(
514
515
  exception = stderr
515
516
  if delim in exception:
516
517
  exception = f"{delim}{exception.split(delim, 1)[1]}"
517
- # print extractor logging at error level
518
- logger.error(f"maco extractor raised exception, stderr:\n{stderr}")
519
- raise Exception(exception) from e
518
+ if "maco.exceptions.AnalysisAbortedException" in exception:
519
+ # Extractor voluntarily terminated, re-raise exception to be handled by collector
520
+ raise AnalysisAbortedException(
521
+ exception.split("maco.exceptions.AnalysisAbortedException: ")[-1]
522
+ )
523
+ else:
524
+ # print extractor logging at error level
525
+ logger.error(f"maco extractor raised exception, stderr:\n{stderr}")
526
+ raise Exception(exception) from e
520
527
  # ensure that extractor logging is available
521
528
  logger.info(f"maco extractor stderr:\n{stderr}")
522
529
  return loaded
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: maco
3
- Version: 1.2.11
3
+ Version: 1.2.12
4
4
  Author: sl-govau
5
5
  Maintainer: cccs-rs
6
6
  License: MIT License
@@ -2,26 +2,29 @@ demo_extractors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  demo_extractors/elfy.py,sha256=Jo_GKExCeFOKGENJnNM_9ONfJO7LQFucCNz0ryTAo9U,765
3
3
  demo_extractors/limit_other.py,sha256=BWjeyOxB75kw4eRla5zvSzdcXtELOS8R6hc71rLPh1s,1295
4
4
  demo_extractors/nothing.py,sha256=MNPlb0IsBjrlU5e438JlJ4DIKoBpBRAaYY3JhD3yHqk,601
5
- demo_extractors/requirements.txt,sha256=E0tD6xBZldq6sQGTHng6k88lBeASOhmLJcdcjpcqBNE,6
5
+ demo_extractors/requirements.txt,sha256=nD7BPNv7YEPUr9MDcaKYNs2UfHtxvN8FOKKesgC_L5g,50
6
6
  demo_extractors/shared.py,sha256=2P1cyuRbHDvM9IRt3UZnwdyhxx7OWqNC83xLyV8Y190,305
7
+ demo_extractors/terminator.py,sha256=G1AQHL1JGI8iMa4-H55nWwLzOlPicWH-2HiADw4aE9M,552
7
8
  demo_extractors/complex/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
9
  demo_extractors/complex/complex.py,sha256=tXrzj_zWIXbTOwj7Lezapk-qkrM-lfwcyjd5m-BYzdg,2322
9
10
  demo_extractors/complex/complex_utils.py,sha256=aec8kJsYUrMPo-waihkVLt-0QpiOPkw7dDqfT9MNuHk,123
10
11
  maco/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
12
  maco/base_test.py,sha256=cjGLEy2c69wl9sjn74QFz7X-VxWOfdin4W8MvYsXc4Q,2718
12
- maco/cli.py,sha256=iXAfSSL8Td8DyOrMtMqZaXO4uGC5NPYrMDR9GklON24,8734
13
- maco/collector.py,sha256=w4NQ1BcLOICXJxrEyOcXlkWGi_p31D9eK3IghKxq5y0,7576
13
+ maco/cli.py,sha256=K9gjsyGXcmSqBSkRkertVTH-Z4mwGFVk7TQxx8Y2mXo,8937
14
+ maco/collector.py,sha256=T1tGibakx-yfgHzrHC4mqY-G2Y-VhDz8Qx1KoXa7l0g,7752
15
+ maco/exceptions.py,sha256=aUbkX9CZfgp1aZFTEa98Uwge6MeQcQ3LbYkgNOwWaCg,214
14
16
  maco/extractor.py,sha256=uGSGiCQ4jd8jFmfw2T99BGcY5iQJzXHcG_RoTIxClTE,2802
15
- maco/utils.py,sha256=LvrpAa4xfYFMUywtp-5INGdHlWqK8n9fsd31dtMPa1c,21273
17
+ maco/utils.py,sha256=bD2z6xZeR-MNhM834w2vQi4IP-kpQSXL-l71vmGweAU,21726
16
18
  maco/yara.py,sha256=8RVaGyeUWY5f8_wfQ25lDX1bcXsb_VoSja85ZC2SqGw,2913
17
19
  maco/model/__init__.py,sha256=ULdyHx8R5D2ICHZo3VoCk1YTlewTok36TYIpwx__pNY,45
18
20
  maco/model/model.py,sha256=4uY88WphbP3iu-L2WjuYwtgZCS_wNul_hr0bAVuTpvc,23740
19
21
  model_setup/maco/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
22
  model_setup/maco/base_test.py,sha256=cjGLEy2c69wl9sjn74QFz7X-VxWOfdin4W8MvYsXc4Q,2718
21
- model_setup/maco/cli.py,sha256=iXAfSSL8Td8DyOrMtMqZaXO4uGC5NPYrMDR9GklON24,8734
22
- model_setup/maco/collector.py,sha256=w4NQ1BcLOICXJxrEyOcXlkWGi_p31D9eK3IghKxq5y0,7576
23
+ model_setup/maco/cli.py,sha256=K9gjsyGXcmSqBSkRkertVTH-Z4mwGFVk7TQxx8Y2mXo,8937
24
+ model_setup/maco/collector.py,sha256=T1tGibakx-yfgHzrHC4mqY-G2Y-VhDz8Qx1KoXa7l0g,7752
25
+ model_setup/maco/exceptions.py,sha256=aUbkX9CZfgp1aZFTEa98Uwge6MeQcQ3LbYkgNOwWaCg,214
23
26
  model_setup/maco/extractor.py,sha256=uGSGiCQ4jd8jFmfw2T99BGcY5iQJzXHcG_RoTIxClTE,2802
24
- model_setup/maco/utils.py,sha256=LvrpAa4xfYFMUywtp-5INGdHlWqK8n9fsd31dtMPa1c,21273
27
+ model_setup/maco/utils.py,sha256=bD2z6xZeR-MNhM834w2vQi4IP-kpQSXL-l71vmGweAU,21726
25
28
  model_setup/maco/yara.py,sha256=8RVaGyeUWY5f8_wfQ25lDX1bcXsb_VoSja85ZC2SqGw,2913
26
29
  model_setup/maco/model/__init__.py,sha256=ULdyHx8R5D2ICHZo3VoCk1YTlewTok36TYIpwx__pNY,45
27
30
  model_setup/maco/model/model.py,sha256=4uY88WphbP3iu-L2WjuYwtgZCS_wNul_hr0bAVuTpvc,23740
@@ -36,9 +39,9 @@ tests/extractors/basic_longer.py,sha256=1ClU2QD-Y0TOl_loNFvEqIEpTR5TSVJ6zg9ZmC-E
36
39
  tests/extractors/test_basic.py,sha256=FLKekfSGM69HaiF7Vu_7D7KDXHZko-9hZkMO8_DoyYA,697
37
40
  tests/extractors/bob/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
41
  tests/extractors/bob/bob.py,sha256=G5aOoz58J0ZQK2_lA7HRxAzeLzBxssWxBTZcv1pSbi8,176
39
- maco-1.2.11.dist-info/LICENSE.md,sha256=gMSjshPhXvV_F1qxmeNkKdBqGWkd__fEJf4glS504bM,1478
40
- maco-1.2.11.dist-info/METADATA,sha256=Tq5p2qkCIvlvzc48rskdrBhl6-FUEq0FhE-Xdm6JcL0,15893
41
- maco-1.2.11.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
42
- maco-1.2.11.dist-info/entry_points.txt,sha256=TpcwG1gedIg8Y7a9ZOv8aQpuwEUftCefDrAjzeP-o6U,39
43
- maco-1.2.11.dist-info/top_level.txt,sha256=iMRwuzmrHA3zSwiSeMIl6FWhzRpn_st-I4fAv-kw5_o,49
44
- maco-1.2.11.dist-info/RECORD,,
42
+ maco-1.2.12.dist-info/LICENSE.md,sha256=gMSjshPhXvV_F1qxmeNkKdBqGWkd__fEJf4glS504bM,1478
43
+ maco-1.2.12.dist-info/METADATA,sha256=fQa29RHfFtLo3isR5emR5qEtpeTTTHwBk4EN1CWzyRs,15893
44
+ maco-1.2.12.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
45
+ maco-1.2.12.dist-info/entry_points.txt,sha256=TpcwG1gedIg8Y7a9ZOv8aQpuwEUftCefDrAjzeP-o6U,39
46
+ maco-1.2.12.dist-info/top_level.txt,sha256=iMRwuzmrHA3zSwiSeMIl6FWhzRpn_st-I4fAv-kw5_o,49
47
+ maco-1.2.12.dist-info/RECORD,,
model_setup/maco/cli.py CHANGED
@@ -3,18 +3,20 @@
3
3
  import argparse
4
4
  import base64
5
5
  import binascii
6
+ import cart
6
7
  import hashlib
7
8
  import io
8
9
  import json
9
10
  import logging
10
11
  import os
11
12
  import sys
12
- from typing import BinaryIO, List, Tuple
13
13
 
14
- import cart
14
+ from importlib.metadata import version
15
+ from typing import BinaryIO, List, Tuple
15
16
 
16
17
  from maco import collector
17
18
 
19
+
18
20
  logger = logging.getLogger("maco.lib.cli")
19
21
 
20
22
 
@@ -199,6 +201,13 @@ def main():
199
201
  action="store_true",
200
202
  help="Force installation of Python dependencies for extractors (in both host and virtual environments).",
201
203
  )
204
+ parser.add_argument(
205
+ "--version",
206
+ action="version",
207
+ version=f"version: {version('maco')}",
208
+ help="Show version of MACO",
209
+ )
210
+
202
211
  args = parser.parse_args()
203
212
  inc = args.include.split(",") if args.include else []
204
213
  exc = args.exclude.split(",") if args.exclude else []
@@ -13,6 +13,7 @@ from multiprocess import Manager, Process, Queue
13
13
  from pydantic import BaseModel
14
14
 
15
15
  from maco import extractor, model, utils, yara
16
+ from maco.exceptions import AnalysisAbortedException
16
17
 
17
18
 
18
19
  class ExtractorLoadError(Exception):
@@ -191,6 +192,9 @@ class Collector:
191
192
  venv=extractor["venv"],
192
193
  )
193
194
  )
195
+ except AnalysisAbortedException:
196
+ # Extractor voluntarily aborted analysis of sample
197
+ return
194
198
  except Exception:
195
199
  # caller can deal with the exception
196
200
  raise
@@ -0,0 +1,3 @@
1
+ # Can be raised by extractors to abort analysis of a sample
2
+ # ie. Can abort if preliminary checks at start of run indicate the file shouldn't be analyzed by extractor
3
+ class AnalysisAbortedException(Exception): ...
model_setup/maco/utils.py CHANGED
@@ -34,6 +34,7 @@ from uv import find_uv_bin
34
34
 
35
35
  from maco import model
36
36
  from maco.extractor import Extractor
37
+ from maco.exceptions import AnalysisAbortedException
37
38
 
38
39
  logger = logging.getLogger("maco.lib.utils")
39
40
 
@@ -514,9 +515,15 @@ def run_extractor(
514
515
  exception = stderr
515
516
  if delim in exception:
516
517
  exception = f"{delim}{exception.split(delim, 1)[1]}"
517
- # print extractor logging at error level
518
- logger.error(f"maco extractor raised exception, stderr:\n{stderr}")
519
- raise Exception(exception) from e
518
+ if "maco.exceptions.AnalysisAbortedException" in exception:
519
+ # Extractor voluntarily terminated, re-raise exception to be handled by collector
520
+ raise AnalysisAbortedException(
521
+ exception.split("maco.exceptions.AnalysisAbortedException: ")[-1]
522
+ )
523
+ else:
524
+ # print extractor logging at error level
525
+ logger.error(f"maco extractor raised exception, stderr:\n{stderr}")
526
+ raise Exception(exception) from e
520
527
  # ensure that extractor logging is available
521
528
  logger.info(f"maco extractor stderr:\n{stderr}")
522
529
  return loaded
File without changes