maco 1.2.1__py3-none-any.whl → 1.2.3__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.
maco/base_test.py CHANGED
@@ -46,8 +46,7 @@ class BaseTest(unittest.TestCase):
46
46
  runs = self.c.match(stream)
47
47
  if not runs:
48
48
  raise NoHitException("no yara rule hit")
49
- hits = runs[self.name]
50
- resp = self.c.extract(stream, hits, self.name)
49
+ resp = self.c.extract(stream, self.name)
51
50
  return resp
52
51
 
53
52
  def _get_location(self) -> str:
maco/cli.py CHANGED
@@ -8,7 +8,7 @@ import json
8
8
  import logging
9
9
  import os
10
10
  import sys
11
- from typing import BinaryIO, List
11
+ from typing import BinaryIO, List, Tuple
12
12
 
13
13
  import cart
14
14
 
@@ -57,7 +57,7 @@ def process_file(
57
57
  # run and store results for extractor
58
58
  logger.info(f"run {extractor_name} extractor from rules {[x.rule for x in hits]}")
59
59
  try:
60
- resp = collected.extract(stream, hits, extractor_name)
60
+ resp = collected.extract(stream, extractor_name)
61
61
  except Exception as e:
62
62
  logger.exception(f"extractor error with {path_file} ({e})")
63
63
  resp = None
@@ -91,18 +91,22 @@ def process_filesystem(
91
91
  force: bool,
92
92
  include_base64: bool,
93
93
  create_venv: bool = False,
94
- ):
94
+ ) -> Tuple[int, int, int]:
95
+ """Process filesystem with extractors and print results of extraction.
96
+
97
+ Returns total number of analysed files, yara hits and successful maco extractions.
98
+ """
95
99
  if force:
96
100
  logger.warning("force execute will cause errors if an extractor requires a yara rule hit during execution")
97
101
  collected = collector.Collector(path_extractors, include=include, exclude=exclude, create_venv=create_venv)
98
102
 
99
103
  logger.info(f"extractors loaded: {[x for x in collected.extractors.keys()]}\n")
100
104
  for _, extractor in collected.extractors.items():
101
- extractor = extractor["module"]
105
+ extractor_meta = extractor["metadata"]
102
106
  logger.info(
103
- f"{extractor.family} by {extractor.author}"
104
- f" {extractor.last_modified} {extractor.sharing}"
105
- f"\n{extractor.__doc__}\n"
107
+ f"{extractor_meta['family']} by {extractor_meta['author']}"
108
+ f" {extractor_meta['last_modified']} {extractor_meta['sharing']}"
109
+ f"\n{extractor_meta['description']}\n"
106
110
  )
107
111
 
108
112
  num_analysed = 0
@@ -144,7 +148,7 @@ def process_filesystem(
144
148
  finally:
145
149
  logger.info("")
146
150
  logger.info(f"{num_analysed} analysed, {num_hits} hits, {num_extracted} extracted")
147
-
151
+ return num_analysed, num_hits, num_extracted
148
152
 
149
153
  def main():
150
154
  parser = argparse.ArgumentParser(description="Run extractors over samples.")
maco/collector.py CHANGED
@@ -40,7 +40,11 @@ def _verify_response(resp: Union[BaseModel, dict]) -> Dict:
40
40
 
41
41
  class Collector:
42
42
  def __init__(
43
- self, path_extractors: str, include: List[str] = None, exclude: List[str] = None, create_venv: bool = False
43
+ self,
44
+ path_extractors: str,
45
+ include: List[str] = None,
46
+ exclude: List[str] = None,
47
+ create_venv: bool = False,
44
48
  ):
45
49
  """Discover and load extractors from file system."""
46
50
  path_extractors = os.path.realpath(path_extractors)
@@ -72,6 +76,13 @@ class Collector:
72
76
  module_path=module.__file__,
73
77
  module_name=member.__module__,
74
78
  extractor_class=member.__name__,
79
+ metadata={
80
+ "family": member.family,
81
+ "author": member.author,
82
+ "last_modified": member.last_modified,
83
+ "sharing": member.sharing,
84
+ "description": member.__doc__,
85
+ },
75
86
  )
76
87
  namespaced_rules[name] = member.yara_rule or extractor.DEFAULT_YARA_RULE.format(name=name)
77
88
 
@@ -116,7 +127,6 @@ class Collector:
116
127
  def extract(
117
128
  self,
118
129
  stream: BinaryIO,
119
- matches: List[yara.Match],
120
130
  extractor_name: str,
121
131
  ) -> Dict[str, Any]:
122
132
  """Run extractor with stream and verify output matches the model."""
@@ -127,7 +137,15 @@ class Collector:
127
137
  sample_path.write(stream.read())
128
138
  sample_path.flush()
129
139
  # enforce types and verify properties, and remove defaults
130
- return _verify_response(utils.run_extractor(sample_path.name, **extractor))
140
+ return _verify_response(
141
+ utils.run_extractor(
142
+ sample_path.name,
143
+ module_name=extractor["module_name"],
144
+ extractor_class=extractor["extractor_class"],
145
+ module_path=extractor["module_path"],
146
+ venv=extractor["venv"],
147
+ )
148
+ )
131
149
  except Exception:
132
150
  # caller can deal with the exception
133
151
  raise
maco/utils.py CHANGED
@@ -265,7 +265,7 @@ def find_and_insert_venv(path: str, venvs: List[str]):
265
265
  venv = None
266
266
  for venv in sorted(venvs, reverse=True):
267
267
  venv_parent = os.path.dirname(venv)
268
- if path.startswith(venv_parent):
268
+ if path.startswith(f"{venv_parent}/"):
269
269
  # Found the virtual environment that's the closest to extractor
270
270
  break
271
271
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: maco
3
- Version: 1.2.1
3
+ Version: 1.2.3
4
4
  Author: sl-govau
5
5
  Maintainer: cccs-rs
6
6
  License: MIT License
@@ -6,20 +6,20 @@ demo_extractors/complex/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG
6
6
  demo_extractors/complex/complex.py,sha256=TkNmR9UUYo1f2JVpJhGasLG-5wHZI05JYxMIXj16GKM,2307
7
7
  demo_extractors/complex/complex_utils.py,sha256=aec8kJsYUrMPo-waihkVLt-0QpiOPkw7dDqfT9MNuHk,123
8
8
  maco/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
- maco/base_test.py,sha256=7uZTprPoFZRnPaO_hLkMGz5rVW9F9TozAUWtNeXouig,2555
10
- maco/cli.py,sha256=56xM2qqLNlvQgWBF3Uc1fDbG8_46PSx66Wqj2mMxl1E,7713
11
- maco/collector.py,sha256=uBk_RrnJAoiQkBxnNA-B7zIPj9fDm5gkFb4D_VyMWi8,5342
9
+ maco/base_test.py,sha256=pqet9ofMwFRTj3JHgPdh9WHwdyp8kxNMi1vJNUzkSNA,2518
10
+ maco/cli.py,sha256=1I3U54yPddTxqWclCtZ5Ma5hW6RoVTZMzLSFOjjfM1g,8008
11
+ maco/collector.py,sha256=sxP374lK16lzdi0lhm5e4GT3a5lzeyE1VCicE4m_E3k,6003
12
12
  maco/extractor.py,sha256=4ZQd8OfvEQYUIkUS3LzZ5tcioembuLhT9_uRVNKSsyM,2750
13
- maco/utils.py,sha256=lkZ4yb-LjkzjVpyY6INNWKyimYg5k3Y2N_Hr9CdrFbw,18232
13
+ maco/utils.py,sha256=nyRTTsiwIE3L9XjFME6R_vR_EvLluwNL0kLb0r96jcg,18238
14
14
  maco/yara.py,sha256=vPzCqauVp52ivcTdt8zwrYqDdkLutGlesma9DhKPzHw,2925
15
15
  maco/model/__init__.py,sha256=SJrwdn12wklUFm2KoIgWjX_KgvJxCM7Ca9ntXOneuzc,31
16
16
  maco/model/model.py,sha256=ngen4ViyLdRo_z_TqZBjw2DN0NrRLpuxOy15-6QmtNw,23536
17
17
  model_setup/maco/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
- model_setup/maco/base_test.py,sha256=7uZTprPoFZRnPaO_hLkMGz5rVW9F9TozAUWtNeXouig,2555
19
- model_setup/maco/cli.py,sha256=56xM2qqLNlvQgWBF3Uc1fDbG8_46PSx66Wqj2mMxl1E,7713
20
- model_setup/maco/collector.py,sha256=uBk_RrnJAoiQkBxnNA-B7zIPj9fDm5gkFb4D_VyMWi8,5342
18
+ model_setup/maco/base_test.py,sha256=pqet9ofMwFRTj3JHgPdh9WHwdyp8kxNMi1vJNUzkSNA,2518
19
+ model_setup/maco/cli.py,sha256=1I3U54yPddTxqWclCtZ5Ma5hW6RoVTZMzLSFOjjfM1g,8008
20
+ model_setup/maco/collector.py,sha256=sxP374lK16lzdi0lhm5e4GT3a5lzeyE1VCicE4m_E3k,6003
21
21
  model_setup/maco/extractor.py,sha256=4ZQd8OfvEQYUIkUS3LzZ5tcioembuLhT9_uRVNKSsyM,2750
22
- model_setup/maco/utils.py,sha256=lkZ4yb-LjkzjVpyY6INNWKyimYg5k3Y2N_Hr9CdrFbw,18232
22
+ model_setup/maco/utils.py,sha256=nyRTTsiwIE3L9XjFME6R_vR_EvLluwNL0kLb0r96jcg,18238
23
23
  model_setup/maco/yara.py,sha256=vPzCqauVp52ivcTdt8zwrYqDdkLutGlesma9DhKPzHw,2925
24
24
  model_setup/maco/model/__init__.py,sha256=SJrwdn12wklUFm2KoIgWjX_KgvJxCM7Ca9ntXOneuzc,31
25
25
  model_setup/maco/model/model.py,sha256=ngen4ViyLdRo_z_TqZBjw2DN0NrRLpuxOy15-6QmtNw,23536
@@ -33,9 +33,9 @@ tests/extractors/basic_longer.py,sha256=1ClU2QD-Y0TOl_loNFvEqIEpTR5TSVJ6zg9ZmC-E
33
33
  tests/extractors/test_basic.py,sha256=FLKekfSGM69HaiF7Vu_7D7KDXHZko-9hZkMO8_DoyYA,697
34
34
  tests/extractors/bob/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
35
35
  tests/extractors/bob/bob.py,sha256=Gy5p8KssJX87cwa9vVv8UBODF_ulbUteZXh15frW2hs,247
36
- maco-1.2.1.dist-info/LICENSE.md,sha256=gMSjshPhXvV_F1qxmeNkKdBqGWkd__fEJf4glS504bM,1478
37
- maco-1.2.1.dist-info/METADATA,sha256=iaJIFA_TcNHwAxT6ysbTLSaRmLib7lF2BC3IBXOoQg4,15610
38
- maco-1.2.1.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
39
- maco-1.2.1.dist-info/entry_points.txt,sha256=TpcwG1gedIg8Y7a9ZOv8aQpuwEUftCefDrAjzeP-o6U,39
40
- maco-1.2.1.dist-info/top_level.txt,sha256=iMRwuzmrHA3zSwiSeMIl6FWhzRpn_st-I4fAv-kw5_o,49
41
- maco-1.2.1.dist-info/RECORD,,
36
+ maco-1.2.3.dist-info/LICENSE.md,sha256=gMSjshPhXvV_F1qxmeNkKdBqGWkd__fEJf4glS504bM,1478
37
+ maco-1.2.3.dist-info/METADATA,sha256=81_65WF-TCXVfF3NeY5m3zCr831F7PVsTswjvZ34Ok4,15610
38
+ maco-1.2.3.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
39
+ maco-1.2.3.dist-info/entry_points.txt,sha256=TpcwG1gedIg8Y7a9ZOv8aQpuwEUftCefDrAjzeP-o6U,39
40
+ maco-1.2.3.dist-info/top_level.txt,sha256=iMRwuzmrHA3zSwiSeMIl6FWhzRpn_st-I4fAv-kw5_o,49
41
+ maco-1.2.3.dist-info/RECORD,,
@@ -46,8 +46,7 @@ class BaseTest(unittest.TestCase):
46
46
  runs = self.c.match(stream)
47
47
  if not runs:
48
48
  raise NoHitException("no yara rule hit")
49
- hits = runs[self.name]
50
- resp = self.c.extract(stream, hits, self.name)
49
+ resp = self.c.extract(stream, self.name)
51
50
  return resp
52
51
 
53
52
  def _get_location(self) -> str:
model_setup/maco/cli.py CHANGED
@@ -8,7 +8,7 @@ import json
8
8
  import logging
9
9
  import os
10
10
  import sys
11
- from typing import BinaryIO, List
11
+ from typing import BinaryIO, List, Tuple
12
12
 
13
13
  import cart
14
14
 
@@ -57,7 +57,7 @@ def process_file(
57
57
  # run and store results for extractor
58
58
  logger.info(f"run {extractor_name} extractor from rules {[x.rule for x in hits]}")
59
59
  try:
60
- resp = collected.extract(stream, hits, extractor_name)
60
+ resp = collected.extract(stream, extractor_name)
61
61
  except Exception as e:
62
62
  logger.exception(f"extractor error with {path_file} ({e})")
63
63
  resp = None
@@ -91,18 +91,22 @@ def process_filesystem(
91
91
  force: bool,
92
92
  include_base64: bool,
93
93
  create_venv: bool = False,
94
- ):
94
+ ) -> Tuple[int, int, int]:
95
+ """Process filesystem with extractors and print results of extraction.
96
+
97
+ Returns total number of analysed files, yara hits and successful maco extractions.
98
+ """
95
99
  if force:
96
100
  logger.warning("force execute will cause errors if an extractor requires a yara rule hit during execution")
97
101
  collected = collector.Collector(path_extractors, include=include, exclude=exclude, create_venv=create_venv)
98
102
 
99
103
  logger.info(f"extractors loaded: {[x for x in collected.extractors.keys()]}\n")
100
104
  for _, extractor in collected.extractors.items():
101
- extractor = extractor["module"]
105
+ extractor_meta = extractor["metadata"]
102
106
  logger.info(
103
- f"{extractor.family} by {extractor.author}"
104
- f" {extractor.last_modified} {extractor.sharing}"
105
- f"\n{extractor.__doc__}\n"
107
+ f"{extractor_meta['family']} by {extractor_meta['author']}"
108
+ f" {extractor_meta['last_modified']} {extractor_meta['sharing']}"
109
+ f"\n{extractor_meta['description']}\n"
106
110
  )
107
111
 
108
112
  num_analysed = 0
@@ -144,7 +148,7 @@ def process_filesystem(
144
148
  finally:
145
149
  logger.info("")
146
150
  logger.info(f"{num_analysed} analysed, {num_hits} hits, {num_extracted} extracted")
147
-
151
+ return num_analysed, num_hits, num_extracted
148
152
 
149
153
  def main():
150
154
  parser = argparse.ArgumentParser(description="Run extractors over samples.")
@@ -40,7 +40,11 @@ def _verify_response(resp: Union[BaseModel, dict]) -> Dict:
40
40
 
41
41
  class Collector:
42
42
  def __init__(
43
- self, path_extractors: str, include: List[str] = None, exclude: List[str] = None, create_venv: bool = False
43
+ self,
44
+ path_extractors: str,
45
+ include: List[str] = None,
46
+ exclude: List[str] = None,
47
+ create_venv: bool = False,
44
48
  ):
45
49
  """Discover and load extractors from file system."""
46
50
  path_extractors = os.path.realpath(path_extractors)
@@ -72,6 +76,13 @@ class Collector:
72
76
  module_path=module.__file__,
73
77
  module_name=member.__module__,
74
78
  extractor_class=member.__name__,
79
+ metadata={
80
+ "family": member.family,
81
+ "author": member.author,
82
+ "last_modified": member.last_modified,
83
+ "sharing": member.sharing,
84
+ "description": member.__doc__,
85
+ },
75
86
  )
76
87
  namespaced_rules[name] = member.yara_rule or extractor.DEFAULT_YARA_RULE.format(name=name)
77
88
 
@@ -116,7 +127,6 @@ class Collector:
116
127
  def extract(
117
128
  self,
118
129
  stream: BinaryIO,
119
- matches: List[yara.Match],
120
130
  extractor_name: str,
121
131
  ) -> Dict[str, Any]:
122
132
  """Run extractor with stream and verify output matches the model."""
@@ -127,7 +137,15 @@ class Collector:
127
137
  sample_path.write(stream.read())
128
138
  sample_path.flush()
129
139
  # enforce types and verify properties, and remove defaults
130
- return _verify_response(utils.run_extractor(sample_path.name, **extractor))
140
+ return _verify_response(
141
+ utils.run_extractor(
142
+ sample_path.name,
143
+ module_name=extractor["module_name"],
144
+ extractor_class=extractor["extractor_class"],
145
+ module_path=extractor["module_path"],
146
+ venv=extractor["venv"],
147
+ )
148
+ )
131
149
  except Exception:
132
150
  # caller can deal with the exception
133
151
  raise
model_setup/maco/utils.py CHANGED
@@ -265,7 +265,7 @@ def find_and_insert_venv(path: str, venvs: List[str]):
265
265
  venv = None
266
266
  for venv in sorted(venvs, reverse=True):
267
267
  venv_parent = os.path.dirname(venv)
268
- if path.startswith(venv_parent):
268
+ if path.startswith(f"{venv_parent}/"):
269
269
  # Found the virtual environment that's the closest to extractor
270
270
  break
271
271
 
File without changes